導航:首頁 > 操作系統 > 51單片機鍵盤

51單片機鍵盤

發布時間:2022-01-26 10:51:09

1. 51單片機4*5鍵盤程序。

if( INT_0 != 0 ) //再次判斷是否有鍵按下
{
EA=0;
scan_key();
delay(50);
INT_0 =judge_hitkey();
while( INT_0 !=1); //等待按鍵釋放
EA=1;
}
在EA=0;這句前,有無加上了,重新把 INT_0 =judge_hitkey(); 再賦回來了?,,我在郭天祥的板子上調試不行; EXITE.C(93): warning C206: 'manage_key1': missing function-prototype;
這是我花兩個多小時寫得51單片機,矩陣鍵盤的顯示,希望能對你有幫助;
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
sbit la=P2^6;
sbit wela=P2^7;
void init();
void display(uchar);
uchar keyscan();
uchar temp,num; //鍵盤掃描
void delay(uint xms) //延時子函數
{
int i,j;
for(i=xms;i>0;i--) //延時xms毫秒
for(j=110;j>0;j--);
}
void main()
{
init();
while(1)
{
keyscan();//不斷掃描鍵盤;
display(num);

}
}
void init()
{
num=0xff; //控制讓程序開始時不出現亂碼;
wela=1;
P0=0xc0; //打開數碼管顯示,靜態顯示;
wela=0;

}
uchar keyscan()
{
P3=0xfe;
temp=P3;
temp=temp&0xf0;//按位與,只能用&;
if(temp!=0xf0) //在用while語句時,一定要加上去抖動,否則程序會停不下來的哦;
{ //還是統一用if語句吧,只有在去抖動才一定要用if語句;
delay(5); //至於中括弧加在那都無所謂啦;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:num=1;
break;
case 0xde:num=2;
break;
case 0xbe:num=3;
break;
case 0x7e:num=4;
break;
}
while (temp!=0xf0) //去抖動只能用while ,只有松開手才會執行下面的,才會有數碼顯;
{ ////一松開手,就相當於把P3口的電平改變了;所以去抖不能在switch前
temp=P3;
temp=temp&0xf0; //不能不要,只有松開手,才會退出這個循環;
}

}
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;//按位與,只能用&;
if(temp!=0xf0)
{
delay(5);
if(temp!=0xf0)
{
temp=P3;
// temp=temp&0xf0; //該句子一定不能要,因為下面判斷的,只是P3口的電平狀態而已;
}

switch(temp)
{ case 0xed: num=5; break;
case 0xdd: num=6; break;
case 0xbd: num=7; break;
case 0x7d: num=8; break;
}
}
while (temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}

P3=0xfb;
temp=P3;
temp=temp&0xf0;//按位與,只能用&;
if(temp!=0xf0)
{
delay(5);
if(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
if(temp!=0xf0)
{
temp=P3;
// temp=temp&0xf0;
}
switch(temp)
{ case 0xeb: num=9; break;
case 0xdb: num=10; break;
case 0xbb: num=11; break;
case 0x7b: num=12; break;
}

while (temp!=0xf0) //去抖動只能用while ,只有松開手才會執行下面的,才會有數碼顯;
{ ////一松開手,就相當於把P3口的電平改變了;所以去抖不能在switch前
temp=P3;
temp=temp&0xf0; //不能不要,只有松開手,才會退出這個循環;
}

P3=0xf7;
temp=P3;
temp=temp&0xf0;//按位與,只能用&;
if(temp!=0xf0)
{
delay(5);
if(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
if(temp!=0xf0) //該句子不能用while語句,因為如果用while語句,如果鬆手了,P3的電平就改變了,temp的值也會改變的。
//因此建議,非必要,還是用if語句;
{
temp=P3;
// temp=temp&0xf0;
}
switch(temp)
{ case 0xe7: num=13; break;
case 0xd7: num=14; break;
case 0xb7: num=15; break;
case 0x77: num=16; break;
}
while (temp!=0xf0) //去抖動只能用while ,只有松開手才會執行下面的,才會有數碼顯;
{ ////一松開手,就相當於把P3口的電平改變了;所以去抖不能在switch前
temp=P3;
temp=temp&0xf0; //不能不要,只有松開手,才會退出這個循環;
}

return num;

}
void display(uchar num)
{
P0=table[num-1];
la=1;
la=0;
}

下面的是郭天祥老師寫的
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit la=P2^6;
sbit wela=P2^7;
sbit key1=P3^4;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0};
uchar num,temp,num1;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
uchar keyscan();
void display(uchar aa);
void main()
{
num=17;
la=1;
P0=0;
la=0;
wela=1;
P0=0xc0;
wela=0;

while(1)
{
display(keyscan());
}
}
void display(uchar aa)
{
la=1;
P0=table[aa-1];
la=0;
}
uchar keyscan()
{
P3=0xfe;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:num=1;
break;
case 0xde:num=2;
break;
case 0xbe:num=3;
break;
case 0x7e:num=4;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}

P3=0xfd;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:num=5;
break;
case 0xdd:num=6;
break;
case 0xbd:num=7;
break;
case 0x7d:num=8;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}

P3=0xfb;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:num=9;
break;
case 0xdb:num=10;
break;
case 0xbb:num=11;
break;
case 0x7b:num=12;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}

