分享我的一個成功的項目源碼:
- #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;//燈亮
- }
- }
復制代碼
|