這是讀取鍵盤的子程序
主要內容為:如何定義位,如何得到按鍵狀態(tài),防止鍵盤干擾的方法
以及如何處理讀入的鍵值
思路:首先在某一引腳輸出一個電平,然后讀入引腳的電平,如果剛好相反
那么可能有按鍵發(fā)生,但是不排除干擾,為了防止干擾,需要軟件延時20ms
消除干擾,然后,等待用戶釋放,否則,可能重復的到某種結果,發(fā)生意外情況
應該說鍵盤輸入是單片機外部指令輸入的重要途徑,因此如何設計鍵盤以及鍵盤的工作原理、讀鍵盤的方法、鍵盤的抗干擾設計等在單電能機系統(tǒng)設計中占有重要地位。這個例子在系統(tǒng)硬件的基礎上設計了軟件查詢程序、軟件延時程序(防止干擾),大致講述了一種查詢式鍵盤的工作原理與讀取方式。
**************************************************
led1 bit p1.0 ;LED 顯示位定義
led2 bit p1.1
led3 bit p1.2
led4 bit p1.3
led5 bit p1.4
led6 bit p1.5
led7 bit p1.6
led8 bit p1.7
s1 bit p0.0 ;數(shù)碼管位定義
s2 bit p0.1
s3 bit p0.2
s4 bit p0.3
s5 bit p0.4
s6 bit p0.5
s7 bit p0.6
s8 bit p0.7
led_data equ p2 ;數(shù)碼管顯示數(shù)據(jù)定義
key1 bit p3.5 ;按鍵引腳定義
key2 bit p3.6 ;
key3 bit p3.7 ;
key equ 46h ;按鍵寄存單元
org 00h
jmp main
org 030h
main:mov sp,#30h ;首先定義
lcall REST;初始化子程序
lp:lcall pro_key ;調用鍵盤查詢子程序
lcall KEYPR ;用來顯示所查詢到的鍵值
jmp lp;反復調用,不斷查詢
REST:
mov a,#00h
mov b,#00h
mov p0,#0
mov p1,0ffh ;
mov p2,#0
mov key,#00h
mov p2,#255
clr beep
RET
KEYPR:
mov a,key ;鍵值在累加器KEY中
jz PROEND ;如果 A= 0,表示沒有按鍵,返回
cjne a,#1,k1;A= 1 ,用戶按了第一個鍵
mov a,#1 ;處理 A = 1的情況
mov dptr,#tab_nu ;查表
movc a,@a+dptr
mov led_data,a ;顯示 “1”
setb s1 ;在第一位
clr s2;其余兩位不顯示
clr s3
jmp PROEND;處理完成,子程序返回
;以下分別處理KEY = 2,3 的情況
k1:cjne a,#2,k2
mov a,#2
mov dptr,#tab_nu
movc a,@a+dptr
mov led_data,a
clr s1
setb s2
clr s3
jmp PROEND
k2:cjne a,#3, PROEND
mov a,#3
mov dptr,#tab_nu
movc a,@a+dptr
mov led_data,a
clr s1
clr s2
setb s3
PROEND:ret
**** 本內容跟帖回復才可瀏覽 *****
;************ 定時20 ms *************
delay20ms: push psw ;保存原來的寄存器單元
clr psw.3;設置新的寄存器
clr psw.4;
mov r0,#2;延時參數(shù)1
mov r1,#250;延時參數(shù)2
mov r2,#2;延時參數(shù)3
dl1:djnz r0,dl1 ;延時循環(huán)1
mov r0,#250 ;重新設置循環(huán)數(shù)據(jù)
dl2:djnz r1,dl1 ;開始第二道循環(huán)
mov r0,#240;
mov r1,#248;
dl3:djnz r2,dl1;第三道循環(huán)
nop;修正定時精度
pop psw ;恢復原來的寄存器組
ret ;返回
;*********** end *******************
;這是數(shù)字顯示表格,其中 帶小數(shù)點的數(shù)字比不帶小數(shù)點的數(shù)字大16
; 比如 0 的顯示代碼為 0;那么 0.的顯示代碼為 16;如此類推
tab_nu:
db 0c0h, 0f9h, 0a4h, 0b0h, 99h , 92h , 82h, 0f8h ;數(shù)字0-7 不帶小數(shù)點代碼
db 80h , 90h, 88h , 83h , 0c6h, 0a1h, 86h, 8eh ;數(shù)字8-f 不帶小數(shù)點代碼
db 40h , 79h, 24h , 30h , 19h , 12h , 02h, 78h ;數(shù)字0-7 帶小數(shù)點代碼
db 00h , 10h, 08h , 03h , 46h , 21h , 06h, 0eh ;數(shù)字8-f 帶小數(shù)點代碼
end;告訴編譯器本程序到此結束,一定需要加上,否則編譯通不過。
;c語言
**************************************************
//按不同的按鍵,會顯示不同的結果
#include 《8051.h》
#define uchar unsigned char
#define key1 P3_4 //鍵盤定義
#define key2 P3_5
#define key3 P3_6
//****************************************************************************
void delay(uchar times);
void display(uchar disseg,uchar disdata);
uchar keyb();
// 這里定義的是數(shù)碼管對應的字符字根
code uchar disbuf_u[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
// ***************************************************************************
uchar keybuf;
void main()
{
uchar keym = 0; //鍵盤返回結果的緩沖區(qū)
keybuf = 0;
P1 = 255; //關閉LED顯示
P0 = 0; //關閉數(shù)碼顯示
P2 = 255; //
while(1) //設置一個無限制循環(huán)
{
keym = keyb(); //得到按鍵結果
if(keym) keybuf = keym; //如果返回有效的按鍵結果才保存
display(keybuf-1,keybuf); //在相應的位置顯示返回的結果
}
}
//*****************************************************************************
//下面是延時程序。具體的延時時間不能通過表面程序看出,(為什么?)
//如果我們需要一個精密的延時程序,那么我們可以采用內嵌匯編代碼的方式
void delay(uchar times)
{
int t=100; //延時倍數(shù)
uchar i=times;
for(;i!=0;i--)
{for(;t!=0;t--){}}
}
//這里是顯示子程序,入口參數(shù)為
// disseg -》 位選 可選范圍 0-7 一共8個數(shù)碼管
// disdata -》 段選 可選范圍 0-31 一個32個字符
// 段選 0-15 16個字符 為 “0”-》“F”
// 段選 16-31 16個字符 為 “0.”-》“F.”
void display(uchar disseg,uchar disdata)
{
uchar dataf;
if(disseg 《 8) //只有當要顯示的位數(shù)有效,才顯示。否則,不顯示
{
dataf = 1;
while(disseg)
{
dataf 《《= 1;
disseg--;
}
P0 = dataf;
P2 = disbuf_u[disdata];
}
else{P0=0,P2=255;} //關閉數(shù)碼管顯示
}
uchar keyb()
{
uchar key,keytmp;
key1 = 1; //將輸出線拉高
key2 = 1;
key3 = 1;
key = P3 ; //讀回來
key = key & 0xf0; //獲得鍵盤結果
if(key == 112 ) return 0; //如果用戶沒有按鍵返回 0
else
{
keytmp = key;
delay(1); //判斷是不是干擾
key = P3 & 0xf0;
if (key != keytmp ) return 0; //是干擾,返回 0
else //不是干擾,等待用戶釋放按鍵
{
do{
key1 = 1; //輸出拉高
key2 = 1;
key3 = 1;
key = P3 & 0xf0; //讀回來
P1_0 = ~P1_0; //如果用戶不釋放,閃爍 p1.0
}while(key != 112 ); //等待用戶釋放
P1_0 = 1; //用戶釋放以后,清除p1.0指示燈
switch(keytmp)
{
case 96: return 3;//返回用戶按鍵結果
case 80: return 2;
case 48: return 1;
}
}
}
}
//
-
led
+關注
關注
242文章
23277瀏覽量
660872 -
單片機
+關注
關注
6037文章
44558瀏覽量
635299 -
鍵盤
+關注
關注
4文章
859瀏覽量
39670
發(fā)布評論請先 登錄
相關推薦
評論