51单片机 矩阵按键的扫描、消抖、动作分离
2014-10-15 13:19
218 查看
#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; code unsigned char 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} }; void main() { unsigned char i, j; unsigned char backup[4][4] = { //按键值备份,保存前一次的值 {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1} }; EA = 1; //使能总中断 ENLED = 0; //选择数码管DS1进行显示 ADDR3 = 1; ADDR2 = 0; ADDR1 = 0; ADDR0 = 0; TMOD = 0x01; //设置T0为模式1 TH0 = 0xFC; //为T0赋初值0xFC67,定时1ms TL0 = 0x67; ET0 = 1; //使能T0中断 TR0 = 1; //启动T0 P0 = LedChar[0]; //默认显示0 while (1) { for (i=0; i<4; i++) { //循环检测4*4的矩阵按键 for (j=0; j<4; j++) { if (KeySta[i][j] != backup[i][j]) { //检测按键动作 if (KeySta[i][j] == 0) { //按键按下时执行动作 P0 = LedChar[i*4 + j]; //将编号显示到数码管 } backup[i][j] = KeySta[i][j]; //更新前一次的备份值 } } } } } /* T0中断服务函数,扫描矩阵按键状态并消抖 */ void InterruptTimer0() interrupt 1 { unsigned char j; static unsigned char i = 0; //矩阵按键扫描输出索引 static unsigned char keybuf[4][4] = { //矩阵按键扫描缓冲区 {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF} }; TH0 = 0xFC; //重新加载初值 TL0 = 0x67; //将一行的4个按键值移入缓冲区 keybuf[i][0] = (keybuf[i][0] << 1) | KEY_IN_1; keybuf[i][1] = (keybuf[i][1] << 1) | KEY_IN_2; keybuf[i][2] = (keybuf[i][2] << 1) | KEY_IN_3; keybuf[i][3] = (keybuf[i][3] << 1) | KEY_IN_4; //消抖后更新按键状态 for (j = 0; j < 4; j++) { //每行4个按键,所以循环4次 if ((keybuf[i][j] & 0x0F) == 0x00) { //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下 KeySta[i][j] = 0; } else if ((keybuf[i][j] & 0x0F) == 0x0F) { //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起 KeySta[i][j] = 1; } } //执行下一次的扫描输出 switch (i) { //根据索引,释放当前输出引脚,拉低下次的输出引脚 case 0: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break; case 1: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break; case 2: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break; case 3: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break; default: break; } i = ++i & 0x03; }
相关文章推荐
- 蓝桥杯——矩阵按键行列扫描
- 8.7 单片机矩阵按键的扫描
- 关于独立按键与矩阵按键的程序(51单片机)
- 51单片机按键扫描C程序
- 51单片机的4x4矩阵键盘扫描例程(C51)
- 4*4矩阵按键扫描程序
- 51单片机:独立按键与矩阵按键控制数码管
- 用扫描法读出4×4矩阵键盘,在数码管显示按键值
- 矩阵按键扫描函数---线路不管怎样接,此函数可适用,可做底层函数
- 矩阵按键扫描
- 51单片机矩阵扫描键盘程序(源代码)
- 51单片机开发系列五_矩阵按键扫描
- 多功能检测按键-3 按键扫描 单按 长按 多个按键 响应方式
- 一个51单片机的键盘扫描程序,算法简单有效
- 新型的按键扫描程序
- 独立按键扫描程序的思考(整合两种算法)
- 4*4矩阵按键控制数码管显示0-F
- stm32的按键扫描[操作寄存器+库函数]
- STM32F103的4*4矩阵按键,调试通过
- 线段树+扫描线求矩阵面积并