P3=0xf7;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:num=13;
break;
case 0xd7:num=14;
break;
case 0xb7:num=15;
break;
case 0x77:num=16;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
}
}
return num;

}

2. 51單片機鍵盤輸入

用不著數組。

只要增加一個數字vlaue,再讓 key 從keyscan()函數中,得到0~9,

最後如下計算到vlaue中: vlaue = vlaue * 10 + key;

以後,每得到一個按鍵數值(0~9),都執行一遍上面的算式,即可。

3. 51單片機鍵盤電路的兩種方式,各自的優缺點

獨立按鍵優點:可以直接讀取,檢測佔用時間較少,不受其他因素影響
缺點:佔用IO口資源較多,每一個按鍵都獨佔一個IO口。
矩陣鍵盤優點:佔用IO口資源較少。
缺點:必須掃描檢測按鍵情況,程序復雜,佔用時間較多。

4. 51單片機按鍵

#include<reg51.h>
#define uchar unsigned char
uchar num,time,limit=2;
sbit led1=P1^0;
sbit key1=P2^0;
bit flag=0;
void t0isr() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
time++;
if(time>=60)
{
TR0=0;
time=0;
flag=1;
}
}
void t1isr() interrupt 3
{
TH1=(65536-10000)/256;
TL1=(65536-10000)%256;
num++;
if(num>limit)
{
num=0;
led1=~led1;
}
}
main()
{
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-10000)/256;
TL1=(65536-10000)%256;
ET0=1;
ET1=1;
EA=1;
while(1)
{
if(key1==0)
{
time=0;
num=0;
TR1=1;
TR0=1;
flag=0;
while(key1==0);
if(flag==1)limit++;
}
}
}

5. 利用STC89S51單片機做鍵盤。

#include "KBCODE.H"
#define LCM_RS P2_0
#define LCM_RW P2_1 //定義LCD引腳
#define LCM_E P2_2
#define LCM_Data P0
#define Busy 0x80 //用於檢測LCM狀態字中的Busy標識
#define Key_Data P3_2 //定義Keyboard引腳
#define Key_CLK P3_3
void LCMInit(void);
void DisplayOneChar(unsigned char X,unsigned char Y,unsigned char DData);
void DisplayListChar(unsigned char X,unsigned char Y,unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
void Decode(unsigned char ScanCode);
void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadStatusLCM(void);
unsigned char code cdle_net[] = {"RICHMCU PS2 TEST"};
unsigned char code email[] = {"www.RICHMCU.COM"};
unsigned char code Cls[] = {" "};
static unsigned char IntNum = 0; //中斷次數計數
static unsigned char KeyV; //鍵值
static unsigned char DisNum = 0; //顯示用指針
static unsigned char Key_UP=0, Shift = 0;//Key_UP是鍵松開標識,Shift是Shift鍵按下標識
static unsigned char BF = 0; //標識是否有字元被收到

void main(void)
{
unsigned char TempCyc;

Delay400Ms(); //啟動等待,等LCM講入工作狀態
LCMInit(); //LCM初始化

DisplayListChar(0, 0, cdle_net);
DisplayListChar(0, 1, email);
for(TempCyc=0; TempCyc<10; TempCyc++) {
Delay400Ms(); //延時
}
DisplayListChar(0, 1, Cls);

IT1 = 0; //設外部中斷1為低電平觸發
EX1 = 1; //開中斷
EA = 1;

while(1) {
if(BF)
Decode(KeyV);
else {
EA = 1; //開中斷
}
}
}

//寫數據
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //檢測忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在這後加小的延時
LCM_E = 0; //延時
LCM_E = 1;
}

