第12章 常用單片機(jī)接口程序 1 靜 態(tài) 顯 示 2 動 態(tài) 顯 示 3 獨(dú)立按鍵 4 矩陣按鍵 數(shù)碼管是常用的輸出顯示器件,按鍵是常用的信號輸入器件。
0.png (105.63 KB, 下載次數(shù): 107)
下載附件
2016-3-28 20:56 上傳
常見數(shù)碼管引腳排列如圖所示
1.png (137.42 KB, 下載次數(shù): 97)
下載附件
2016-3-28 20:56 上傳
靜態(tài)顯示電路如下圖:
2.png (301.17 KB, 下載次數(shù): 89)
下載附件
2016-3-28 20:56 上傳
① 數(shù)碼管要顯示某個數(shù)字或字符,首先根據(jù)單只數(shù)碼管引腳圖,確定需要點(diǎn)亮數(shù) 碼管的哪幾段,從而確定數(shù)碼管8個引腳電平的高低。
3.png (249.54 KB, 下載次數(shù): 95)
下載附件
2016-3-28 20:56 上傳
例12.1 74HC595移位顯示程序,上電后數(shù)碼管固定顯示123456。 #include "STC15W4K.H" | // | 注意宏定義后面沒分號 | #include "intrins.h" | // | 程序中_nop_()函數(shù)需用 |
sbit | Dat=P3^2; | // | 定義串行數(shù)據(jù)輸入端 | sbit | Clk=P3^3; | // | 定義時鐘端 | sbit | CNT=P3^4; | // | 定義控制端 |
unsigned char DispBuf[6]; unsigned char code DispTab[]={0x03,0x9f,0x25,0x0d,0x19,0x41,0x1f,0x01,0x09, 0x11,0xc1,0x63,0x85,0x61,0x71}; // 定義定形碼表 void SendData(unsigned char SDat) // 74HC595傳送一個字節(jié)的數(shù)據(jù) { // 固定代碼,直接復(fù)制使用 } void Disp() // 顯示位數(shù)在6位內(nèi)不用修改 { unsigned char c=0,i=0; CNT=0; // 為產(chǎn)生脈沖上升沿作準(zhǔn)備 for(i=0;i<6;i++) // 顯示位數(shù)需用根據(jù)硬件修改 { c=DispBuf[ i ]; // 取出待顯示字符 SendData(DispTab[c]); // 送出字形碼數(shù)據(jù) } CNT=1; // 產(chǎn)生脈沖上升沿,并行輸出數(shù)據(jù) }
void main() { unsigned long i=123456; // 123456 DispBuf[0]=i%10; // 個位 DispBuf[1]=i/10%10; // 十位 DispBuf[2]=i/100%10; // 百位 DispBuf[3]=i/1000%10; // 千位 DispBuf[4]=i/10000%10; // 萬位 DispBuf[5]=i/100000%10; // 十萬位 Disp(); for(;;) { ; // 程序停在這里 } } 2 動態(tài)顯示 這里介紹的動態(tài)顯示電路如下圖所示,看起來有點(diǎn)像靜態(tài)顯示電路,但比靜態(tài) 顯示電路占用硬件要少,比單片機(jī)直接驅(qū)動數(shù)碼管占用IO口也要少。
0.png (280.03 KB, 下載次數(shù): 103)
下載附件
2016-3-28 21:00 上傳
1.png (241.11 KB, 下載次數(shù): 95)
下載附件
2016-3-28 21:00 上傳
DAT 結(jié)合電路圖,控制某一位數(shù)碼管電源通斷的位選碼就簡單多了,如下所示。 單片機(jī)內(nèi)部數(shù)據(jù)位 595引腳 | D7 Q0 | D6 Q1 | D5 Q2 | D4 Q3 | D3 Q4 | D2 Q5 | D1 Q6 | D0 Q7 | 位碼 | 十萬位 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0xDF | 萬位 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0xBF | 千位 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0x7F | 百位 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0xFB | 十位 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0xFD | 個位 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0xFE |
例12.3 單片機(jī)上電后數(shù)碼管顯示123456 sbit | Dat=P4^2; | // | 定義串行數(shù)據(jù)輸入端 | sbit | Clk=P4^4; | // | 定義時鐘端 | sbit | CNT=P4^5; | // | 定義控制端 |
unsigned char code BitTab[]={0xFE,0xFD,0xFB,0x7F,0xBF,0xDF,}; // 位選 code unsigned char DispTab[] = {0x14,0x77,0x4c,0x45,0x27,0x85,0x84,0x57, 0x04,0x05,0x06,0xa4,0x9c,0x64,0x8c,0x8e}; // 字形碼 unsigned char DispBuf[6]; // 6字節(jié)的顯示緩沖區(qū),DispBuf[0]是最低位; void SendData(unsigned char SendDat) // 74HC595傳送一個字節(jié)的數(shù)據(jù) { ;// 同例12.1 } void timer0_init() // 定時器初始化 { // 2ms定時中斷設(shè)置 } void main() { timer0_init(); DispBuf[0]=6; DispBuf[1]=5; DispBuf[2]=4;DispBuf[3]=3; DispBuf[4]=2;DispBuf[5]=1; for(;;) { ; } }
void Timer0() interrupt 1 {
unsigned char tmp; //臨時變量
static unsigned char Count=0; //顯示程序通過它得知現(xiàn)正顯示哪個數(shù)碼管
// ***************** 重裝定時常數(shù) *************************** TH0=0xf1; TL0=0x99; // 定時時間為2ms/22.1184MHz // ******************點(diǎn)亮某位數(shù)碼管************************** CNT=0; // 為產(chǎn)生脈沖上升沿作準(zhǔn)備 SendData(BitTab[Count]); // 最先點(diǎn)亮最右邊個位 // ******************輸出待顯數(shù)據(jù)************************** tmp=DispBuf[Count]; // 根據(jù)當(dāng)前的計(jì)數(shù)值取顯示緩沖待顯示值 tmp=DispTab[tmp]; // 取字形碼 SendData(tmp) ; CNT=1; // 產(chǎn)生脈沖上升沿,并行輸出數(shù)據(jù) // ******************************************** Count++; if(Count==6) Count=0; }
3 獨(dú)立按鍵 電路如圖所示,單片機(jī)引腳作為輸入使用,軟件首先將接有按鍵的IO口置1,當(dāng)鍵 沒有被按下時,單片機(jī)引腳上為高電平,而當(dāng)鍵被按下后,引腳接地,單片機(jī)引 腳上為低電平,通過編程即可獲知是否有鍵按下及按鍵的位置。
0.png (136.63 KB, 下載次數(shù): 101)
下載附件
2016-3-28 21:04 上傳
由于機(jī)械按鍵按下和松開瞬間都會產(chǎn)生抖動,為了不讓一次按鍵動作過程中程序產(chǎn)生多 次響應(yīng)引起混亂,就需要軟件去抖動處理,它的思路是:在單片機(jī)獲得某按鍵IO口為低 的信息后,不是立即認(rèn)定該鍵被按下,而是延時一段時間,通常選擇10mS,再次檢測IO 口,如果仍為低,則說明該鍵的確被按下,這避開了按鍵的前沿抖動,而在檢測到按鍵 釋放后(該IO口為高),再延時10mS,消除釋放時的后沿抖動,然后再對鍵值進(jìn)行處 理,實(shí)際的程序中其實(shí)一般都是不需要后沿抖動處理的,在后沿抖動的過程中,程序可 能誤判為鍵按下,在鍵按下后程序會執(zhí)行前沿延時10mS,所以前沿的10mS延時也就同時 用作了后沿去抖動的10mS。主要程序代碼如下: void main() { unsigned char KValue; | // | 存放鍵值 | port_mode(); | // | 所有IO口設(shè)為準(zhǔn)雙向弱上拉方式。 | for(;;) { | | | KValue=Key(); | // | 調(diào)用鍵盤程序并獲得鍵值 | if(KValue) | // | 如果該值不等于0,表示有鍵按下 | { | | | KProce(KValue); | // | 根據(jù)鍵值執(zhí)行不同的功能 |
} } } unsigned char Key() // 獲取鍵值函數(shù) { unsigned char KValue; // 存放鍵值 unsigned char tmp; // 臨時變量 P3|=0x3c; // 0x3c=0011 1100,將P3口接鍵盤的中間四位置1 _nop_();_nop_(); KValue=P3; KValue|=0xc3; | // | // STC指令太快,加上更可靠 0xc3=1100 0011,將未接鍵的4位置1 |
if(KValue==0xff) // 中間4位均為1,無鍵按下 |
return(0); | | // 返回 | delay10ms(); KValue=P3; KValue|=0xc3; | // | // 延時10ms,去鍵抖 // 與下一行一起作最終返回鍵值。 0xc3=1100 0011,將未接鍵的4位置1,最終返回鍵值。 |
if(KValue==0xff) // 中間4位均為1,無鍵按下 |
return(0); // 返回,如尚未返回,說明一定有1或更多位被按下 for(;;) { tmp=P3; // 等待按鍵釋放 if((tmp|0xc3)==0xff) break; } return(KValue); }
4 矩陣按鍵 電路如圖所示,只要熟悉了獨(dú)立按鍵,矩陣按鍵也同樣的簡單。
1.png (173.83 KB, 下載次數(shù): 97)
下載附件
2016-3-28 21:04 上傳
主要代碼如下: sbit KeyOut1 = P2^7;sbit KeyOut2 = P2^6;sbit KeyOut3 = P2^5;sbit KeyOut4 = P2^4; sbit KeyIn1 = P2^3;sbit KeyIn2 = P2^2;sbit KeyIn3 = P2^1;sbit KeyIn4 = P2^0; unsigned char KeyScan() { unsigned char key=0xff; // 臨時變量 KeyOut1 = 1; KeyOut2 = 1; KeyOut3 = 1; KeyOut4 = 0; // 掃描第1列 if(KeyIn1 == 0) { delay10ms(); if(KeyIn1 == 0) key=0x00; } if(KeyIn2 == 0) { delay10ms(); if(KeyIn2 == 0) key=0x04; } if(KeyIn3 == 0) { delay10ms(); if(KeyIn3 == 0) key=0x08; } if(KeyIn4 == 0) { delay10ms(); if(KeyIn4 == 0) key=0x0c; } KeyOut1 = 1; KeyOut2 = 1; KeyOut3 = 0; KeyOut4 = 1; // 掃描第2列 if(KeyIn1 == 0) { delay10ms(); if(KeyIn1 == 0) key=0x01; } …… } |