51单片机基础
寫在前面:51單片機有一些基礎(chǔ)理論概念,大家一般都已經(jīng)了解或者在百度上能查找到詳細說明,博主就會省略,所以以下內(nèi)容比較精煉,大家看完之后都能上手敲出代碼,控制51單片機。但是想要融會貫通,真正精通51單片機,還需要大家私下不斷編寫代碼,燒錄程序。
一、LED
LED點亮,閃爍,流水燈見之前的博客。
二、蜂鳴器
蜂鳴器見之前博客。
三、 數(shù)碼管
見之前博客(上傳word文檔形式)。
四、鍵盤
見之前博客(上傳word文檔形式)。
五、8*8點陣屏
見之前博客(上傳word文檔形式)。
以上五個板塊為51單片機基礎(chǔ)中的基礎(chǔ),下面我們來看51單片機中的基礎(chǔ)中的中級內(nèi)容。
六、中斷系統(tǒng)
1.什么是中斷:
計算機執(zhí)行某程序時,發(fā)生了緊急事件或有特殊請求,CPU暫停某程序的執(zhí)行,轉(zhuǎn)而去處理上述事件或請求,處理完畢后再重新執(zhí)行某程序的過程叫做中斷。
2.實現(xiàn)外部中斷:
言簡意賅,需要先進行外部中斷1初始化,再編寫中斷服務(wù)函數(shù)。中斷初始化:a.打開總中斷,然后b.開外部中斷,c.配置外部中斷觸發(fā)方式。實現(xiàn)代碼如下:(以開外部中斷1為例)
之后在主函數(shù)中引用此初始化函數(shù)即可。
初始化之后需要編寫中斷服務(wù)函數(shù)。
中斷小結(jié):主函數(shù)中引用中斷初始化函數(shù),之后一旦觸發(fā)中斷,即CPU停下正在處理的事,執(zhí)行中斷服務(wù)函數(shù)。(關(guān)于中斷初始化函數(shù)中控制位的說明,我會在文章最后附上STC89C52使用手冊,控制位記不住在手冊中查詢即可)
七、定時計數(shù)器
1.51單片機上的定時計數(shù)器:
51單片機有2個16位定時器/計數(shù)器:定時器0(T0為P3.4)和定時器1(T1為P3.5),這里所說的16位是指定時/計數(shù)器內(nèi)部分別有16位的計數(shù)寄存器。
當(dāng)工作在定時模式時,每經(jīng)過一個機器周期內(nèi)部的16位計數(shù)寄存器的值就會加1,當(dāng)這個寄存器裝滿時溢出。我們可以算出工作在定時模式時最高單次定時時間為65535*1.085us=時間(單位us)當(dāng)工作在計數(shù)器模式時,T0(P3.4引腳),T1(P3.5引腳)每來一個脈沖計數(shù)寄存器加1。
2.基本步驟
定時器定時
a.定時器初始化:啟動定時/計數(shù)器(通過TCON控制器),設(shè)置定時/計數(shù)器工作模式(通過TMOD控制器)
b.查詢定時/計數(shù)器是否溢出(讀TCON內(nèi)TF位)
定時器初始化
b.在主函數(shù)中查詢定時計數(shù)器是否溢出
定時器計數(shù):這里我們用定時器1做計數(shù)器,即使用定時器1的定時功能,然后用定時器0做計數(shù)器使用。
初始化函數(shù)
主函數(shù)引用
通過計數(shù)器每500ms使LED=~LED,產(chǎn)生一次方波,計數(shù)器加1,期間不斷進行display函數(shù)的掃描。
定時器中斷:
初始化:需要啟動相應(yīng)中斷和啟動定時器
根據(jù)工作模式,中斷服務(wù)函數(shù)里需要設(shè)置初值:
void timer0 () interrupt 1//中斷入口 {TH0=0xed;TL0=0xff;dispaly(num);//數(shù)碼管顯示函數(shù) }PS:以下內(nèi)容為實現(xiàn)的基礎(chǔ)代碼及注釋,文章最后會上傳STC89C52使用手冊和開發(fā)板原理圖,各位瀏覽資料相應(yīng)位置結(jié)合代碼即可理解(STC89C52使用手冊,開發(fā)板原理圖借用“清翔MCS51開發(fā)板資料”)
八、串口通信
1.基礎(chǔ)步驟:
串口初始化、串口中斷函數(shù)
串口初始化:
波特率=2^SMOD·fosc/32·12·(256-T初)
串口中斷函數(shù):
九、 IIC總線EEPROM
有2個主功能函數(shù),6主功能輔助函數(shù)
歸結(jié)為:PS:()中內(nèi)容為從機操作
寫入一字節(jié)步驟:S,器件地址+0,(A),寫入首地址,(A),Dat,(A),P
讀出一字節(jié)步驟:S,器件地址+0,(A),讀出首地址,(A),S,器件地址+1,(A),(Dat),NA,P
十、ADDA數(shù)模轉(zhuǎn)換
90%類似EEPROM操作。(九中前6個函數(shù)一樣,后2個函數(shù)步驟有細微差異)
寫入一字節(jié):S,器件地址+0,(A),發(fā)送控制字節(jié),(A),Dat,(A),P
讀出一字節(jié):S,器件地址+0,(A),發(fā)送控制字節(jié),(A),S,器件地址+1;(A),(Dat),NA,P
十一、數(shù)字溫度傳感器DS18B20
包括:初始化函數(shù),寫一字節(jié)函數(shù),讀一字節(jié)函數(shù)
注意,主機和DS18B20做任何通訊之前都需要對其初始化
操作一般步驟:初始化,ROM指令,操作指令
十二、紅外通訊
//初始化函數(shù) void init() {TMOD = 0x22; TH0 = 0x00; TL0 = 0x00;EA = 1; ET0 = 1; TR0 = 1; IT0 = 1; EX0 = 1;TH1 = 0xfd; TL1 = 0xfd;TR1 = 1; SM1 = 1; ES=1; }void time0() interrupt 1 //定時器0中斷服務(wù)函數(shù) {IRtime++; }void int0() interrupt 0 {static uchar i; static bit startflag; if(startflag) {if( (IRtime < 53) && (IRtime >= 32) ) i = 0; IRdata[i] = IRtime; IRtime = 0; i++; if(i == 33) {IRok = 1; i = 0; }}else {IRtime = 0; startflag = 1; } }void IRcordpro() //解碼 {uchar i, j, k, cord, value; k = 1; for(i = 0; i < 4; i++){for(j = 0; j < 8; j++){cord = IRdata[k]; if(cord > 5) value = value | 0x80; if(j < 7){value = value >> 1; }k++; }IRcord[i] = value; value = 0; }IRpro_ok = 1; }void main() {uchar i;init(); while(1) {if(IRok) { IRcordpro();IRok = 0;if(IRpro_ok) {for(i = 0; i < 4; i++) { SBUF = IRcord[i];while(!TI);TI = 0;}IRpro_ok = 0;}} } }紅外通訊:脈寬檢測,解碼,傳輸數(shù)據(jù)
十三、實時時鐘DS1302
//寫DS1302數(shù)據(jù) void Write_DS1302_DAT(uchar cmd, uchar dat) {uchar i;TRST = 0; TSCLK = 0;TRST = 1; for(i = 0; i < 8; i++){TSCLK = 0; TIO = cmd & 0x01; TSCLK = 1; cmd >>=1; }for(i = 0; i < 8; i++){TSCLK = 0; TIO = dat & 0x01; TSCLK = 1; dat >>= 1; } } //讀DS1302數(shù)據(jù) uchar Read_DS1302_DAT(uchar cmd) {uchar i, dat;TRST = 0; TSCLK = 0; TRST = 1; for(i = 0; i < 8; i++){TSCLK = 0; TIO = cmd & 0x01;TSCLK = 1; cmd >>=1; }for(i = 0; i < 8; i++){TSCLK = 0; dat >>= 1; if(TIO) dat |= 0x80;TSCLK = 1; }return dat; } //數(shù)據(jù)轉(zhuǎn)BCD碼 uchar Dat_Chg_BCD(uchar dat) {uchar dat1, dat2;dat1 = dat / 10;dat2 = dat % 10;dat2 = dat2 + dat1 * 16;return dat2; } //BCD碼轉(zhuǎn)換為數(shù)據(jù) uchar BCD_Chg_Dat(uchar dat) {uchar dat1, dat2;dat1 = dat / 16;dat2 = dat % 16;dat2 = dat2 + dat1 * 10;return dat2; } void main() { uchar i;uchar Sec, Min, Hour;Write_DS1302_DAT(0x8e, 0);Write_DS1302_DAT(0x80, Dat_Chg_BCD(30));Write_DS1302_DAT(0x82, Dat_Chg_BCD(15));Write_DS1302_DAT(0x84, Dat_Chg_BCD(19));Write_DS1302_DAT(0x8e, 0x80);while(1){ Write_DS1302_DAT(0x8e, 0); Sec = BCD_Chg_Dat(Read_DS1302_DAT(0x81));Min = BCD_Chg_Dat(Read_DS1302_DAT(0x83));Hour = BCD_Chg_Dat(Read_DS1302_DAT(0x85));Write_DS1302_DAT(0x8e, 0x80);for(i = 0; i < 50; i++) Display(Hour, Min, Sec); } }十四、LCD1602液晶
//判斷液晶忙 void Read_Busy() {uchar busy;P0 = 0xff;RS = 0;RW = 1;do{EN = 1;busy = P0;EN = 0;}while(busy & 0x80); } //寫LCD1602命令一個字節(jié) void Write_Cmd(uchar cmd) {Read_Busy();//判斷忙RS = 0;RW = 0;P0 = cmd;EN = 1;EN = 0; } //寫一個字節(jié)數(shù)據(jù) void Write_Dat(uchar dat) {Read_Busy();RS = 1;RW = 0;P0 = dat;EN = 1;EN = 0; } void main() { Write_Cmd(0x38);Write_Cmd(0x0f);Write_Cmd(0x01);Write_Cmd(0x06);Write_Cmd(0x80 | 0x06);Write_Dat(1 + '0');Write_Dat(2 + '0');Write_Dat(3 + '0');Write_Dat(4 + '0');Write_Dat(5 + '0');while(1); }十五、手機藍牙控制51最小系統(tǒng)
void UART_INIT() {SM0 = 0;SM1 = 1;REN = 1;EA = 1;ES = 1;TMOD = 0x20;TH1 = 0xfd;TL1 = 0xfd;TR1 = 1; } //串口中斷 void UART_SER() interrupt 4 {if(RI){RI = 0;switch(SBUF){case 0x01: LED1 = 0; break;case 0x02: LED1 = 1; break;}} } void main() {UART_INIT();while(1); }以上就是51單片機的基礎(chǔ)內(nèi)容(濕度傳感器,電機驅(qū)動,藍牙,WiFi四個板塊博主也會在近期寫出相應(yīng)博客),后面一些章節(jié)因為時間匆忙,只有代碼,各位可以結(jié)合以下博主上傳的開發(fā)板原理圖資料自己消化理解,結(jié)合實際,相信大家一定可以學(xué)好51單片機,共勉!
PS:開發(fā)板原理圖是借用的此清翔MCS51開發(fā)板資料。
STC89C52使用手冊大家可以在網(wǎng)絡(luò)上找以下資源,里面內(nèi)容也是非常重要的。
總結(jié)
- 上一篇: 【例4-3】利用数组,给定N个正整数数据
- 下一篇: layout_gravity和gravi