27,28兩個按鍵用于控制時間的暫停和重新計數
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei截圖20210105155944.jpg (119.48 KB, 下載次數: 76)
下載附件
2021-1-5 16:00 上傳
單片機源程序如下:
- #include <reg51.h>
- #include <absacc.h>
- #include <intrins.h>
- #define BIT0 0x01
- #define BIT1 0x02
- #define BIT2 0x04
- #define BIT3 0x08
- #define BIT4 0x10
- #define BIT5 0x20
- #define BIT6 0x40
- #define BIT7 0x80
- #define KeyInPort XBYTE[0xE800]
- #define KeyOutPort XBYTE[0xEC00]
- typedef unsigned int u16; //對數據類型進行聲明定義
- typedef unsigned char u8;
- u16 Timer0_flag = 0;
- u16 time100ms_cnt = 0;//100ms計數變量
-
- u8 xdata smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,//0x00全滅
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71, 0x00};//顯示0~F的值,18不顯示
- u8 xdata smgduan_num[] = { 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0xff};//0xff選中所有數碼管
-
- u8 code KeyOutTAB[] = {
- 0xFF, // 湊數的
- ~BIT0,
- ~BIT1,
- ~BIT2,
- ~BIT3,
- ~BIT4,
- ~BIT5,
- ~BIT6,
- ~BIT7,
- };
- u8 code conKeyFunCode[] = {
- 3, // 湊數
- 0x81,// 0
- 0x22,// 1
- 0x42,// 2
- 0x82,// 3
- 0x83,// 4
- 0x43,// 5
- 0x23,// 6
- 0x84,// 7
- 0x44,// 8
- 0x24,// 9
- 0x14,// A
- 0x13,// B
- 0x12,// C
- 0x11,// D
- 0x21,// E
- 0x41,// F
- 0x00,// 空鍵 16
- 0x85,// 17
- 0x45,// 18
- 0x25,// 19
- 0x15,// 20
- 0x86,// 21
- 0x46,// 22
- 0x26,// 23
- 0x16,// 24
- 0x0C,// 25
- 0x0B,// 26
- 0x0A,// 27
- 0x09,// 28
- };
- u16 smgduan_addr = 0XE3FF; //E3FF是PS0的地址,段碼的8位數據
- u16 smgduan_num_addr = 0XE7FF; //E7FF是PS1的地址,選擇那一個數碼管亮
- u16 key_out_addr = 0XEFFF; //EFFF是PS3的地址,矩陣按鍵輸出地址
- u16 key_in_addr = 0XEBFF; //EBFF是PS2的地址,矩陣按鍵讀地址
- u8 Key_Flag = 0;
- u8 Sys_Key = 0; // 鍵值存放在這里
- u8 duanma_mode = 0;
- u8 preKey = 0;
- u8 curKey = 0;
- u8 SameKeyNum = 0;
- bit Flag_1ms = 0;
- unsigned char Cnt_1ms = 0;
- bit Flag_10ms = 0;
- unsigned char Cnt_10ms = 0;
- bit Flag_100ms = 0;
- unsigned char Cnt_100ms = 0;
- bit Flag_1s = 0;
- unsigned char Cnt_1s = 0;
-
- void Fun_KeyScan( void ){
-
- unsigned char Temp = 0;
- unsigned char LineNum = 0;
-
- // 1、獲取鍵值
- for( LineNum = 6; LineNum > 0; LineNum-- ){
- KeyOutPort = KeyOutTAB[LineNum]; // 輸出
- Temp = KeyInPort; // 讀取
- Temp = ~Temp; // 取反,有按下的是低電平
- Temp &= 0x1F; // 屏蔽,0001 1111
- if( Temp ){ // 如果有鍵按下
- break; // 則跳出循環
- } // 否則繼續掃描
- }
-
- // 2、拼合鍵值
- Temp <<= 3;//左移3位
- Temp |= LineNum;//6 = 110B
-
- // 3、獲取功能碼
- for( LineNum = 29; LineNum > 0; LineNum-- ){//一共30個數,但是第一個數是無效數,從29掃描到1
- if( Temp == conKeyFunCode[ LineNum ] ){
- break;
- }
- }
-
- if( LineNum > 0 ){ LineNum--; }
-
- // 4、數字濾波
- curKey = LineNum;
- if( curKey != preKey ){//判斷下一次掃描的是不是還是上一個按鍵
- preKey = curKey;
- SameKeyNum = 0;
- }
- else{
- SameKeyNum++;
- if( SameKeyNum == 30 ){ Key_Flag = 1; Sys_Key = curKey; }
- if( SameKeyNum == 80 ){ Key_Flag = 1; Sys_Key = curKey; }
- if( SameKeyNum >= 100 ){ Key_Flag = 1; Sys_Key = curKey; SameKeyNum = 80; }
- }
-
- }
- bit key28_down = 0;
- bit key28_up = 0;
- bit key27_down = 0;
- bit key27_up = 0;
- bit time_start = 1;
- void InitTimer0(void)
- {
- TMOD = 0x01;
- TH0 = 0x0FC;
- TL0 = 0x18;
- EA = 1;
- ET0 = 1;
- TR0 = 1;
- }
- void delay1ms(void) //誤差 0us
- {
- unsigned char a,b,c;
- for(c=1;c>0;c--)
- for(b=142;b>0;b--)
- for(a=2;a>0;a--);
- }
- void main(void)
- {
- InitTimer0();
- while(1)
- {
- Fun_KeyScan();
- if (Sys_Key == 28)//當28號鍵按下去然后在松開,key28_up == 1
- {
- key28_down = 1;
- }
- if(key28_down == 1 && Sys_Key == 16)
- {
- key28_down = 0;
- key28_up = 1;
- }
- if(key28_up == 1)
- {
- key28_up = 0;
- time_start = ~time_start;
- }
-
- if (Sys_Key == 27)//當27號鍵按下去然后在松開,key27_up == 1
- {
- key27_down = 1;
- }
- if(key27_down == 1 && Sys_Key == 16)
- {
- key27_down = 0;
- key27_up = 1;
- }
- if((key27_up == 1) && (time_start == 0))
- {
- key27_up = 0;
- duanma_mode++;
- // if(duanma_mode >= 3)
- // {
- // duanma_mode = 0;
- // }
- }
-
- if(duanma_mode == 1)
- {
- time100ms_cnt = 0;
- }
- if(duanma_mode == 2)
- {
- duanma_mode = 0;
- time_start = 1;
- }
- XBYTE[smgduan_num_addr] = smgduan_num[1];
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
51.zip
(69.18 KB, 下載次數: 19)
2021-1-5 16:00 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|