历史上的今天
今天是:2024年11月24日(星期日)
2021年11月24日 | C51键盘检测相关问题总结
2021-11-24 来源:eefocus
附注:
原理图各接口连接关系可参考代码中的端口定义;
P0口数据锁存器为两片74HC573芯片;
1.对独立键盘的检测
/*--------------------------
功能:用数码管实现60s计时器
上电时,数码管显示00
key4控制开始/暂停计时
暂停状态下,key1进行加1操作
key2进行减1操作
key3进行清零操作
---------------------------
Author: Zhang Kaizhou
Date: 2019-5-19 19:14:20
--------------------------*/
#include #define uchar unsigned char #define uint unsigned int sbit key1 = P3^4; sbit key2 = P3^5; sbit key3 = P3^6; sbit key4 = P3^7; sbit wei_address = P2^7; sbit duan_address = P2^6; uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; // 定义一个无符号字符型数组table[],存放在单片机内部的ROM或Flash中 uchar n1 = 0, n2 = 0; void init(); void display(uchar num); void keyScan(); void delay(uchar xms); void main() { init(); while(1) { keyScan(); display(n1); } } /*初始化函数*/ void init() { TMOD = 0x01; // 定时器0,方式1 TH0 = (65536 - 45872) / 256; // 定时50ms TL0 = (65536 - 45872) % 256; EA = 1; // 开全局中断 ET0 = 1; // 开定时器0溢出中断 } /*定时器0中断服务程序*/ void T0_interrupt() interrupt 1 { TH0 = (65536 - 45872) / 256; // 定时器0重装初值 TL0 = (65536 - 45872) % 256; n2++; if(n2 == 20) // 定时到1s { n2 = 0; n1++; if(n1 == 60) { n1 = 0; } } } /*数码管显示函数*/ void display(uchar num) { uchar shi, ge; shi = num / 10; ge = num % 10; duan_address = 1; // 在数码管上显示十位的数字 P0 = table[shi]; duan_address = 0; P0 = 0xff; wei_address = 1; P0 = 0xfe; wei_address = 0; delay(5); duan_address = 1; // 在数码管上显示个位的数字 P0 = table[ge]; duan_address = 0; P0 = 0xff; wei_address = 1; P0 = 0xfd; wei_address = 0; delay(5); } /*键盘扫描函数*/ void keyScan() { if(!key1) // key1按下,加1 { delay(10); if(!key1) { n1++; if(n1 == 60) { n1 = 0; } while(!key1); } } if(!key2) // key2按下,减1 { delay(10); if(!key2) { if(!n1) { n1 = 60; } n1--; while(!key2); } } if(!key3) // key4按下,暂停或开始定时器0 { delay(10); if(!key3) { n1 = 0; while(!key3); } } if(!key4) { delay(10); if(!key4) { while(!key4); TR0 = ~TR0; } } } /*延时函数*/ void delay(uchar xms) { uchar i, j; for(i = 0; i < xms; i++) for(j = 0; j < 110; j++); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 2.对矩阵键盘进行扫描 /*------------------------ 功能:扫描4x4矩阵键盘 Author: Zhang Kaizhou Date: 2019-5-21 21:37:31 -------------------------*/ #include #define uchar unsigned char sbit wei_address = P2^7; sbit duan_address = P2^6; uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; // 定义一个无符号字符型数组table[],存放在单片机内部的ROM或Flash中 uchar buffer, key; void init_digitron(); void array_scan_oneline(uchar address); void array_scan(); void display(uchar key); void delay(uchar xms); void main() { init_digitron(); // 初始化数码管 while(1) // 循环逐行扫描按键是否按下 { array_scan(); } } /*数码管初始化函数*/ void init_digitron() { P0 = 0; // 关闭所有数码管 duan_address = 1; duan_address = 0; P0 = 0x00; // 选中所有数码管 wei_address = 1; wei_address = 0; } /*矩阵键盘扫描函数*/ void array_scan() { array_scan_oneline(0xfe); array_scan_oneline(0xfd); array_scan_oneline(0xfb); array_scan_oneline(0xf7); } /*矩阵键盘扫描一行的函数*/ void array_scan_oneline(uchar address) { P3 = address; buffer = P3; buffer = buffer & 0xf0; if(buffer != 0xf0) // 有键按下 { delay(10); // 消抖 buffer = P3; buffer = buffer & 0xf0; if(buffer != 0xf0) { buffer = P3; switch(buffer) { case 0xee: key = 0; break; case 0xde: key = 1; break; case 0xbe: key = 2; break; case 0x7e: key = 3; break; case 0xed: key = 4; break; case 0xdd: key = 5; break; case 0xbd: key = 6; break; case 0x7d: key = 7; break; case 0xeb: key = 8; break; case 0xdb: key = 9; break; case 0xbb: key = 10; break; case 0x7b: key = 11; break; case 0xe7: key = 12; break; case 0xd7: key = 13; break; case 0xb7: key = 14; break; case 0x77: key = 15; break; } while(buffer != 0xf0) // 等待按键释放 { buffer = P3; buffer = buffer & 0xf0; } display(key); } } } /*延时函数*/ void delay(uchar xms) { uchar i, j; for(i = 0; i < xms; i++) for(j = 0; j < 110; j++); } /*数码管显示函数*/ void display(uchar key) { P0 = table[key]; duan_address = 1; duan_address = 0; }
下一篇:LCD1602显示总结
史海拾趣
|
此开关电源属于复合式开关电源,采用TL431的精密基准和PC817组成反馈电路。整个工作过程:交流输入经滤波、整流后成为直流高压,再由功率开关管斩波、高频变压器降压后得到高频矩形波电压,最后经过输出整流滤波器,获得所需要的直流输出电压。此开 ...… 查看全部问答> |
|
中心议题: 如何简化[url=]开关[/url]电源设计解决方案: 性能评估电气仿真与热仿真测试原型电源设计的思路 过去15年来,开关电源的设计逐渐成为主流。现在,开关电源的设计已不再是专家的任务,任何参与系统设计的人员都能够最终设计出自己的开关 ...… 查看全部问答> |
|
在WinCE6.0操作系统上,用户如何注册自已的动态库(像XP系统上一样regsvr32.exe \\xxx\\XXX.dll )… 查看全部问答> |
|
这样的 线程A不停地malloc数据,通过PostThreadMessage()把数据块的指针发送给另外一个线程。 线程B while地GetMessage(),将数据块保存至文件,并free掉。 现在发现这样做的情况下,会发生内存泄露,后来我设置了一个变量,每次PostThreadMessa ...… 查看全部问答> |
|
模块实现了一个10位SAR核、采样选择控制、参考电压发生器和数据传输控制器。 数据传输控制器DTC可以将ADC采样结果存储在内存的任何位置。 ADC10特点: l 高于20万次/秒的转换速率; l &n ...… 查看全部问答> |