//寫指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC為0時忽略忙檢測
{
if(BuysC) ReadStatusLCM(); //根據需要檢測忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;

LCM_E = 1;
}

//讀狀態
unsigned char ReadStatusLCM(void)
{
LCM_Data = 0xFF;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 1;
while(LCM_Data & Busy); //檢測忙信號

return(LCM_Data);
}

void LCMInit(void) //LCM初始化
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次顯示模式設置,不檢測忙信號
Delay5Ms();
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
Delay5Ms();

WriteCommandLCM(0x38,1); //顯示模式設置,開始要求每次檢測忙信號
WriteCommandLCM(0x08,1); //關閉顯示
WriteCommandLCM(0x01,1); //顯示清屏
WriteCommandLCM(0x06,1); // 顯示游標移動設置
WriteCommandLCM(0x0F,1); // 顯示開及游標設置
}

//按指定位置顯示一個字元
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大於15,Y不能大於1
if(Y)
X |= 0x40; //當要顯示第二行時地址碼+0x40;
X |= 0x80; //算出指令碼
WriteCommandLCM(X, 1); //發命令
WriteDataLCM(DData); //發數據
}

//按指定位置顯示一串字元
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;

ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大於15,Y不能大於1
while (DData[ListLength]>0x19) {//若到達字串尾則退出
if(X <= 0xF) {//X坐標應小於0xF
DisplayOneChar(X, Y, DData[ListLength]); //顯示單個字元
ListLength++;
X++;
}
}
}

//5ms延時
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--)
;
}

//400ms延時
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--) {
TempCycB=7269;
while(TempCycB--)
;
}
}

