51最基础简单易懂的单片机,差不多一个月的时间,断断续续地学习,终于算是学完了,下个目标是飞思卡尔s12x和k60 也就是 crotex-M4架构. 51最核心的部分,我觉得是中断的使用,一个项目离不开中断,还有就是串口的理解,还有就是IIC通信。
以 电子时钟 为结尾篇,附上代码。代码有些不怎么完美。但终究是差不多写出来了。结合了IIC通信,中断定时器的使用,使用,还有液晶的显示。
#includesbit 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); } else if(countleft == 1) { countleft++; writecmd(0x80+0x40+7); } else if(countleft == 2) { countleft++; writecmd(0x80+0x40+4); } else if(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); } else if(countleft == 2) { min--; if(min == 60) min = 0; writedate(7,min); WriteIIC(0xa0,2,min); writecmd(0x80+0x40+7); } else if(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); } else if(countleft == 2) { min++; if(min == 60) min = 0; writedate(7,min); writecmd(0x80+0x40+7); } else if(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); }}
-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。