分享我的一个成功的项目源码:
- #include<reg52.h>//51单片机头文件
- #define uchar unsigned char//宏定义
- #define uint unsigned int
- //uchar code smg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数码管段码
- //uchar code smg_we[]={0x00,0x04,0x08,0x0c,0x10,0x14,0x18,0x1f};//数码管位码
- uchar code digit[]={"0123456789"};//定义字符数组数字
- uchar disp[8];//存储拆开的数
- uint cnt;//中断次数
- uchar v;//电机0速度
- uchar date,num,CYCLE,PWM_ON;
- sbit sda=P2^0;
- sbit scl=P2^1;
- uchar flag; //计满1秒钟标志位
- uint i;
- char j,k=5;
- /////////
- sbit PWM=P1^0; //pwm输出口
- sbit rs=P2^6;//数据命令选择
- sbit rw=P2^5;//读写控制信号
- sbit e=P2^7;//使能信号
- ///////////////
- void delay1() //微秒延时
- {;;}
- /////
- void start() //I2C开始信号
- {
- sda=1;
- delay1();
- scl=1;
- delay1();
- sda=0;
- delay1();
- }
- void stop() //I2C停止信号
- {
- sda=0;
- delay1();
- scl=1;
- delay1();
- sda=1;
- delay1();
- }
- void respons() //I2C应答信号
- {
- uchar i;
- scl=1;
- delay1();
- while((sda==1)&&(i<250))i++;
- scl=0;
- delay1();
- }
- void writebyte(uchar date) //I2C写信号
- {
- uchar i,temp;
- temp=date;
- for(i=0;i<8;i++)
- {
- temp=temp<<1;
- scl=0;
- delay1();
- sda=CY;
- delay1();
- scl=1;
- delay1();
- }
- scl=0;
- delay1();
- sda=1;
- delay1();
- }
- uchar readbyte() //I2C读信号
- {
- uchar i,k;
- scl=0;
- delay1();
- sda=1;
- for(i=0;i<8;i++)
- {
- scl=1;
- delay1();
- k=(k<<1)|sda;
- scl=0;
- delay1();
- }
- return k;
- }
- void init1() //初始化
- {
- scl=1;
- delay1();
- sda=1;
- delay1();
- }
- uchar read_ad(uchar channel) //读取ad转换结果
- {
- uchar num;
- start();
- writebyte(0x90);
- respons();
- writebyte(0x40|channel);
- respons();
- start();
- writebyte(0x91);
- respons();
- num=readbyte();
- stop();
- return num;
- }
- /////
- void delay_50us(uint t)//50us延时函数
- {
- uchar j;
- for(;t>0;t--)
- for(j=19;j>0;j--);
- }
- void write_com(uchar com)//写地址
- {
- e=0;
- rs=0;
- rw=0;
- P0=com;
- delay_50us(10);
- e=1;
- delay_50us(10);
- e=0;
- }
- ///////
- void write_data(uchar dat)// 写数据
- {
- e=0;
- rs=1;
- rw=0;
- P0=dat;
- delay_50us(10);
- e=1;
- delay_50us(10);
- e=0;
- }
- //////
- void init(void)//液晶初始化
- {
- delay_50us(300);
- write_com(0x38);
- delay_50us(100);
- write_com(0x38);
- delay_50us(100);
- write_com(0x38);
- write_com(0x38);
- write_com(0x08);
- write_com(0x01);
- write_com(0x06);
- write_com(0x0c);
- }
- /////////////
- void writeaddress(uchar x)//指定字符的实际地址
- {
- write_com(x|0x80);//显示位置的确定方法规定为“80h+地址码x“
- }
- //////////
- void display_sym(void)//显示速度提示符
- {
- writeaddress(0x00);//写显示地址第一行第一列
- write_data('v');//写数据v
- write_data('=');//写数据=
- }
- //////
- void dispose()//
- {
- disp[0]=v/1000;
- disp[1]=(v%1000)/100;
- disp[2]=(v/100)/10;
- disp[3]=v%10;
- }
- /////////////
- void display_val(void)
- {
- writeaddress(0x02);//写显示地址,第一行第三列
- write_data(digit[disp[0]]);//千
- write_data(digit[disp[1]]);//百
- write_data(digit[disp[2]]);//时
- write_data(digit[disp[3]]);//个
- }
- ////////
- void display_uint(void)//显示速度单位
- {
- writeaddress(0x06);//第1行第7列
- write_data('r');//千
- write_data('/');//百
- write_data('m');//时
- write_data('i');//个
- write_data('n');//个
- }
- void initial()//初始化
- {
- TMOD=0x51; //定时器T1工作与计数器模式1,定时器T0工作于计数器模式1
- RCAP2H=(65536-50000)/256;
- RCAP2L=(65536-50000)%256;
- TH0=(65536-1000)/256;
- TL0=(65536-1000)%256;
- ET0=1;
- TR0=1;
- ET2=1;
- TR2=1;
- EA=1;
- }
- ///////
- void main()
- {
- init();
- init1();
- v=0;
- CYCLE = 100;
- initial();
- cnt=0;
- display_sym();
- display_uint();
- while(1)
- {
- num=num=read_ad(0);
- PWM_ON=num;
- TR1=1;
- TH1=0;
- TL1=0;
- flag=0; // 时间还未满1分钟
- while(flag==0); // 时间未满等待
- v=(TH1*256+TL1)*60/20; // 计算速度,每周产生20个脉冲
- dispose();
- display_val();
- }
- }
- //////
- void time2() interrupt 5//定时器T2中断服务程序
- {
- TF2=0;
- cnt++;
- if(cnt==20)
- {
- flag=1;
- cnt=0;
- }
- }
- //////
- void tim(void) interrupt 1 using 1
- {
- static unsigned char count; //
- TH0=(65536-1000)/256;
- TL0=(65536-1000)%256;//定时1mS
- if (count==PWM_ON)
- {
- PWM = 1; //灯灭
- }
- count++;
- if(count == CYCLE)
- {
- count=0;
- if(PWM_ON!=0) //如果左右时间是0 保持原来状态
- PWM = 0;//灯亮
- }
- }
复制代码
|