void Keyboard_out(void) interrupt 2
{
if((IntNum > 0) && (IntNum < 9)) {
KeyV >>= 1; //因鍵盤數據是低>>高,結合上一句所以右移一位
if(Key_Data) {
KeyV |= 0x80; //當鍵盤數據線為1時為1到最高位
}
}
IntNum++;
while(!Key_CLK); //等待PS/2CLK拉高
if(IntNum > 10) {
IntNum = 0; //當中斷10次後表示一幀數據收完,清變數准備下一次接收
BF = 1; //標識有字元輸入完了
EA = 0; //關中斷等顯示完後再開中斷
}
}
void Decode(unsigned char ScanCode) //注意:如SHIFT+G為12H 34H F0H 34H F0H 12H,也就是說shift的通碼+G的通碼+shift的斷碼+G的斷碼
{
unsigned char TempCyc;

if(!Key_UP) { //當鍵盤松開時
switch(ScanCode) {
case 0xF0 : //當收到0xF0,Key_UP置1表示斷碼開始
Key_UP = 1;
break;
case 0x12: // 左 SHIFT
Shift = 1;
break;
case 0x59: // 右 SHIFT
Shift = 1;
break;
default:
if(DisNum > 15) {
DisplayListChar(0,1,Cls); //清LCD第二行
DisNum = 0;
}
if(Shift == 1) { //如果按下SHIFT
for(TempCyc = 0;(Shifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表顯示
if(Shifted[TempCyc][0] == ScanCode) {
DisplayOneChar(DisNum,1,Shifted[TempCyc][1]);
}
DisNum++;
}
else { //沒有按下SHIFT
for(TempCyc = 0; (UnShifted[TempCyc][0]!=ScanCode)&&(TempCyc<59);TempCyc++); //查表顯示
if(UnShifted[TempCyc][0] == ScanCode) {
DisplayOneChar(DisNum,1,UnShifted[TempCyc][1]);
}
DisNum++;
}
break;
}
}
else {
Key_UP = 0;
switch(ScanCode) { //當鍵松開時不處理判碼,如G 34H F0H 34H 那麼第二個34H不會被處理
case 0x12: // 左 SHIFT
Shift = 0;
break;
case 0x59: // 右 SHIFT
Shift = 0;
break;
default:
break;
}
}
BF = 0; //標識字元處理完了
}

6. 51單片機矩陣鍵盤

第一個程序,在定時中斷函數中,延時,並不合適。

第二個程序,不穩定,還是按鍵檢測,太拖拉了。

4*4 矩陣鍵盤的檢測,不用寫這么多的程序。

我的網路空間裡面有實用的程序。

7. 51單片機最小系統如何外接鍵盤

標准鍵盤有四條線,你把數據線和時鍾線接單片機,就可以接收到鍵盤的數據了,但你要先知道標准鍵盤的數據協議,再些接收代碼,把數據顯示在LCD上。

8. 51單片機按鍵輸入怎麼寫

這個程序確實沒有對按鍵的讀取和操作,按鍵輸入要看具體硬體是怎樣連接的,不同 的接法有不同的處理方法,不管怎麼接,按鍵的輸入都是很簡單的了

9. 關於51單片機鍵盤輸入定時

給個提示,在按鍵掃描程序里,將掃描按鍵的值給一個數組table[2] 按入2個鍵 後,將table[2]的兩個元素組合成一個變數a,啟動定時器,將定時時間設為a,時間到後運行加熱器驅動程序

10. 51單片機如何與電腦鍵盤相接,USB的

我自己沒做過,但是51單片機處理USB協議太吃力了,建議你使用32位的單片機,STM32F103ZET6之類的,或者換成矩陣鍵盤,按鍵也比較多了。

以下是我在網上找的一些參考,希望能夠對你有幫助:

如果是USB介面,那麼你要懂USB協議,而且單片機的速度要足夠快,一般的51怕是做不了,得用USB晶元,比如南京沁恆的CH375,單片機做主機,USB鍵盤做從機。
USB協議是很復雜的,不是一天兩天就能搞得通的,程序也很復雜,就不附上了,如果你是初學者,那麼不建議你一開始就調試USB,你可以嘗試下圓口的PS2鍵盤,那個比較容易
用 帶 USB 介面的 51內核 單片機吧
買個讀片子機,把程序燒進去,ok
你知道USB協議有多復雜嗎?!還用51來讀?
要是說在鍵盤上接一個USB轉串口的晶元,然後用51來讀串口,這樣更可行一些

還不如老老實實用矩陣鍵盤呢
單片機最小系統板不能直接和PC機USB相連,如果是支持ISP下載的單片機,可以通過USB轉232(TTL電平),單片機的串口RXD(P3.0)接232的TXD,單片機的串口TXD(P3.1)接232的RXD。
USB轉232(TTL電平)下載器需要裝驅動程序,採用的晶元不同驅動不同,請對應安裝。
如果單片機從USB取電,板上要有電源開關。

閱讀全文

與51單片機鍵盤相關的資料

熱點內容
android如何新建activity 瀏覽:737
ntp支持的認證演算法 瀏覽:710
想做快手主播需要什麼app 瀏覽:921
阿里雲伺服器如何轉賬戶 瀏覽:901
編譯器和解釋器實現技術完全不同 瀏覽:429
虐殺原形漢化補丁怎麼解壓 瀏覽:643
文件夾驗證失敗 瀏覽:635
python是用什麼軟體編程 瀏覽:247
java並發編程教程 瀏覽:319
江鈴寶典空調壓縮機工作時間過短 瀏覽:634
自製單片機玩具車 瀏覽:901
stm32單片機模塊電源電壓 瀏覽:187
pdf層次 瀏覽:735
電腦里找不到編譯器 瀏覽:843
明茨伯格pdf 瀏覽:442
把網頁存成pdf 瀏覽:268
如何對電腦的d盤加密 瀏覽:101
刀片式伺服器怎麼連接電腦 瀏覽:82
矩陣計算java 瀏覽:235
如何把各銀行app整合 瀏覽:881