完整的电路仿真图:
两个数码管,一个4*4的矩阵键盘,还有一个排阻,由于其中一个数码管接的是P0端口,需要接上拉电阻,用排阻更加方便,所以就用了这个,如果觉得不错的话可以点赞收藏!
#include <reg51.h>
#define KEY_PORT P2 //定义P2端口
#define DIG_PORT_1 P0 //定义P0端口,作为个位数显示
#define DIG_PORT_2 P1 //定义P1端口,作为十位数显示
#define u8 unsigned charu8 code gDuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管的段码值void KeyValueDisplay(u8 val); //进行函数声明
void Delay10ms(void);
u8 KeyScan(void);/**************************************
*函数名:Delay
*函数功能:延时函数
*函数参数: 无
*函数返回值:无*************************************/
void Delay()
{unsigned char t,j;for(t=20;t>0;t--)for(j=2;j>0;j--);
}/**************************************
*函数名:KeyScan
*函数功能:矩阵键盘扫描
*函数参数: 无
*函数返回值:val*************************************/
u8 KeyScan(void){u8 val = 0;KEY_PORT = 0x0f; //设置P2口的低四位为高电平if(KEY_PORT!=0x0f){ //如果发现P2口的电平有变化,则进行下一步Delay(); //加延时函数,确认按键有被按下if(KEY_PORT != 0x0f){ //证明按键被按下switch(KEY_PORT){ //确认哪一列 case 0x07:val = 1;break;case 0x0b:val = 2;break;case 0x0d:val = 3;break;case 0x0e:val = 4;break;default: break;}KEY_PORT = 0xf0;switch(KEY_PORT){ //确认哪一行case 0x70:val = val+0;break;case 0xb0:val = val+4 ;break;case 0xd0:val = val+8;break;case 0xe0:val = val+12;break;default:break;}return val; //返回计算好的值}}return 0;
}
/**************************************
*函数名:KeyValueDisplay
*函数功能:数码管显示val的值
*函数参数: val
*函数返回值:无*************************************/void KeyValueDisplay(u8 val){if(val<10){ //判断返回值,小于10,只显示个位数DIG_PORT_1 = gDuanMa[val%10];DIG_PORT_2 = 0x00;Delay();DIG_PORT_1 = 0x00;//消隐DIG_PORT_2 = 0x00;}else{ //如果val值大于10,则P0口显示个位,P1口显示十位数DIG_PORT_1 = gDuanMa[val%10]; DIG_PORT_2 = gDuanMa[val/10];Delay();DIG_PORT_1 = 0x00;DIG_PORT_2 = 0x00;}}
/***********************************************
*函数名:main
*函数功能:主程序
*函数参数:无
*函数返回值:无
************************************************/
void main(void){u8 key = 0;u8 key1=0;while(1){key = KeyScan();//矩阵键盘扫描函数if(key!=0){key1 = key;}KeyValueDisplay(key1); //数码管显示函数}
}
效果展示: