机顶盒常用74HC164、74HC595、TM1637等芯片实现数码管驱动和按键检测功能,通过动态扫描和分时复用技术,利用人眼视觉暂留效应,让同一组I/O口既控制数码管显示,又实现按键检测,有效的节省I/O端口。
分时复用原理:将按键并联接到数码管的A-H端,最多可以连接8个按键,由单片机一个IO口检测按键状态。在数码管完成一个扫描周期后,关闭数码管位码,将按键码输出,此时数码管段选端和按键都接收到这个数据,但由于数码管位码关闭,数码管并无显示,未受到干扰。
按键码为低电平有效,当有按键被按下,单片机检测端会接收到低电平,若在传送0xfe时接收到低电平,则判断为K1被按下,数码管会显示相应的键值“01”,其它按键同理。
本案例只是显示01-06键值,若需要实现其它的功能,可在此程序的基础上自行修改。
参考程序:
/*******************************************
74HC164驱动4位数码管及解析按键码
*******************************************/
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code SEG[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数码管0~9共阳代码
uchar code COM[]={0x01,0x02,0x04,0x08}; //数码管位码
uchar code KEY[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //按键码
uchar buff[4]; //显示缓存
uchar keynum; //按键消抖计时及按键键值
sbit DIO = P2^0; //HC164数据
sbit CLK = P2^1; //HC164时钟
sbit Key_data = P2^2; //按键检测位
/**********************************************
延时函数 x*1ms
**********************************************/
void delay(uint xms)
{
uchar i;
while(--xms)
{
i=166;
while(--i);
}
}
/**********************************************
74HC164写入数据函数
**********************************************/
void Wr_hc164(uchar dat)
{
uchar i;
for(i=0; i<8; i++)
{
dat<<=1;
DIO = CY;
CLK = 0;
CLK = 1;
}
}
/*********************************************
显示函数
*********************************************/
void display()
{
uchar i;
buff[0]=0xc6;
buff[1]=0x89;
buff[2]=SEG[keynum/10];
buff[3]=SEG[keynum%10];
for(i=0;i<4;i++)
{
Wr_hc164(buff); //传送段码
P3 = COM; //传送位码
delay(3);
P3 = 0x00; //消隐
}
}
/**********************************************
按键扫描函数
**********************************************/
void keyscan()
{
uchar i;
for(i=0;i<6;i++) //循环6个按键
{
Wr_hc164(KEY); //传送按键码
if(Key_data==0)
{
keynum=i+1; //键值
} //若要使按键具有加、减功能,需加入松手检测
}
}
/**********************************************
主程序
**********************************************/
void main()
{
while(1)
{
display();
keyscan(); //4个数码管完成1个扫描周期共12ms,正好作为按键的延时消抖
}
}
仿真程序下载:
分时复用仿真(proteus8.17以上版本).zip
(21.9 KB, 下载次数: 0)
|