本筆記默認學習者已擁有:
1.Keil5和stc燒寫工具 等各種軟件、驅動、環境;
2.有一個屬於自己的 51單片機開發板及相關零件 ;
3.認識C語言的語法;
本人使用的51開發板為 郭天祥C51 TX-1C增強版開發板 ;
本筆記根據B站up主:江科大自化協的教學視頻 整理得到ヾ(•ω•)
3-1 獨立按鍵控制LED亮滅
原理分析
上圖為TX-1C的 獨立按鍵及矩陣按鍵 原理圖 ,注意到寄存器位置與視頻 有所不同
1.GND為接地線,可以視為電源的負極;
2.獨立按鍵一頭 接地 ,另一頭接到了 IO口上,單片機通電時,所有IO口默認都是高電平;
3.所以當沒有按下 獨立按鍵時,IO口為高電平,按下 獨立按鍵時,IO口為低電平;
上一節,我們介紹了寄存器,介紹了寄存器可以賦值給IO口。
4.寄存器可以檢測IO口的電平,讀回到寄存器中,
如果 按鍵 松開,直接讀取寄存器,它應該為 1(高電平的狀態);如果按下 按鍵,那它的值應該為 0(低電平狀態);
通過此現象,可以檢測按鍵是否被按下;
實踐代碼
上一節 學習了 直接給整個P2寄存器賦值,來達到讓LED亮滅的效果,但如果只控制獨立的單個位,而不影響其他位呢?
1.打開頭文件 #include<reg51.h>
,其中sfr
是用來定義 整個8位寄存器 的;
2.其中 sbit
是用來定義 位寄存器 的,操作這些變量,就可以單獨操作每一位;
獨立按鍵控制LED亮滅.c
#include<reg51.h>
sbit led1=P1^0;
//sfr P1=0x90; 但#include<reg51.h>中並未定義其 位寄存器
//這里選擇 自主定義
void main(){
while(1){
//根據#include<reg51.h>的定義,s2按鍵對應的端口為P3^4,即為 T0
if(T0==0) led1=0;
else led1=1;
}
}
運行結果如下:
3-2 獨立按鍵控制LED狀態
消抖的兩種方法:
(1)硬件消抖:增加電路,通過電路中的觸發器等 電路操作,將抖動進行過濾,此方法比較麻煩,且需要硬件支持;
(2)軟件消抖:檢測按鍵是否按下時,前后各延時20ms,抖動時間就過去了;
如下是完整的 檢測按鍵是否按下 的代碼
if(T0==0){
Delayms(20);
while(T0==0);//檢測松手,只要不松手,就一直保持循環
Delayms(20);
//do sth.
}
獨立開關控制LED狀態.c
#include<reg51.h>
#define uint unsigned int
sbit led1=P1^0;
void Delayms(uint x) //@11.0592MHz
{
unsigned char i, j;
while(x--){
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main(){
while(1){
Delayms(20);
if(T0==0){
Delayms(20);
while(T0==0);
Delayms(20);
led1=~led1;
}
Delayms(20);
}
}
運行結果如下:
3-3 獨立按鍵控制LED顯示二進制.c
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
void Delayms(uint x) //@11.0592MHz
{
unsigned char i, j;
while(x--){
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main(){
uchar LEDnum=0;
//uchar 剛好表示 0~255,符合 8位寄存器的大小
while(1)
if(T0==0){
Delayms(20);
while(T0==0);
Delayms(20);
//P1口上電默認給高電平,即P1= 1111 1111
//直接讓P1 +1 ,則P1=0000 0000
//不符合預期,故使用 變量 LEDnum 來表示 寄存器
++LEDnum;
P1=LEDnum;
}
}
運行結果如下:
3-4 獨立按鍵控制LED移位.c
此代碼寫法與視頻不同
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
void Delayms(uint x) //@11.0592MHz
{
unsigned char i, j;
while(x--){
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main(){
uchar LEDnum=0;
while(1){
if(T0==0){
Delayms(20);
while(T0==0);
Delayms(20);
LEDnum<<=1;
if(LEDnum==0) LEDnum=1;
P1=~LEDnum;
}
if(T1==0){
Delayms(20);
while(T1==0);
Delayms(20);
LEDnum>>=1;
if(LEDnum==0) LEDnum=0x80;
P1=~LEDnum;
}
}
}
運行結果如下:
相關知識
此為 復位按鍵,按下 復位按鍵,相當於 電源重新打開,單片機程序會從頭開始。