技术中心
 
 

经典常用的单片机c程序

   日期:2011-05-06    
核心提示:经典常用的单片机c程序

  //16进制<->10进制互换程序

  unsigned char d[10]; //用于显示的10位显示缓存

  //========================================================

  //16进制to10进制输出子程序:显示数据,起始位,结束位,有无小数点

  //========================================================

  void output(unsigned long dd,unsigned char s,unsigned char

  e,unsigned char dip) {

  unsigned long div;

  unsigned char tm[8],i,j;

  div=10000000;

  for (i=0;i<8;i++) {

  tm[i]=dd/div;

  dd%=div;

  div/=10;

  }

  for (i=0;i<6;i++) {

  if (tm[i]!=0) break;

  tm[i]=nul;

  }

  tm[5]|=dip; //小数点控制,请看“串行LED数码管显示驱动程序”

  j=7;

  for (i=s;i

  d[i]=tm[j];

  j--;

  }

  }

  //把显示位5-9位的10进制数转换成为16进制数

  unsigned int input(void) {

  unsigned int dd,dat;

  dd=10000;dat=0;

  for (i=5;i<10;i++) {

  dat+=dd*temp;

  dd/=10;

  }

  return(dat);

  }

  /* 89C51系列CPU编程器接收CPU程序*/

  #i nclude

  #i nclude

  #i nclude

  #define e 8

  #define p 9

  #define l 10

  sbit led=P3^2;

  sbit p27=P2^7;

  sbit p26=P2^6;

  sbit p36=P3^6;

  sbit p37=P3^7;

  sbit rst=P3^3;

  sbit ale=P3^5;

  sbit vpp=P3^4;

  bit b_break;

  unsigned int adds;

  // 13.8mS

  void int_t0(void) interrupt 1 {

  TH0=-100;

  b_break=1;

  }

  void wait(unsigned char w) {

  unsigned int t=w*184;

  b_break=0;

  TL0=-t%256-1;TH0=-t/256;

  while (b_break==0) {}

  }

  void nop(void) {

  _nop_();_nop_();_nop_();_nop_();

  _nop_();_nop_();_nop_();_nop_();

  _nop_();_nop_();_nop_();_nop_();

  _nop_();_nop_();_nop_();_nop_();

  _nop_();_nop_();_nop_();_nop_();

  }

  unsigned char command(void) {

  TH0=-100;b_break=0;

  while (RI==0) {if (b_break==1) return(0);}

  RI=0;

  return(SBUF);

  }

  void earsure(unsigned char cpu) {

  switch (cpu) {

  case 1: //89C51

  case 2:rst=p26=1;p27=p36=p37=0;nop();vpp=1;nop();

  ale=0;wait(110);ale=1;nop();

  break;

  case 3:

  case 4:break;

  case 5:

  case 6:break;

  }

  }

  void program(unsigned char cpu) {

  unsigned int bdata adds=0;

  unsigned char d;

  switch (cpu) {

  case 1: //89C51

  case 2:

  p36=p37=1;rst=1;

  while (1) {

  TH0=-100;b_break=0;

  while (RI==0) {if (b_break==1) return;}

  RI=0;

  d=SBUF;

  //address

  P0=adds%256;

  P2=adds/256;

  p27=1;

  //data

  P1=d;

  nop(); //48clcl

  //vpp

  vpp=1;

  nop(); //48clcl

  //ale

  ale=0;

  wait(1);//100uS

  ale=1;

  nop(); //10uS

  vpp=0;

  nop(); //48clcl

  p27=0;

  nop(); //48clcl

  P1=0xff;

  TH0=-100;b_break=0;

  while (d!=P1) {if (b_break==1) return;} //data

  polling

  SBUF=d;

  adds++;

  }

  break;

  case 3:

  case 4:

  case 5:

  case 6:break;

  }

  }

  void lock(unsigned char cpu) {

  unsigned char i;

  switch (cpu) {

  case 1: //89c51

  case 2:

  //lock 1

  rst=p26=p36=p27=p37=1;nop();

  vpp=1;

  nop();

  ale=0;

  // for (i=0;i<6;i++) wait(100);

  wait(1);

  ale=1;

  nop();

  vpp=0;

  nop();

  //lock 2

  rst=p26=p27=1;p36=p37=0;nop();

  vpp=1;

  nop();

  ale=0;

  // for (i=0;i<6;i++) wait(100);

  wait(1);

  ale=1;

  nop();

  vpp=0;

  nop();

  //lock 3

  rst=p26=p36=1;p27=p37=0;nop();

  vpp=1;

  nop();

  ale=0;

  // for (i=0;i<6;i++) wait(100);

  wait(1);

  ale=1;

  nop();

  vpp=0;

  nop();

  break;

  case 3:

  case 4:

  case 5:

  case 6:break;

  }

  }

  void main(void) {

  unsigned char disp,flash,temp,cpu;

  EA=1;

  SCON=0xd8;PCON=0x80;

  TMOD=0x21;

  TL1=TH1=0xff;TR1=1;

  TH0=-100;ET0=TR0=1;

  flash=0x80;

  while (1) {

  temp=command();

  switch (temp) {

  case 0:

  case 1: //89c51

  case 2: //89C52

  case 3: //80f51

  case 4: //80F52

  case 5: //87F51

  case 6:cpu=temp;SBUF=temp;break;//87f52

  case e:SBUF=temp;earsure(cpu);break; //erasure

  case p:SBUF=temp;program(cpu);break; //program

  case l:lock(cpu);SBUF=temp;break; //lock

  default:SBUF=temp;break;

  }

  b_break=0;

  if ((++disp)>flash) {disp=0;led=!led;}

  }

  }

  //HT1380实时时钟驱动程序

  sbit clock_dat=P0^1;

  sbit clock_clk=P0^2;

  sbit clock_rst=P0^3;

  sbit a0=ACC^0;

  sbit a1=ACC^1;

  sbit a2=ACC^2;

  sbit a3=ACC^3;

  sbit a4=ACC^4;

  sbit a5=ACC^5;

  sbit a6=ACC^6;

  sbit a7=ACC^7;

  void clock_out(unsigned char dd) {

  ACC=dd;

  clock_dat=a0;clock_clk=1;clock_clk=0;

  clock_dat=a1;clock_clk=1;clock_clk=0;

  clock_dat=a2;clock_clk=1;clock_clk=0;

  clock_dat=a3;clock_clk=1;clock_clk=0;

  clock_dat=a4;clock_clk=1;clock_clk=0;

  clock_dat=a5;clock_clk=1;clock_clk=0;

  clock_dat=a6;clock_clk=1;clock_clk=0;

  clock_dat=a7;clock_clk=1;clock_clk=0;

  }

