❶ 單片機中獨立鍵盤和矩陣鍵盤如何一起使用 請用C語言寫個程序說明,謝謝。
這個很好處理呀,比如以下舉例,獨立+矩陣,實現獨立按鍵相當於類似SHIFT作用的效果。
#include<reg51.h>
#define uchar unsigned char
uchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0到f
uchar keyval,num;
sbit skey=P1^0; //獨立鍵P1.0
void delay(uchar a)
{
uchar i,j;
for(i=0;i<a;i++)
for(j=0;j<125;j++);
}
uchar kbscan(void) //矩陣鍵掃描程序
{
unsigned char sccode,recode;
P3=0x0f; //發0掃描,列線輸入
if ((P3 & 0x0f) != 0x0f) //有鍵按下
{
delay(20); //延時去抖動
if ((P3&0x0f)!= 0x0f)
{
sccode = 0xef; //逐行掃描初值
while((sccode&0x01)!=0)
{
P3=sccode;
if((P3&0x0f)!=0x0f)
{
recode=(P3&0x0f)|0xf0;
while((P3&0x0f)!=0x0f);//等待鍵抬起
return((~sccode)+(~recode));
}
else
sccode=(sccode<<1)|0x01;
}
}
}
return 0; //無鍵按下,返回0
}
void getkey(void)
{
unsigned char key;
key=kbscan();
if(key==0)
{
return;
}
switch(key)
{
case 0x11:keyval=7;break;
case 0x12:keyval=4;break;
case 0x14:keyval=1;break;
case 0x18:keyval=10;break;
case 0x21:keyval=8;break;
case 0x22:keyval=5;break;
case 0x24:keyval=2;break;
case 0x28:keyval=0;break;
case 0x41:keyval=9;break;
case 0x42:keyval=6;break;
case 0x44:keyval=3;break;
case 0x48:keyval=11;break;
case 0x81:keyval=12;break;
case 0x82:keyval=13;break;
case 0x84:keyval=14;break;
case 0x88:keyval=15;break;
default:keyval=0xff;break;
}
//以下處理獨立按鍵
if(skey==0)
{
if(keyval!=0xff)keyval+=16; //如果獨立鍵按下,鍵值加16
while(skey==0); //等待獨立鍵釋放
}
}
void t0isr() interrupt 1
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
switch(num)
{
case 0:P2=0x01;break;
case 1:P2=0x02;break;
case 2:P2=0x04;break;
case 3:P2=0x08;break;
default:break;
}
if(keyval<16) P0=~tab[keyval]; //獨立鍵未按正常顯示
else P0=~(tab[keyval]|0x80); //獨立鍵按下顯示+DP
num++;
num&=0x03;
}
main()
{
TMOD=0x01;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
TR0=1;
ET0=1;
EA=1;
while(1)
{
getkey();
}
}
❷ 單片機按鍵有幾種方式_單片機按鍵連接方法
單片機按鍵連接方法總結(五種按鍵擴展方案詳細介紹)
單片機在各種領域運用相當廣泛,而作為人機交流的按鍵設計也有很多種。不同的設計方法,有著不同的優缺點。而又由於單片機I/O資源有限,如何用最少的I/O口擴展更多的按鍵是我所研究的問題。接下來我給大家展示幾種自己覺得比較好的按鍵擴展方案,大家可以在以後的單片機電路設計中靈活運用。
1)、第一種是最為常見的,也就是一個I/O口對應一個按鈕開關。
這種方案是一對一的,一個I/O口對應一個按鍵。這里P00到P04,都外接了一個上拉電阻,在沒有開關按下的時候,是高電平,一旦有按鍵按下,就被拉成低電平。這種方案優點是電路簡單可靠,程序設計也很簡單。缺點是佔用I/O資源多。如果單片機資源夠多,不緊缺,推薦使用這種方案攜啟。
2)、第二種方案也比較常見,但是比第一種的資源利用率要高,硬體電路也不復雜。
這是一種矩陣式鍵盤,用8個I/O控制了16個按鈕開關,優點顯而易見。當然這種電路的程序設計相對也還是很簡單的。由P00到P03循環輸出低電平,然後檢測P04到P07的狀態。比方說這里P00到P03口輸出1000,然後檢測P04到P07,如果P04為1則說明按下的鍵為s1,如果P05為1則說明按下的是s2等等。為了電路的可靠,也可以和第一種方案一樣加上上拉電阻。
3)、第三種是我自己搞的一種方案,可以使用4個I/O控制8個按鍵,電路多了一些二極體,稍微復雜了一點。
這個電路的原理很簡單,就是利用二極體的單向導電性。也是和上面的方案一樣,程序需要採用輪訓的方法。比方說,先置P00到P03都為低電平,然後把P00置為高電平,接著查詢P02和P03的狀態,如果P02為高則說明按下的是s5,若P03為高則說明按下的是s6,然後再讓P00為低,P01為高,同樣檢測P02和P03的狀態。接下來分別讓P02和P03為高,其他為低,分別檢測P00和P01的狀態,然後再做判斷。這種方案的程序其實也不難。
4)這是我在一本書上看到的,感覺設計的非常巧妙,同樣它也用到了二極體,不過比我的上一種方案的I/O利用率更高,他用4個I/O口控制了12個按盯正鍵。我相信你了解了之後也會驚奇的。
首先好好品味一下這個方案吧,想想怎麼來識別按鍵呢!
首先,我們讓P00到P03全輸出高電平。如果這個時候從P00到P03的任意一個埠檢測到低電平,很容易知道是按下了那個鍵,肯定是s13到s16的其中一個。如果沒有檢測到信號,就進行下一次的檢測,讓P01到P03為高電平,P00為低電平,然後檢測P01到P03的狀態。如凱隱悔果P01為低,則按下的是s1,;P02為低,則按下的是s2;P03為低,則按下的是s3。
然後再讓P00,P02,P03為高電平,P01為低電平。同理用上面的方法可以檢測出按下的那個按鍵。(部分程序源代碼會在後面貼出來,閱讀代碼可以更好理解電路)
5)、接下來這種方案則更為強大。不過需要用到一個A/D轉換器(有的單片機集成有A/D轉換器,則更為方便)。如果A/D轉化器的解析度為n位,理論上是可以擴展2^n(2的n次方)個按鍵。
這是一種接AD轉化器的方案,有兩種:第一種是並聯式;第二種是串聯式。在功能上也有些不同。第一種的話各個電阻值各不相同,當按下不同按鍵時,進入AD的模擬量是不一樣的,通過AD轉換,就可以得到按下的是哪個按鍵。方式一還可以同時識別多個按鍵,即可以設置組合鍵,只要電阻取得合適。
方式二各個電阻可以取一樣的,方便計算,但是不能有組合按鍵。因為當按下上面的按鍵後,下面所有按鍵都會被短路。(在實際運用中,還需要接地,這里沒有畫出) 。前面說理論上可以擴展2^n個按鍵,這只是理論,因為這里電阻的精度有限,所以實際是不可能的,兩個模擬量之間要有足夠大的差值,程序才可能准確的分辨。
上面就是我介紹的五種按鍵擴展方案,後面幾種比較另類,不過也有他們的優點。以上電路我都模擬過,可以實現。
附方案4鍵盤掃描源代碼:
sbit line_1=P0.1;
sbit line_2=P0.2;
sbit line_3=P0.3;
sbit line_4=P0.4
char key=0;
void key_scan()
{
line_1=line_2=line_3=line_4=1;
if(~(line_1&&line_2&&line_3&&line_4)) {
if(line_1==0) {key=13;return;} if(line_2==0) {key=14; return;} if(line_3==0) {key=15;return;} if(line_4==0) {key=16; return;} }
line_2=line_3=line_4=1;
line_1=0;
if(~(line_2&&line_3&&line_4)) {
delay();
if(line_2==0) {key=1;return;} if(line_3==0) {key=2;return;} if(line_4==0) {key=3;return;} }
line_1=line_3=line_4=1;
line_2=0;
if(~(line_1&&line_3&&line_4)) {
delay();
if(line_3==0) {key=5;return;} if(line_4==0) {key=6;return;} }
line_1=line_2=line_4=1;
line_3=0;
if(~(line_2&&line_1&&line_4)) {
delay();
if(line_4==0) {key=9;return;} }
line_4=0;
line_1=line_2=line_3=1;
if(~(line_2&&line_3&&line_1)) {
delay();
if(line_1==0) {key=10;return;} if(line_2==0) {key=11;return;} if(line_3==0) {key=12;return;} }
line_3=0;
line_1=line_2=line_4=1;
if(~(line_2&&line_3&&line_4)) {
delay();
if(line_1==0) {key=7;return; } if(line_2==0) {key=8;return; } }
line_2=0;
line_1=line_3=line_4=1;
if(~(line_2&&line_3&&line_4)) {
delay();
if(line_1==0) {key=4;return; } }
return;
}
❸ 如何用單片機模擬鍵盤控制電腦
介面協議原理
PS/2鍵盤介面採用一種雙向同步串列協議。即每在時鍾線上發一個脈沖,就在數據線上發送一位數據。在相互傳輸中,主機擁有匯流排控制權,即它可以在任何時候抑制鍵盤的發送。方法是把時鍾線一直拉低,鍵盤就不能產生時鍾信號和發送數據。在兩個方向的傳輸中,時鍾信號都是由鍵盤產生,即主機不產生通信時鍾信號。
如果主機要發送數據,它必須控制鍵盤產生時鍾信號。方法如下:主機首先下拉時鍾線至少100μs抑制通信,然後再下拉數據線,最後釋放時鍾線。通過這一時序控制鍵盤產生時鍾信號。當鍵盤檢測到這個時序狀態,會在10ms內產生時鍾信號。如圖3中 A 時序段。主機和鍵盤之間,傳輸數據幀的時序如圖2、圖3所示。2.2 數據包結構在主機程序中,利用每個數據位的時鍾脈沖觸發中斷,在中斷常式中實現數據位的判斷和接收。在實驗過程中,通過合適的編程,能夠正確控制並接收鍵盤數據。但該方案有一點不足,由於每個CLOCK都要產生一次中斷,中斷頻繁,需要耗用大量的主機資源。
/*-----------------------------------------------
ps2滑鼠的基本原理應用
說明:此程序使用標准PS2鍵盤輸入。此樣例僅作測試使用
晶振使用12M或者11.0592M,本鍵盤使用部分字母和數字測試,其他按鍵不能使用,用
戶可以自行擴展。由於開發板和程序的各種參數,程序中沒有使用奇偶校驗,不保證沒有
誤碼,校驗程序請自行添加。
-------------------------------------------------*/
#include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
sbit Key_Data = P3^3 ; //定義Keyboard引腳
sbit Key_CLK = P3^2; //使用中斷
bit BF=0;
bit Shift; //定義上檔鍵標志
bit Key_UP; //定義通碼斷碼標志
unsigned char KeyV;
unsigned char IntNum;
unsigned char DisNum;
/*-----------------------------------------------
外部中斷讀入信息
-----------------------------------------------*/
void Keyboard_out(void) interrupt 0
{
if ((IntNum > 0) && (IntNum < 9))
{
KeyV = KeyV >> 1; //因鍵盤數據是低>>高,結合上一句所以右移一位
if (Key_Data)
KeyV = KeyV | 0x80; //當鍵盤數據線為1時到最高位
}
IntNum++;
while (!Key_CLK); //等待PS/2CLK拉高
if (IntNum > 10)
{
IntNum = 0; //當中斷11次後表示一幀數據收完,清變數准備下一次接收
BF = 1; //標識有字元輸入完了
EA = 0; //關中斷等顯示完後再開中斷
}
}
/*-----------------------------------------------
解碼信息
注意:如SHIFT+G為12H 34H F0H 34H F0H 12H
也就是說shift的通碼+G的通碼+shift的斷碼+G的斷碼
-----------------------------------------------*/
void Decode(unsigned char ScanCode) //
{
unsigned char TempCyc,Val;
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(!Shift) //如果SHIFT沒按下
{
for (TempCyc = 0;(UnShifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表顯示
if (UnShifted[TempCyc][0] == ScanCode)
{
Val= UnShifted[TempCyc][1];
LCD_Write_Char(DisNum%16,DisNum/16,Val);
DisNum++;
if(DisNum==33)
{
LCD_Clear(); //清屏
DisNum=0; //重頭寫數據
}
}
}
else //按下SHIFT
{
for(TempCyc = 0; (Shifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表顯示
if (Shifted[TempCyc][0] == ScanCode)
{
Val= Shifted[TempCyc][1];
LCD_Write_Char(DisNum%16,DisNum/16,Val);
DisNum++;
if(DisNum==33)
{
LCD_Clear(); //清屏
DisNum=0; //重頭寫數據
}
}
}
break;
}
}
else
{
Key_UP = 0;
switch (ScanCode) //當鍵松開時不處理判碼,如G 34H F0H 34H 那麼第二個34H不會被處理
{
case 0x12 : // 左 SHIFT
Shift = 0;
break;
case 0x59 : // 右 SHIFT
Shift = 0;
break;
}
}
BF = 0; //標識字元處理完了
}
/*-----------------------------------------------
ps2初始化(實際初始化外部中斷)
-----------------------------------------------*/
void PS2_Init(void)
{
IT1 = 0; //設外部中斷1為低電平觸發
EA = 1; //外部中斷開
EX0 = 1; //開中斷
}
/*-----------------------------------------------
讀取鍵盤值
-----------------------------------------------*/
void Read_KeyBoard(void)
{
if (BF)
Decode(KeyV);
else
EA = 1; //開中斷
}
❹ 單片機應用中,獨立式按鍵操作的流程是什麼
一種是普通io口,一種是中彈的形式,普通io口是按下按鍵觸發按鍵子程序案件,指程序經過一段時間的,比如20~50毫秒的延時再次毒案件,如果按鍵值還是會按下,那麼就延時等待按鍵抬起按鍵,抬起後執行按鍵程序,然後返回中彈也是一樣的,按下按鍵之後進入中段讀按鍵狀態,是否還是為按一下是按一下等待延時再讀等待,然後等待案件採取後執行相應的代碼,然後退出總代。
❺ 單片機怎麼控制電腦鍵盤輸入
進入軟體,最基礎的創建工程我就不說了,直接到按鍵程序,寫程序,首先要了解按鍵,對於按鍵,分為獨立式和矩陣式按鍵。
先說說獨立式按鍵,這個十分簡單,特點是每個按鍵佔用一條I/O線,當按鍵數量較多時,I/O口利用率不高,但程序編制簡單。所以,如果按鍵就那麼兩三個的話用起來還是占優勢的哦。這樣的開關程序就是一個檢測過程,看I/O埠是否低電平,如果是則有按鍵按下,否則就沒有。如下是獨立式按鍵的接法。
步驟閱讀
3
復雜的是矩陣式按鍵,但是他也有很大的優勢,電路連接復雜,但提高了I/O口利用率,軟體編程較復雜。要是你的東西有很多的按鍵要操作,那麼採用這種方式的優勢就十分明顯了。如下圖就是矩陣式按鍵,矩陣式按鍵的程序較獨立式按鍵復雜的多,方法也很多,基本的有線翻轉法,掃描法,計演算法,因為程序很復雜的原因,在這里就不一一講解了,有興趣的自己可以查查資料。
❻ 單片機應用系統的鍵盤處理程序主要包括哪幾部分內容
輸出,輸入,復位。
1、單片系統的鍵盤程序包括輸出,由鍵盤進行敲擊字母輸出。
2、輸入是通過打完的字通過顯示器進行輸入。
3、復位是將錯誤的地方進行刪除復位。
❼ 單片機的按鍵功能是什麼
你們知道單片機的每個按鍵的具體功能嗎?下面是我收集整理關於單片機的每個按鍵的具體功能的資料以供大家參考學習,希望大家喜歡。·
鍵盤的分類:
鍵盤分編碼鍵盤和非編碼鍵盤。
鍵盤上閉合鍵的識別由專用的硬體編碼器實現,並產生鍵編碼號或鍵值的稱為編碼鍵盤,如計算機鍵盤;
而靠軟體編程來識別的稱為非編碼鍵盤。
在單片機組成的各種系統中,用的最多的是非編碼鍵盤。也有用到編碼鍵盤的。
非編碼鍵盤有分為:獨立鍵盤和行列式(又稱為矩陣式)鍵盤。
本文主要討論矩陣鍵盤(獨立鍵盤比較簡單可以與此類比),下面是矩陣鍵盤的電路連接圖。
如果單片機檢測到的是抖動部分,則無法按鍵判斷是否有效,所以我們需要加入防抖程序。
註:也可以通過硬體防抖,如上圖(b)。
功能:矩陣鍵盤
(按相應的按鍵,數碼管從0~F的顯示)
單片機:AT89S52
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit DAT=P0^3;
sbit CLK=P0^2;
uchar temp,h;
void delay(uint); //延遲程序
void sendbyte(uchar); //數碼管顯示
void keyscan(); //按鍵掃描
uchar code tab[]={
0xed,0x09,0xbc,0x9d,0x59,0xd5,
0xf5,0x0d,0xfd,0xdd,0x7d,0xf1,
0xe4,0xb9,0xf4,0x74,0x00} ; //0-F, 全滅
void main (void)
{
sendbyte(16); //初始時數碼管無顯示
while(1)
{
keyscan(); //按鍵掃描
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--);
}
void sendbyte(uchar byte)
{
uchar num,c;
num=tab[byte];
for(c=0;c<8;c++)
{
CLK=0;
DAT=num&0x01;
CLK=1;
num>>=1; //右移位賦值
}
}
void keyscan()
{
/*第一行按鍵的掃描*/
P2=0xfe; //確定第一行的按鍵有效
temp=P2; //將其賦給一個變數(處理I/O口時,一般先賦值給一個變數,然後通過處理變數來處理I/O口)
temp=temp&0xf0; //用於檢測第一行的哪個按鍵按下
while(temp!=0xf0) /*這個部分只要是用來消除按下抖動的*/
{
delay(5);
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0) //這個地方,已經消除了按下抖動,P2口的值已經確定
{
temp=P2; //將P2口得值賦給變數
switch(temp) //這個switch語句,用來確定哪一個按鍵按下時,數碼管的顯示值
{
case 0x7e:h=0;
break; //這個break很重要,表示如果有匹配的值,就跳出switch語句,防止程序跳不出來。
case 0xbe:h=1;
break;
case 0xde:h=2;
break;
case 0xee:h=3;
break;
default : h=16;
break;
}
while(temp!=0xf0) /*這個部分只要是用來消除釋放抖動的*/
{
temp=P2;
temp=temp&0xf0;
}
sendbyte(h); //送給數碼管顯示
}
}
/*第二行按鍵的掃描*/
P2=0xfd;
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case 0x7d:h=4;
break;
case 0xbd:h=5;
break;
case 0xdd:h=6;
break;
case 0xed:h=7;
break;
default : h=16;
break;
}
while(temp!=0xf0)
{
temp=P2;
temp=temp&0xf0;
}
sendbyte(h);
}
}
/*第三行按鍵的掃描*/
P2=0xfb;
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case 0x7b:h=8;
break;
case 0xbb:h=9;
break;
case 0xdb:h=10;
break;
case 0xeb:h=11;
break;
default : h=16;
break;
}
while(temp!=0xf0)
{
temp=P2;
temp=temp&0xf0;
}
sendbyte(h);
}
}
/*第四行按鍵的掃描*/
P2=0xf7;
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P2;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case 0x77:h=12;
break;
case 0xb7:h=13;
break;
case 0xd7:h=14;
break;
case 0xe7:h=15;
break;
default : h=16;
break;
}
while(temp!=0xf0)
{
temp=P2;
temp=temp&0xf0;
}
sendbyte(h);
}
}
❽ 單片機的鍵盤介面連接分為哪幾類說明各自的工作原理。鍵盤消抖是什麼有哪幾種方法
一般而言,單片機與鍵盤介面有3種方式:1、靜態介面方式;2、動態矩陣掃描方式;3、採用鍵盤管理晶元方式;第一種方式最簡單,主要用於按鍵不多的情況,每個按鍵佔用一條口線,第二種方式多用於按鍵較多的情況,比如用一個8位口就可以實現4x4鍵盤掃描,這種方式的優點是節省口線,缺點是佔用了較多的MCU資源,第三種方式是把管理鍵盤的任務交給了專用晶元,效率較高適用於按鍵多MCU處理任務重的應用場合。
鍵盤消抖顧名思義就是要消除鍵盤按下或抬起瞬間由於觸點抖動引起的不確定狀態,主要有軟體和硬體消抖兩種方法,軟體消抖就是監測到有鍵按下時並不立即響應,而是延時一段時間後再次判鍵把不確定狀態躲過去,硬體消抖是通過RS觸發器或施密特觸發器將鍵盤與單片機介面隔離,使得單片機讀取的是經過硬體濾波後的確定狀態。