51最基礎(chǔ)簡單易懂的單片機(jī),差不多一個月的時間,斷斷續(xù)續(xù)地學(xué)習(xí),終于算是學(xué)完了,下個目標(biāo)是飛思卡爾s12x和k60 也就是ARM crotex-M4架構(gòu). 51最核心的部分,我覺得是中斷的使用,一個項目離不開中斷,還有就是串口的理解,還有就是IIC通信。
以 電子時鐘 為結(jié)尾篇,附上代碼。代碼有些不怎么完美。但終究是差不多寫出來了。結(jié)合了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; //釋放數(shù)據(jù)線 Scl = 1; while(1) { if(Sda) //應(yīng)答信號沒來 { if(OverTime++ > 200) { TempFlag = 0; //應(yīng)答信號長時間沒有來,認(rèn)為無應(yīng)答 break; } } else { TempFlag = 1; ///檢測到應(yīng)答信號 break; } } Scl = 0; return TempFlag; } static void NoRespons(void) //非應(yīng)答 { Sda = 1; //釋放數(shù)據(jù)線 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拉高,準(zhǔn)備寫數(shù)據(jù) Scl = 0; //scl拉低,寫數(shù)據(jù)完成 } } 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);//關(guān)屏 writecmd(0x01);//清屏 writecmd(0x06);//設(shè)置光標(biāo)右移 writecmd(0x0c);//顯示,無標(biāo) 閃爍 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); } }