[pagebreak]

  unsigned char clock_in(void) {

  clock_dat=1;

  a0=clock_dat;

  clock_clk=1;clock_clk=0;a1=clock_dat;

  clock_clk=1;clock_clk=0;a2=clock_dat;

  clock_clk=1;clock_clk=0;a3=clock_dat;

  clock_clk=1;clock_clk=0;a4=clock_dat;

  clock_clk=1;clock_clk=0;a5=clock_dat;

  clock_clk=1;clock_clk=0;a6=clock_dat;

  clock_clk=1;clock_clk=0;a7=clock_dat;

  return(ACC);

  }

  unsigned char read_clock(unsigned char ord) {

  unsigned char dd=0;

  clock_clk=0;

  clock_rst=0;

  clock_rst=1;

  clock_out(ord);

  dd=clock_in();

  clock_rst=0;

  clock_clk=1;

  return(dd);

  }

  void write_clock(unsigned char ord,unsigned char dd) {

  clock_clk=0;

  clock_rst=0;

  clock_rst=1;

  clock_out(ord);

  clock_out(dd);

  clock_rst=0;

  clock_clk=1;

  }

  /*单个汉字库字摸提取程序,tc2.0编译*/

  #i nclude "stdio.h"

  #i nclude "dos.h"

  #i nclude "process.h"

  #i nclude "string.h"

  void main(void) {

  long int num_bytes,qm,wm;

  unsigned char d,i,j,k,a[132],b[132];

  unsigned char * data;

  unsigned char * hz;

  static unsigned char dd[103];

  FILE *fp;

  if ((fp=fopen("hzk16f","rb"))==NULL) {

  printf("can't open hzk16n");

  exit(1);

  }

  clrscr();

  while (1) {

  data=(unsigned char *) malloc(33);

  printf("please input:n");

  scanf("%s",dd); /*输入一个汉字*/

  qm=* dd; /*通过区位码计算其在hzk16f文件中的偏移地址*/

  qm=qm-161;

  if (qm>87) exit(0);

  wm=* (dd+1);

  wm=wm-161;

  if (wm>94) exit(0);

  num_bytes=((long)qm*94+wm)*32;

  fseek(fp,num_bytes,SEEK_SET);

  fgets(data,33,fp);

  for (i=0;i<32;i++) b[i]=* data++;

  for (i=0;i<32;i+=2) a[i/2]=b[i];

  for (i=0;i<32;i+=2) a[i/2+16]=b[i+1];

  for (i=8;i<16;i++) b[i]=a[i];

  for (i=8;i<16;i++) a[i]=a[i+8];

  for (i=8;i<16;i++) a[i+8]=b[i];

  /*转换,hzf16f在电脑的储存格式是以行为字节计算的,一般的lcd都采用以列为字节计算*/

  for (k=0;k<32;k+=8) {

  for (j=0;j<8;j++) {

  d=0;

  for (i=0;i<8;i++) {

  if (a[i+k]>=0x80) {

  switch (i) {

  case 0:d+=1;break;

  case 1:d+=2;break;

  case 2:d+=4;break;

  case 3:d+=8;break;

  case 4:d+=0x10;break;

  case 5:d+=0x20;break;

  case 6:d+=0x40;break;

  case 7:d+=0x80;break;

  }

  }

  }

  for (i=0;i<8;i++) a[i+k]<<=1;

  b[j+k]=d;

  }

  }

  clrscr();

  printf("/*%s:*/n",dd); /*输出0x00格式的16进制数*/

  for (k=0;k<32;k+=8) {

  for (j=0;j<8;j++) printf("0x%x,",b[j+k]);

  printf("n");

  }

  getch();

  }

  }

  //按键扫描驱动程序

  unsigned char key,key_h,kpush;

  unsigned int key_l;

  //按键连接到p1.0、p1.1、p1.2

  void int_t0(void) interrupt 1 {

  unsigned char dd,i;

  TL0=TL0+30;TH0=0xfb; //800

  /* 按键判别 */

  if ((P1&0x7)==0x7) {

  if ((key_l>30)&&(key_l<800)&&(key_h>30)) {

  //释放按键,如果之前按键时间少于1秒,读入键值

  key=kpush;

  }

  if ((++key_h)>200) key_h=200;

  key_l=0;

  if (key>=0x80) key=0;

  //如果之前的按键为长按1秒,清除键值

  } else {

  kpush=P1&0x7;

  key_l++;

  if ((key_l>800)&&(key_h>30)) {

  //如果按键超过1秒,键值加0x80标志长按键

  key=kpush|0x80;

  key_h=0;

  key_l=0;

  }

  }

  }

  void main(void) {

  TMOD=0x1;TR0=1;ET0=1;EA=1;

  while (1) {

  while (!key) {}

  switch (key) {

  case 1:break;

  case 2:break;

  }

  }

  //串行驱动led显示,

  //一个74hc595位移寄存器驱动三极管驱动led位,

  //两个74hc595驱动led段,方式位5位x8段x2=10个数码管

  //5分频,每次扫描时间位1.25ms

  //定义特殊符号

  #define nul 0xf

  #define qc 0xc

  #define qb 0xb

  #define q_ 0xa

  #define q__ 0xd

  #define q___ 0xe

  #define qp 0x10

  #define qe 0x11

  #define qj 0x12

  #define qn 0x13

  #define qf 0x14

  #define qa 0x15

  #define qr 0x16

  #define qd 0x17

  #define qu 0x18

  #define ql 0x19

  #define qh 0x1a

  #define qwen 0x1b

  #define qt 0x1c

  #define qla 0x1d

  #define qlb 0x1e

  #define qlc 0x1f

  #define qld 0x20

  #define qle 0x21

  #define qlf 0x22

  #define qlg 0x23

  #define qldp 0x24

  //显示段信息,不同led排列组合的段信息只需更改8个数值即可。

[pagebreak]

  //因此,该定义具有通用性。

  // 显示

  // -d 20

  // |c 40 |e 10

  // - g 80

  // |b 2 |f 4

  // _a1 .dp 8

  #define pa 1

  #define pb 2

  #define pc 0x40

  #define pd 0x20

  #define pe 0x10

  #define pf 4

  #define pg 0x80

  #define pdp 8

  //--------------

  #define l0 pdp+pg

  #define l1 255-pf-pe

  #define l2 pdp+pc+pf

  #define l3 pdp+pc+pb

  #define l4 pdp+pa+pb+pd

  #define l5 pdp+pb+pe

  #define l6 pdp+pe

  #define l7 pdp+pc+pg+pb+pa

  #define l8 pdp

  #define l9 pdp+pb

  #define la pdp+pa

  #define lb pdp+pd+pe

  #define lc pdp+pg+pe+pf

  #define ld pdp+pc+pd

  #define le pdp+pe+pf

  #define lf pdp+pe+pf+pa

  #define l_ 255-pg

  #define lnul 255

  #define ll pdp+pg+pd+pf+pe

  #define lp pdp+pa+pf

  #define lt pdp+pd+pe+pf

  #define lr pdp+pe+pf+pg+pa

  #define ln pdp+pg+pa

  #define lh pdp+pd+pe+pa

  #define ly pdp+pb+pd

  #define lu pdp+pg+pd

  #define l__ pdp+pg+pb+pc+pe+pf

  #define l___ l__-pg

  #define l_1 255-pa

  #define l_2 255-pa-pg

  #define lj 255-(pe+pf+pa)

  #define lwen 255-(pd+pe+pg+pb)

  #define lall 0

  #define lla 255-pa

  #define llb 255-pb

  #define llc 255-pc

  #define lld 255-pd

  #define lle 255-pe

  #define llf 255-pf

  #define llg 255-pg

  #define lldp 255-pdp

  //串行送出的位信息,目前是10位led显示。

  unsigned char code un_dig[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb};

  //串行送出的短信息。

  unsigned char code

  un_disp[]={l0,l1,l2,l3,l4,l5,l6,l7,l8,l9,l_,lb,lc,l__,l___,lnul,lp,le,lj,ln,lf,la,lr,ld,lu,

  ll,lh,lwen,lt,lla,llb,llc,lld,lle,llf,llg,lldp,lnul};

  sbit d_clk=P0^0; //移位时钟

  sbit d_dat=P0^1; //移位数据

  sbit d_st=P0^2; //移位锁定

  unsigned char dig; //位扫描计数器

  unsigned char d[10]; //显示缓冲

  //送出8位串行数据

  void out_disp(unsigned char dd) {

  unsigned char i;

  for (i=0;i<8;i++) {

  if (dd&1) d_dat=1; else d_dat=0;

  d_clk=0;

  dd>>=1;

  d_clk=1;

  }

  }

  //控制小数点和闪烁,显示数据|0x040表示有小数点;显示数据|0x80表示闪烁。

  void out_displ(unsigned char dd) {

  if (dd>=0x80) {

  if (s001>flash_time) {out_disp(0xff);return;}

  }

  dd&=0x7f;

  if (dd>=0x40) {

  dd=un_disp[dd&0x3f]^pdp;

  } else dd=un_disp[dd];

  out_disp(dd);

  }

  unsigned int s001; //闪烁时间参考

  void int_t0(void) interrupt 1 {

  unsigned char dd;

  TL0=TL0+30;TH0=0xfb; //800

  time++;

  if ((++s001)>=800) s001=0;

  // 显示

  if ((++dig)>4) dig=0;

  d_st=0;

  dd=d[dig+5];

  out_displ(dd);

  dd=d[dig];

  out_displ(dd);

  out_disp(un_dig[dig]);

  d_st=1;

  }

  void main(void) {

  unsigned char i;

  TMOD=0x1;

  TR0=ET0=1;

  EA=1;

  for (i=0;i<10;i++) d[i]=i; //display test

  while (1) {}

  }


 
  
  
  
  
 
更多>同类技术
 
全年征稿 / 资讯合作
 
推荐图文
推荐技术
可能喜欢