?? 專欄簡介:本專欄記錄了從零學(xué)習(xí)單片機(jī)的過程,其中包括51單片機(jī)和STM32單片機(jī)兩部分;建議先學(xué)習(xí)51單片機(jī),其是STM32等高級(jí)單片機(jī)的基礎(chǔ);這樣再學(xué)習(xí)STM32時(shí)才能融會(huì)貫通。
?? 專欄適用人群 :適用于想要從零基礎(chǔ)開始學(xué)習(xí)入門單片機(jī),且有一定C語言基礎(chǔ)的的童鞋。
??專欄目標(biāo):實(shí)現(xiàn)從零基礎(chǔ)入門51單片機(jī)和STM32單片機(jī),力求在玩好單片機(jī)的同時(shí),能夠了解一些計(jì)算機(jī)的基本概念,了解電路及其元器件的基本理論等。?? 專欄主要內(nèi)容: 主要學(xué)習(xí)51單片機(jī)的功能、各個(gè)模塊、單片機(jī)的外設(shè)、驅(qū)動(dòng)等,最終玩好單片機(jī)和單片機(jī)的外設(shè),全程手敲代碼,實(shí)現(xiàn)我們所要實(shí)現(xiàn)的功能。
?? 專欄說明 :如果文章知識(shí)點(diǎn)有錯(cuò)誤的地方,歡迎大家隨時(shí)在文章下面評(píng)論,我會(huì)第一時(shí)間改正。讓我們一起學(xué)習(xí),一起進(jìn)步。
??專欄主頁:http://t.csdn.cn/HCD8v
本學(xué)習(xí)過程參考:https://space.bilibili.com/383400717
單片機(jī)安裝軟件、各種資料以及源碼的路徑:
https://pan.baidu.com/s/1vDTN2o8ffvczzNQGfyjHng
提取碼:gdzf
一、本節(jié)背景和目標(biāo)
1.1 獨(dú)立按鍵的原理(很重要!?。。?/h3>
獨(dú)立按鍵在開發(fā)板上的位置如下圖所示,左右到右依次是K1、K2、K3、K4
獨(dú)立按鍵的原理圖如下所示:
其在MCU上的位置如下所示:
由上面兩張圖可以知道,獨(dú)立按鍵是接在MCU的P3.0口到P3.3口的;
可以看到,獨(dú)立按鍵的右端是接地的;這里需要注意,獨(dú)立按鍵跟LED燈的原理有區(qū)別,LED燈是通過高低電平通電,進(jìn)而使燈亮;而獨(dú)立按鍵不一樣,獨(dú)立按鍵的一端接地,獨(dú)立按鍵就是一個(gè)開關(guān);以K1為例,K1右端是GND,左端是RXD,我們知道,單片機(jī)在剛上電時(shí),所有i/o口默認(rèn)都是高電平的;所以當(dāng)K1按鍵沒有按下時(shí),RXD是高電平,但當(dāng)K1按鍵按下時(shí),電路進(jìn)行了連通,RXD接通了GND,所以RXD此時(shí)變成了低電平。
從上一篇文章中我們知道了,在寄存器中寫入一個(gè)值,該值就會(huì)同步到對(duì)應(yīng)的i/o口上;其實(shí)反之也成立,即通過寄存器可以讀到i/o口的狀態(tài),是高電平還是低電平。
所以當(dāng)按鍵沒有按下時(shí),寄存器讀到的該i/o的狀態(tài)就是高電平(即1);反之,當(dāng)按鍵按下時(shí),寄存器就可以讀到該i/o口的狀態(tài)為低電平(即0)
;我們則可以通過寄存器讀到的i/o口的狀態(tài)是高電平還是低電平,就知道按鍵是按下還是松開了,進(jìn)一步可以寫程序?qū)π暨M(jìn)行控制。
1.2 本節(jié)目標(biāo)
目標(biāo)1:獨(dú)立按鍵控制LED亮滅
K1控制LED燈D1的亮滅,即按下K1(持續(xù)不松開)時(shí)D1亮,松開D1時(shí)D1滅;如下圖所示
目標(biāo)2:獨(dú)立按鍵控制LED狀態(tài)
還是K1控制D1燈,現(xiàn)象是K1按一下并松開,D1點(diǎn)亮;再按一下并松開,D1滅;再按一下并松開,D1變亮;再按一次并松開,D1滅;如下圖
目標(biāo)3:獨(dú)立按鍵控制LED顯示二進(jìn)制
每按下并松開一次K1,LED燈點(diǎn)亮一次,多次按下并松開,實(shí)現(xiàn)按照二進(jìn)制遞增的順序進(jìn)行點(diǎn)亮;具體的說,可以將8個(gè)等比作8個(gè)二進(jìn)制數(shù)字,最右邊的亮表示1,右邊第二個(gè)燈亮表示2,右邊第三個(gè)燈亮表示4,右邊第四個(gè)燈亮表示8;以此類推;也可以知道,右邊第一個(gè)和右邊第二個(gè)燈同時(shí)亮表示3(1+2)以此類推;每次按下并松開一次K1,此8個(gè)燈中亮起的一個(gè)或幾個(gè)燈組成的數(shù)字就加1;如下圖所示:
目標(biāo)4:獨(dú)立按鍵控制LED移位
按下K1并松開時(shí),LED燈向左移一位;按下K2時(shí),LED燈向右移一位。
K1每按下一次,LED燈向左移動(dòng)一位:
K2每按下一次,LED燈向右移動(dòng)一位:文章來源:http://www.zghlxwxcb.cn/news/detail-716265.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-716265.html
二、獨(dú)立按鍵控制LED亮滅
代碼路徑:51單片機(jī)入門教程資料\課件及程序源碼\程序源碼\KeilProject\3-1 獨(dú)立按鍵控制LED亮滅
代碼實(shí)現(xiàn):
#include <REGX52.H>
void main()
{
while(1)
{
if(P3_1==0 || P3_0==0) //如果K1按鍵或K2按鍵按下
{
P2_0=0; //LED1輸出0,點(diǎn)亮
}
else
{
P2_0=1; //LED1輸出1,熄滅
}
}
}
代碼解釋:
P3_1和P3_0分別表示按鍵K1和按鍵K2在MCU上的端口;P3_0等于0表示通過寄存器讀到的P3_0端口電平狀態(tài)為低電平,由1.1 獨(dú)立按鍵的原理中可知,按鍵按下時(shí)對(duì)應(yīng)的i/o口為低電平,按鍵松開時(shí)對(duì)應(yīng)的i/o口為高電平。所以P3_1==0
表示K2按鍵按下,P3_0==0
表示K1按鍵按下。
P2_0=0
表示P2_0端口賦值為低電平,即對(duì)應(yīng)的LED1燈點(diǎn)亮。注意,在上一篇文章的學(xué)習(xí)中,我們是對(duì)P2口整體進(jìn)行控制,所以使用P2=0xFE
這種方式,這種方式可以一次性控制8個(gè)燈的狀態(tài);例如P2=0xFE
就表示第一個(gè)燈亮,其他的均滅;但是除了對(duì)P2口整體進(jìn)行控制外,我們也可以分別對(duì)P2口的8個(gè)端口進(jìn)行控制,例如P2_0=0
則表示第一個(gè)燈亮,至于其他七個(gè)燈是什么狀態(tài),不管。
最終實(shí)現(xiàn)的效果就是目標(biāo)1:K1控制LED燈D1的亮滅,即按下K1(持續(xù)不松開)時(shí)D1亮,松開D1時(shí)D1滅;如下圖所示
三、獨(dú)立按鍵控制LED狀態(tài)
代碼路徑:51單片機(jī)入門教程資料\課件及程序源碼\程序源碼\KeilProject\3-2 獨(dú)立按鍵控制LED狀態(tài)
代碼實(shí)現(xiàn):
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
while(1)
{
if(P3_1==0) //如果K1按鍵按下
{
Delay(20); //延時(shí)消抖
while(P3_1==0); //松手檢測(cè)
Delay(20); //延時(shí)消抖
P2_0=~P2_0; //LED1取反
}
}
}
代碼解釋:P3_1==0
表示K1按鍵按下,上一節(jié)已經(jīng)進(jìn)行了解釋,這里不再解釋。Delay(20)
表示延時(shí)20ms,此延時(shí)函數(shù)的是通過stc-isp生成的,生成過程在上一篇文章中有講解,這里不再重復(fù)敘述。在里面加了參數(shù)xms
,是為了能實(shí)現(xiàn)延時(shí)時(shí)間可配置。
至于為什么要設(shè)置延時(shí)呢?目的是消除按鍵的抖動(dòng),什么事抖動(dòng)?
通俗的解釋,當(dāng)我們按下按鍵時(shí),并不會(huì)馬上接通,可能會(huì)進(jìn)行抖動(dòng),如 通->斷->通->斷
等過程逐漸的接通;當(dāng)然,在斷開時(shí),也不會(huì)馬上斷開,而是斷->通->斷->通
等過程;這些抖動(dòng)過程其實(shí)是不能作為準(zhǔn)確值的,所以要消除抖動(dòng)。
所以通過延時(shí)函數(shù),將抖動(dòng)期間的動(dòng)作忽略掉,就可以消除抖動(dòng)帶來的影響,達(dá)到的消抖的目的。
最終程序運(yùn)行的結(jié)果就是上面提到的目標(biāo)2:
還是K1控制D1燈,現(xiàn)象是K1按一下并松開,D1點(diǎn)亮;再按一下并松開,D1滅;再按一下并松開,D1變亮;再按一次并松開,D1滅;如下圖
四、獨(dú)立按鍵控制LED顯示二進(jìn)制
代碼路徑:51單片機(jī)入門教程資料\課件及程序源碼\程序源碼\KeilProject\3-3 獨(dú)立按鍵控制LED顯示二進(jìn)制
代碼實(shí)現(xiàn):
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void main()
{
unsigned char LEDNum=0;
while(1)
{
if(P3_1==0) //如果K1按鍵按下
{
Delay(20); //延時(shí)消抖
while(P3_1==0); //松手檢測(cè)
Delay(20); //延時(shí)消抖
LEDNum++; //變量自增
P2=~LEDNum; //變量取反輸出給LED
}
}
}
代碼解釋:
前面的代碼都跟上一節(jié)一致,就是判斷按鍵按下,且按鍵松開,以及延時(shí)消抖操作。
最主要的是LEDNum++以及P2=~LEDNum
兩行代碼;下面按照程序的運(yùn)行過程解釋一下這兩行代碼;
第一次按下并松開K1按鍵時(shí),進(jìn)入第一次進(jìn)入循環(huán),此時(shí)LEDNum
是0,所以LEDNum++
后的值即為1(十六進(jìn)制表示為0x0000 0001
);此時(shí)將LEDNum
取反后的值是0x1111 1110
,將這個(gè)值給到P2口;這樣8個(gè)LED燈的狀態(tài)為:高7位寄存器的值是1,即P20-P26口是高電平,則前7個(gè)LED燈都是滅的,同理,最低位的寄存器的值是0,則P27口是低電平,則最后一個(gè)LED燈是亮的;
第一次按下并松開K1按鍵時(shí),進(jìn)入第二次進(jìn)入循環(huán),此時(shí)LEDNum
是1,所以LEDNum++
后的值即為2(十六進(jìn)制表示為0x0000 0010
);此時(shí)將LEDNum
取反后的值是0x1111 1101
,將這個(gè)值給到P2口;這樣8個(gè)LED燈的狀態(tài)為:高6位以及最低位的寄存器的值是1,即P20-P25以及P27口是高電平,則前6個(gè)LED燈以及第8個(gè)LED燈都是滅的,同理,第7個(gè)LED燈是亮的;
依次類推,每按下并松開一次K1按鍵,則二進(jìn)制數(shù)字加1,對(duì)應(yīng)的寄存器和LED燈也都加一。
最終實(shí)現(xiàn)的效果就是目標(biāo)3:獨(dú)立按鍵控制LED顯示二進(jìn)制
每按下并松開一次K1,LED燈點(diǎn)亮一次,多次按下并松開,實(shí)現(xiàn)按照二進(jìn)制遞增的順序進(jìn)行點(diǎn)亮;具體的說,可以將8個(gè)等比作8個(gè)二進(jìn)制數(shù)字,最右邊的亮表示1,右邊第二個(gè)燈亮表示2,右邊第三個(gè)燈亮表示4,右邊第四個(gè)燈亮表示8;以此類推;也可以知道,右邊第一個(gè)和右邊第二個(gè)燈同時(shí)亮表示3(1+2)以此類推;每次按下并松開一次K1,此8個(gè)燈中亮起的一個(gè)或幾個(gè)燈組成的數(shù)字就加1;如下圖所示:
五、獨(dú)立按鍵控制LED位移
代碼路徑:51單片機(jī)入門教程資料\課件及程序源碼\程序源碼\KeilProject\3-4 獨(dú)立按鍵控制LED移位
代碼實(shí)現(xiàn):
#include <REGX52.H>
void Delay(unsigned int xms);
unsigned char LEDNum;
void main()
{
P2=~0x01; //上電默認(rèn)LED1點(diǎn)亮
while(1)
{
if(P3_1==0) //如果K1按鍵按下
{
Delay(20);
while(P3_1==0); //循環(huán)直到K1鍵松開
Delay(20);
LEDNum++; //LEDNum自增
if(LEDNum>=8) //限制LEDNum自增范圍
LEDNum=0;
P2=~(0x01<<LEDNum); //LED的第LEDNum位點(diǎn)亮
}
if(P3_0==0) //如果K2按鍵按下
{
Delay(20);
while(P3_0==0);//循環(huán)直到K2鍵松開
Delay(20);
if(LEDNum==0) //LEDNum減到0后變?yōu)?
LEDNum=7;
else //LEDNum未減到0,自減
LEDNum--;
P2=~(0x01<<LEDNum); //LED的第LEDNum位點(diǎn)亮
}
}
}
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
代碼解釋:
有了前三節(jié)的基礎(chǔ),這一節(jié)就比較簡單了,看注釋即可。
最終的效果是實(shí)現(xiàn)目 標(biāo)4:獨(dú)立按鍵控制LED移位
按下K1并松開時(shí),LED燈向左移一位;按下K2時(shí),LED燈向右移一位。
K1每按下一次,LED燈向左移動(dòng)一位:
K2每按下一次,LED燈向右移動(dòng)一位:
到了這里,關(guān)于51單片機(jī)(三)獨(dú)立按鍵控制LED的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!