中易网

单片机习题,按下矩阵按钮后,在2个数码管上显示按键值0到15。

答案:2  悬赏:40  
解决时间 2021-01-17 00:21
单片机习题,按下矩阵按钮后,在2个数码管上显示按键值0到15。
最佳答案
#include

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}
};

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 (backup[i][j] != KeySta[i][j]) //检测按键动作
{
if (backup[i][j] != 0) //按键按下时执行动作
{
P0 = LedChar[i*4+j]; //将编号显示到数码管
}
backup[i][j] = KeySta[i][j]; //更新前一次的备份值
}
}
}
}
}

void InterruptTimer0() interrupt 1
{
unsigned char i;
static unsigned char keyout = 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[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;
//消抖后更新按键状态
for (i=0; i<4; i++) //每行4个按键,所以循环4次
{
if ((keybuf[keyout][i] & 0x0F) == 0x00)
{ //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下
KeySta[keyout][i] = 0;
}
else if ((keybuf[keyout][i] & 0x0F) == 0x0F)
{ //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起
KeySta[keyout][i] = 1;
}
}
//执行下一次的扫描输出
keyout++; //输出索引递增
keyout = keyout & 0x03; //索引值加到4即归零
switch (keyout) //根据索引,释放当前输出引脚,拉低下次的输出引脚
{
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;
}
}

这里的ADDR 和ENLED 是控制的数码管的位选和段选,,,,因为是用到了38译码器, 你这里可以根据自己电路的连接方式自己更改下,,,数码管的扫描显示方式 是一样的
全部回答
你好!是c语言还是汇编写程序呢
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
沧月都写过哪些小说按时间顺序是怎么排的
由于零线氧化,对整个回路来讲有什么影响?
Ubuntu的lunix下如何判断Vim是否已经安装?
埃菲尔铁塔是现代巴黎的标志,建于1889年,是
欠私人钱还不上怎么办
金豆幼儿园(贺州平桂)怎么去啊,我要去那办事
斐讯k2t路由器怎么恢
求新堂L的漫画《变身》汉化版,如果有他的其
其拉作战坦克
人品应该像梅花那样什么?
条纹领结不能送人吗?
歌曲《天之涯》的歌词
单宁、单宁酸是不是同一种物质?
前后标识都是B的越野车是奔驰吗?
第三方出具的生产许可证明 中的第三方指的是
推荐资讯
离娘衣谁买是我买还是男朋友,我是六安霍邱的
宁波传成酒械具体位置在哪里?
俏字是几声
8x8x8x8x8x8的积的末位上的数字是多少?
北京火车站到838路总站坐几路公交车
GTA5生命条,旁边的蓝色、黄色是什么?
薛之谦对粉丝说我好像在哪见过你,粉丝蒙了
乡村公路预算怎么算
简便运算 0.7777×0.7+0.1111×2.1
QQ附近人显示0.19km实际距离有多远
半坡文化的出土文物
8除以25=25分之8=75分之么等于什么
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?