RT最近在做一個小制作,用單片機設計一個時鐘,我用外部中斷0做了一個模式切換的功能,每按一下中斷觸發鍵就可以使變量mod加一。其他兩個模式(時鐘調整,鬧鐘調整)都能正常的切換,但是最后一個利用串口連接手機校準時間的模式無法正常切換,進去就卡在那里切不出去,實在是不知道為什么了,麻煩大佬幫我看一眼,多謝!代碼寫的少,可能寫的很不好,如果有建議希望大佬多指教!
為了閱讀方便我刪去了前兩個模式的代碼,用定時器0來生成秒,send函數和receive函數利用了定時器1來生成波特率,串口校準模式的設計思路是先發送一個“1”給手機,再接收手機發送的“1”,確定連接建立后再接收手機發送的數據。因為手機端的開發還沒做完,所以暫時測試只用來校準hour
單片機源程序如下:
- #include<reg52.h>
- typedef unsigned int u16; //對數據類型進行聲明定義
- typedef unsigned char u8;
- #define data8b P0
- sbit K1=P3^2; //外部中斷0
- sbit K2=P3^3; //外部中斷1
- sbit K3=P3^4;
- sbit K4=P3^5;
- sbit p=PSW^0;
- sbit RW=P2^1; //4腳,數據(1)or命令(0)
- sbit RS=P2^0; //5腳,讀(1)寫(0)
- sbit E=P2^2; //6腳,使能信號
- u8 code dat1[]={0X30,0X31,0X32,0X33,
- 0X34,0X35,0X36,0X37,
- 0X38,0X39};
- //LCD1602字符
-
- u8 min=0,hour=0; //時間初始化
- u16 i=0;
- u8 s=0;
- u8 mod=0; //mod初值
- bit signal=0; //發送
- u8 temp=0;
-
-
- void delay(u16 i) //延時函數
- {
- while(i--);
- }
- void open012() //打開中斷0,1,定時器中斷0
- {
- TMOD|=0X01; //選擇為定時器0模式,工作方式1
-
- ET0=1; //打開定時器0中斷允許
- EA=1; //打開總中斷
- TR0=1; //打開定時器
- EX0=1; //打開外部中斷0
- IT0=1; //邊沿觸發方式
- EX1=1; //打開外部中斷1
- IT1=1; //邊沿觸發
-
- }
- void wrm(u8 dat) //寫入命令
- {
- delay(1000);
- RS=0;
- RW=0;
- E=0;
- data8b=dat;
- E=1;
- delay(1000);
- E=0;
- }
- void wrd(u8 dat) //寫入數據
- {
- delay(1000);
- RS=1;
- RW=0;
- E=0;
- data8b=dat;
- E=1;
- delay(1000);
- E=0;
- }
- void init() //LCD初始化
- {
- wrm(0X38); //八位數據,兩行顯示,5*7
- wrm(0X0c); //無光標,打開顯示
- wrm(0X06); //光標右移,屏幕不移動
- wrm(0X01); //清屏
- wrm(0X80); //設置數據指針起點
- }
- void display()
- {
- wrd(dat1[hour/10]); //時十位
- wrd(dat1[hour%10]); //時個位
- wrd(0x3A); //:
- wrd(dat1[min/10]); //分十位
- wrd(dat1[min%10]); //分個位
- wrd(0x3A); //:
- wrd(dat1[(s/10)]); //秒十
- wrd(dat1[(s%10)]); //秒個
- }
- //秒個
- void chuli() //處理進位
- {
- if(min==60)
- {
- hour++;
- min=0;
- }
- if(hour==24)
- {
-
- hour=0;
- }
-
- if(s==60)
- {
- min++;
- s=0;
- }
-
- }
- void send() //發送函數,定時器T1為方式2,串口為方式3,波特率9600,采用偶校驗
- {
- TMOD=0x20;
- SCON=0xc0;
- PCON=0x00;
- TH1=0xfd;
- TL1=0xfd;
- TB8=P;
- SBUF=1;
- while(TI==0);
- ;
- TI==0;
- }
- u8 receive() //接收函數
- {
- u8 dat;
- TMOD=0x20;
- SCON=0xd0;
- PCON=0x00;
- TH1=0xfd;
- TL1=0xfd;
- TR1=1;
- REN=1;
-
- while(RI==0);
- ;
- RI==0;
- ACC=SBUF;
- if(RB8==P)
- {
- dat=ACC;
- return dat;
- }
- }
- void dis_string(u8 *pp, u16 n) //顯示字符串的函數
- {
- int i;
- for (i=0;i<n;i++)
- wrd(pp[i]);
- }
- u8 p1[]="connecting";
- u8 p2[]="OK!";
- u8 p3[]="over";
- void main()
- {
- IP=1;
- open012();
- init();
- chuli();
- display();
-
-
-
-
- while(1)
- {
- while(mod==0)
- {
- EX1=1; //打開外部中斷1
- chuli();
- wrm(0x80);
- display();
- }
-
-
-
-
- while(mod==1)
- {
- init();
- EX1=0;
- TR0=0;
- TR1=1;
- dis_string(p1,10); //輸出字符connecting
- wrm(0x80+0x40); //換行
- send();
- delay(1000);
- signal=receive();
- while(1)
- {
- if(signal=1)
- {
- dis_string(p2,3); //如果標志位=1,則連接成功,輸出ok!;如果標志位為0,則繼續接收
- break;
- }
-
- else if(signal=0)
- {
- signal=receive();
- }
- }
- send();
- temp=receive(); //將接受數據裝入temp中并賦給hour;
- hour=temp;
- init();
- if(temp!=0)
- {
- dis_string(p3,4); //輸出over
- delay(1000);
- }
-
-
- TR1=0;
-
- }
- }
- }
-
-
-
-
-
- void time0() interrupt 1
- {
- TH0=0XFC; //給定時器賦初值,定時1ms
- TL0=0X18;
- i++;
- if(i==1000) //ms轉化為s
- {
- i=0;
- s++;
-
- }
- }
- void key1() interrupt 0 //外部中斷0,切換模式
- {
- EX0=0;
- delay(1000);
- if(K1==0)
- {
-
- mod++;
- while(!K1);
- }
- if(mod>1)
- {
- mod=0;
- }
- EX0=1;
- }
復制代碼 |