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;
- }
复制代码 |