打印
[经验分享]

一些实用的单片机c程序

[复制链接]
1784|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
suoma|  楼主 | 2009-11-19 20:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一些实用的单片机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<e;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 <reg51.h>
#i nclude <intrins.h>
#i nclude <absacc.h>
#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;
     }
}
沙发
suoma|  楼主 | 2009-11-19 20:15 | 只看该作者
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;
}
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 hzk16\n");
         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();
     }
}
//按键扫描驱动程序

使用特权

评论回复
板凳
suoma|  楼主 | 2009-11-19 20:16 | 只看该作者
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个数值即可。
//因此,该定义具有通用性。

//    显示   
//        -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) {}
}

使用特权

评论回复
地板
lovelyegle| | 2009-11-19 22:34 | 只看该作者
收下了···

使用特权

评论回复
5
huamunv| | 2009-12-1 13:08 | 只看该作者
先收藏了,说不定能用上点

使用特权

评论回复
6
suoma|  楼主 | 2009-12-1 17:23 | 只看该作者
:P

使用特权

评论回复
7
gzh19680820| | 2011-11-7 15:02 | 只看该作者
学习学习!!!!!!!!

使用特权

评论回复
8
pengf| | 2011-11-8 10:43 | 只看该作者
我再N年前就看过

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

82

主题

714

帖子

5

粉丝