|
完成數(shù)碼管顯示,按鍵相加的要求
此程序的電路圖下載:http://www.zg4o1577.cn/f/ks51.pdf 只需要看數(shù)碼管部分即可,其他部分可忽略掉.
代碼如下:
- #include<reg52.h>
- sbit ADDR0 = P1^0;
- sbit ADDR1 = P1^1;
- sbit ADDR2 = P1^2;
- sbit ADDR3 = P1^3;
- sbit ENLED = P1^4;
- sbit KEY_IN_1 = P2^4;
- sbit KEY_IN_2 = P2^5;
- sbit KEY_IN_3 = P2^6;
- sbit KEY_IN_4 = P2^7;
- sbit KEY_OUT_1 = P2^3;
- sbit KEY_OUT_2 = P2^2;
- sbit KEY_OUT_3 = P2^1;
- sbit KEY_OUT_4 = P2^0;
- unsigned char code LedChar[]={
- 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
- 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
- };
- unsigned char KeySta[4][4] = {
- {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
- };
- unsigned char LedBuff[6] = {
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
- };
- unsigned char code KeyCodeMap[4][4] = { //矩陣按鍵編號到標準鍵盤鍵碼的映射表
- { 0x31, 0x32, 0x33, 0x26 }, //數(shù)字鍵1、數(shù)字鍵2、數(shù)字鍵3、向上鍵
- { 0x34, 0x35, 0x36, 0x25 }, //數(shù)字鍵4、數(shù)字鍵5、數(shù)字鍵6、向左鍵
- { 0x37, 0x38, 0x39, 0x28 }, //數(shù)字鍵7、數(shù)字鍵8、數(shù)字鍵9、向下鍵
- { 0x30, 0x1B, 0x0D, 0x27 } //數(shù)字鍵0、ESC鍵、 回車鍵、 向右鍵
- };
- void KeyDriver();
- void main()
- {
- EA = 1; //使能總中斷
- ENLED = 0; //選擇數(shù)碼管進行顯示
- ADDR3 = 1;
- TMOD = 0x01; //設置T0為模式1
- TH0 = 0xFC; //為T0賦初值0xFC67,定時1ms
- TL0 = 0x67;
- ET0 = 1; //使能T0中斷
- TR0 = 1; //啟動T0
- LedBuff[0] = LedChar[0]; //上電顯示0
-
- while (1)
- {
- KeyDriver(); //調(diào)用按鍵驅(qū)動函數(shù)
- }
- }
- void ShowNumber(unsigned long num)
- {
- signed char i;
- unsigned char buf[6];
- for(i=0; i<6; i++)
- {
- buf[i] = num % 10;
- num = num / 10;
- }
- for(i=5; i>=1; i--) \\gaoweibuxianshi
- {
- if(buf[i] == 0)
- {
- LedBuff[i] = 0xFF;
- }
- else
- break;
- }
-
- for(; i>=0; i--) \\
- {
- LedBuff[i] = LedChar[buf[i]];
- }
- }
- void KeyAction(unsigned char keycode)
- {
- static unsigned long result = 0;
- static unsigned long addend = 0;
-
- if((keycode >= 0x30) &&(keycode <= 0x39))
- {
- addend = (addend *10) + (keycode - 0x30);
- ShowNumber(addend);
- }
-
- else if(keycode == 0x26)
- {
- result += addend;
- addend = 0;
- ShowNumber(result);
- }
- else if(keycode == 0x0D)
- {
- result += addend;
- addend = 0;
- ShowNumber(result);
- }
- else if(keycode == 0x1B)
- {
- addend = 0;
- result = 0;
- ShowNumber(addend);
- }
-
- }
- void KeyDriver()
- {
- unsigned char i, j;
- static unsigned char backup [4][4] = {
- {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
- };
- for(i=0; i<4; i++)
- {
- for(j=0; j<4; j++)
- {
- if(backup[i][j] != KeySta[i][j])
- {
- if(backup[i][j] == 0)
- {
- KeyAction(KeyCodeMap[i][j]);
- }
- backup[i][j] = KeySta[i][j];
- }
- }
- }
-
- }
- /* 按鍵掃描函數(shù),需在定時中斷中調(diào)用,推薦調(diào)用間隔1ms */
- void KeyScan()
- {
- unsigned char i;
- static unsigned char keyout = 0; //矩陣按鍵掃描輸出索引
- static unsigned char keybuf[4][4] = { //矩陣按鍵掃描緩沖區(qū)
- {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},
- {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}
- };
- //將一行的4個按鍵值移入緩沖區(qū)
- keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
- keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
- keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
- keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;
- //消抖后更新按鍵狀態(tài)
- for (i=0; i<4; i++) //每行4個按鍵,所以循環(huán)4次
- {
- if ((keybuf[keyout][i] & 0x0F) == 0x00)
- { //連續(xù)4次掃描值為0,即4*4ms內(nèi)都是按下狀態(tài)時,可認為按鍵已穩(wěn)定的按下
- KeySta[keyout][i] = 0;
- }
- else if ((keybuf[keyout][i] & 0x0F) == 0x0F)
- { //連續(xù)4次掃描值為1,即4*4ms內(nèi)都是彈起狀態(tài)時,可認為按鍵已穩(wěn)定的彈起
- KeySta[keyout][i] = 1;
- }
- }
- //執(zhí)行下一次的掃描輸出
- keyout++; //輸出索引遞增
- keyout = keyout & 0x03; //索引值加到4即歸零
- switch (keyout) //根據(jù)索引,釋放當前輸出引腳,拉低下次的輸出引腳
- {
- case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
- case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
- case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
- case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
- default: break;
- }
- }
- /* 數(shù)碼管動態(tài)掃描刷新函數(shù),需在定時中斷中調(diào)用 */
- void LedScan()
- {
- static unsigned char i = 0; //動態(tài)掃描的索引
- P0 = 0xFF; //顯示消隱
- switch (i)
- {
- case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
- case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
- case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
- case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
- case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
- case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
- default: break;
- }
- }
- /* T0中斷服務函數(shù),用于數(shù)碼管顯示掃描與按鍵掃描 */
- void InterruptTimer0() interrupt 1
- {
- TH0 = 0xFC;
- TL0 = 0x67;
- LedScan();
- KeyScan();
- }
復制代碼 |
|