按鍵在未按下時,處於一種高電平狀態,一般這種情況下,其對io口的電平一致,則不會產生任何效果,只有在按下狀態時,由於與接地的迴路貫通,故相當於微控制器的io口直接接地。從原理圖上看,之所以要接keyin1-keyin4外接至按鍵中,主要原因是為了獲取按鍵的狀態,因為我們只能獲取微控制器的io口狀態,而不能直接獲取按鍵本身是否按下的狀態,所以只能通過這個電路,通過io口接地的情況,人為造成io為低電平,從而判斷按鍵被按下,如果我們不細緻地把這個原因考慮清楚,而僅僅只是按這種電路圖直接連線的話,勢必是知其然而不知其所以然。
現在我們有16個按鍵,通過四個out和四個in進行組合,但我們需要明白乙個問題,out的主要目標是為了產生低電平,從而才能夠使按鍵按下後,對地電路導通。那麼,如何進行控制out的電平呢?如果預設情況下全部為低電平可不可以?答案是不可以的,因為假定其全部為底電平,此時比如我如果按下key1,key5,那麼都會導致keyin1為低電平,那麼我們如何判定是按了key1還是key5呢?所以不能將其全部設定為低電平,更何況如果全部是低電平,還何必要它們從微控制器的io引出來呢,直接接地就可以了。這裡其實還是利用了與點陣led與數碼管一樣的原理,就是掃瞄的方式。逐個令keyout1-keyout4迴圈為低,則此時對應的那一排key值如有按下,則對應的keyin起作用,而如果不在同一排則按鍵不起作用。
下面是我實現的乙個在最右邊的那個數碼管顯示按鍵值的示例**,其值從0到f進行顯示。
#include
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
//數碼管的顯示數字,從0至f一共16個字元
code uint8number=;
code uint8 keys =;
uint8 k=0;
uint8 counter=0;
sbit enled = p1^4;
sbit addr0 = p1^0;
sbit addr1 = p1^1;
sbit addr2 = p1^2;
sbit addr3 = p1^3;
sbit keyout1 = p2^3;
sbit keyout2 = p2^2;
sbit keyout3 = p2^1;
sbit keyout4 = p2^0;
//初始化計數器1
void init_timer1()
tmod|= 0x10;
tmod&= 0xdf;
th1 = 0xfc;
tl1 = 0x67;
tr1 = 1;
//初始化中斷響應
void init_interrupt()
et1= 1;
ea = 1;
void refresh_keyout()
static uint8 j = 0;
switch(j)
case0: keyout1=0;keyout2=1;keyout3=1;keyout4=1;break;
case1: keyout2=0;keyout1=1;keyout3=1;keyout4=1;break;
case2: keyout3=0;keyout1=1;keyout2=1;keyout4=1;break;
case3: keyout4=0;keyout1=1;keyout2=1;keyout3=1;break;
default:break;
if(3 == j++) j = 0;
uint8 temp=0;
uint8 j=0;
uint8 i=0;
main()
enled= 0; addr3 = 1;
init_timer1();
init_interrupt();
addr0=0;
addr1=0;
addr2=0;
while(1)
temp= p2;
i=0;
for(;i<16;i++)
if(temp== keys[i])
j=i;
break;
p0=number[j];
void interrupt_timer1() interrupt 3
th1 = 0xfc;
tl1 = 0x67;
if(10==counter++)
//切換keyout的輸出,如果太快,則很難把握使用者到底按下了
//哪個按,只能在一段延時的情況下,進行判斷使用者按下了哪個鍵
counter=0;
refresh_keyout();
p2 7 6 5 4 3 2 1 0
in4 in3 in2 in1 out1 out2 out3 out4
k1 1 1 1 0 0 1 1 1 =0xe7=0
k2 1 1 0 1 0 1 1 1 =0xd7=1
k3 1 0 1 1 0 1 1 1 =0xb7=2
k4 0 1 1 1 0 1 1 1 =0x77=3
k5 1 1 1 0 1 0 1 1 =0xeb=4
k6 1 1 0 1 1 0 1 1 =0xdb=5
k7 1 0 1 1 1 0 1 1 =0xbb=6
k8 0 1 1 1 1 0 1 1 =0x7b=7
k9 1 1 1 0 1 1 0 1 =0xed=8
k10 1 1 0 1 1 1 0 1 =0xdd=9
k11 1 0 1 1 1 1 0 1 =0xbd=a
k12 0 1 1 1 1 1 0 1 =0x7d=b
k13 1 1 1 0 1 1 1 0 =0xee=c
k14 1 1 0 1 1 1 1 0 =0xde=d
k15 1 0 1 1 1 1 1 0 =0xbe=e
k16 0 1 1 1 1 1 1 0 =0x7e=f
第十課 邊框
無邊框 border style none 虛線邊框 border style dotted 虛線邊框 border style dashed 實線邊框 border style solid 雙邊框 border style double 凹槽邊框 border style groove 壟狀邊框 ...
第十課 函式
第十課 函式 一.定義函式 def 函式名 引數1,引數2,文件描述 函式體return 值 def 定義函式的關鍵字 函式名 函式名指向函式記憶體位址,是對函式體 的引用。函式的命名應該反映出函式的功能 括號 括號內定義引數,引數是可有可無的,且無需指定引數的型別 冒號 括號後要加冒號,然後在下一...
NeHe第十課學習筆記
1 fgets string,255,f 一次讀1行 從檔案流f中讀取最多255個字元到字串空間string中 2 sscanf oneline,numpollies d num s 從oneline字串中檢索出格式為numpollies d的整數,比如從numpollies 36中檢索 出36到n...