以 电子时钟 为结尾篇,附上代码。代码有些不怎么完美。但终究是差不多写出来了。结合了IIC通信,中断定时器的使用,键盘使用,还有液晶的显示。
#include <reg52.h> sbit RS = P2^7;sbit RW = P2^6;sbit E = P2^5;sbit Sda = P2^0;sbit Scl = P2^1;sbit keyleft = P1^0;sbit keyup = P1^1;sbit keydown = P1^2;sbit keyright = P1^3;unsigned char sec=0,min=0,hour=0;unsigned char Year[20]=" 2012.10.1 ";unsigned char i;unsigned int times = 0;unsigned char countleft = 0,countright = 0;unsigned char busycheck();static void Start(void){Sda = 1;Scl = 1;Sda = 0;}static void Stop(void){Sda = 0;Scl = 1;Sda = 1;}static unsigned char Respons(void){unsigned char OverTime = 0; //超时unsigned char TempFlag = 0;OverTime = 0; Sda = 1; //释放数据线 Scl = 1;while(1){if(Sda) //应答信号没来{if(OverTime++ > 200){ TempFlag = 0; //应答信号长时间没有来,认为无应答 break;}}else{ TempFlag = 1; ///检测到应答信号break;}}Scl = 0;return TempFlag;}static void NoRespons(void) //非应答{ Sda = 1; //释放数据线 Scl = 1;Scl = 0;}static void WriteByte(unsigned char temp){unsigned char i;Scl = 0;for(i = 0;i < 8;i++){Sda = temp & 0x80;temp <<= 1;Scl = 1; //scl拉高,准备写数据Scl = 0; //scl拉低,写数据完成}}static unsigned char ReadByte(void){unsigned char i;unsigned char x = 0;for(i = 0;i < 8;i++){Scl = 1;x <<= 1;x |= (unsigned char)Sda;Scl = 0;}return x;}void WriteIIC(unsigned char device,unsigned char parameter,unsigned char temp){Start();WriteByte(device);if(Respons()){WriteByte(parameter);if(Respons()){WriteByte(temp);if(Respons()){Stop();}else{Stop();}}else{Stop();}}else{Stop();}}unsigned char ReadIIC(unsigned char device,unsigned char parameter){unsigned char x;Start();WriteByte(device);if(Respons()){WriteByte(parameter);if(Respons()){Start();WriteByte(device | 0x01);if(Respons()){x = ReadByte();NoRespons();Stop();}else{Stop();}}else{Stop();}}else{Stop();}return x;}void writecmd(unsigned char cmd){while(busycheck());RS = 0;RW = 0;E = 1;P0 = cmd;E = 0;}void writedata(unsigned char dat){while(busycheck());RS = 1;RW = 0;E = 1;P0 = dat;E = 0;}unsigned char busycheck(){P0 = 0xff;RS = 0;RW = 1;E = 0;E = 1;return(P0 & 0x80);}void writedate(unsigned char add,unsigned char date){unsigned char shi,ge;shi = date/10;ge = date%10;writecmd(0x80+0x40+add);writedata(0x30+shi);writedata(0x30+ge);}void Init(){writecmd(0x38);//显示模式 writecmd(0x08);//关屏 writecmd(0x01);//清屏 writecmd(0x06);//设置光标右移writecmd(0x0c);//显示,无标 闪烁writecmd(0x80);for(i = 0;i < 20;i++)writedata(Year[i]);writecmd(0x80+0x40+6);writedata(':');writecmd(0x80+0x40+9);writedata(':');sec = ReadIIC(0xa0,0);min = ReadIIC(0xa0,2);hour = ReadIIC(0xa0,4);writedate(10,sec);writedate(7,min);writedate(4,hour);TMOD = 0x02;TH0 = 6;TL0 = 6;EA = 1;ET0 = 1;TR0 = 1;}void delay(){unsigned char x = 2000;while(x--);}void keyscan(){if(!keyleft){delay();if(!keyleft){TR0 = 0;if(countleft == 0){countleft++;writecmd(0x80+0x40+10);writecmd(0x0f);}elseif(countleft == 1){countleft++;writecmd(0x80+0x40+7);}elseif(countleft == 2){countleft++;writecmd(0x80+0x40+4);}elseif(countleft == 3){TR0 = 1;writecmd(0x0c);countleft = 0;}else{} }else{}}else{}if(!keydown){delay();if(!keydown){if(countleft == 1){sec--;if(sec == 60)sec = 0;writedate(10,sec);WriteIIC(0xa0,1,sec);writecmd(0x80+0x40+10);}elseif(countleft == 2){min--;if(min == 60)min = 0;writedate(7,min);WriteIIC(0xa0,2,min);writecmd(0x80+0x40+7);}elseif(countleft == 2){hour--;if(hour == 24)hour = 0;writedate(4,hour);WriteIIC(0xa0,3,hour);writecmd(0x80+0x40+4);}else{} }else{}}else{}if(!keyright){delay();if(!keyright){if(countleft == 1){sec++;if(sec == 60)sec = 0;writedate(10,sec);writecmd(0x80+0x40+10);}elseif(countleft == 2){min++;if(min == 60)min = 0;writedate(7,min);writecmd(0x80+0x40+7);}elseif(countleft == 2){hour++;if(hour == 24)hour = 0;writedate(4,hour);writecmd(0x80+0x40+4);}else{} }else{}}else{}}void main(){Init();while(1){keyscan();}}void Time0(void) interrupt 1{times++;if(times == 3686){times = 0;sec++;if(sec == 60){sec = 0;min++;if(min == 60){min = 0;hour++;if(hour == 24){hour = 0;}writedate(4,hour);WriteIIC(0xa0,3,hour);}writedate(7,min);WriteIIC(0xa0,2,min);}writedate(10,sec);WriteIIC(0xa0,1,sec);}}