在CT107D单片机综合训练平台上,首先将J5处的跳帽接到1~2引脚,使按键S4~S19按键组成4X4的矩阵键盘。
需要注意的是比赛的时候用的IAP15f2k61s2单片机是没有P36和P37的,是用P44代替P37,P42代替P36,所有写程序的时候需要注意一下,大家应该对矩阵键盘的扫描原理清楚吧,这里不在对矩阵键盘的扫描原理做讲解,主要是针对一个题目做出相应程序设计。
内容设计:
1.不同按键对应不同的键值,例如S7对应数字7,S19对应数字19,在数码管后两位上显示出来;
2.数字不足两位的数码管应只显示一位,另外一个关闭。
#include<stc15f2k60s2.h>
#define uchar unsigned char //定义无符号字符类型uchar
#define uint unsigned int //定义无符号整型类型uint
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//数字0~9,“-”,“关”
uchar qi,ba; //定义字符型变量qi,ba,当作数码管显示控制变量
uchar num=0;
void delayms(int ms); //延时函数
void allinit(); //初始化函数
void keyscan16(); //矩阵按键函数
void display4(uchar qi,uchar ba); //第七、八段数码管函数
void main()//主函数
{
allinit(); //初始化函数
while(1)
{
if(num>=10){qi=num/10;ba=num%10;}//键值大于等于10,数码管分两位显示
else {qi=11;ba=num;} //键值小于10,数码管显示一位,另外一位熄灭
keyscan16(); //矩阵按键函数
display4(qi,ba); //第七、八段数码管函数
}
}
void keyscan16()//矩阵按键函数
{
uchar temp; //定义一个无符号变量temp
P44=0;P42=1;P3=0x7f; //让第一列按键为低电平
temp=P3; //把P3的值赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //判断第一列是否有按键按下
{
delayms(5); //延时5ms,用来按键消抖
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //再次判断第一列是否有按键按下
{
temp=P3; //把P3的值重新赋给temp
switch(temp)
{
case 0x7e:num=7;break; //第一列第一个按键按下
case 0x7d:num=6;break; //第一列第二个按键按下
case 0x7b:num=5;break; //第一列第三个按键按下
case 0x77:num=4;break; //第一列第四个按键按下
}
while(temp!=0x0f) //无按键按下则进入循环
{
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
}
}
}
P44=1;P42=0;P3=0xbf; //让第二列按键为低电平
temp=P3; //把P3的值赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //判断第一列是否有按键按下
{
delayms(5); //延时5ms,用来按键消抖
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //再次判断第一列是否有按键按下
{
temp=P3; //把P3的值重新赋给temp
switch(temp)
{
case 0xbe:num=11;break; //第二列第一个按键按下
case 0xbd:num=10;break; //第二列第二个按键按下
case 0xbb:num=9;break; //第二列第三个按键按下
case 0xb7:num=8;break; //第二列第四个按键按下
}
while(temp!=0x0f) //无按键按下则进入循环
{
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
}
}
}
P44=1;P42=1;P3=0xdf; //让第三列按键为低电平
temp=P3; //把P3的值赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //判断第一列是否有按键按下
{
delayms(5); //延时5ms,用来按键消抖
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //再次判断第一列是否有按键按下
{
temp=P3; //把P3的值重新赋给temp
switch(temp)
{
case 0xde:num=15;break; //第三列第一个按键按下
case 0xdd:num=14;break; //第三列第二个按键按下
case 0xdb:num=13;break; //第三列第三个按键按下
case 0xd7:num=12;break; //第三列第四个按键按下
}
while(temp!=0x0f) //无按键按下则进入循环
{
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
}
}
}
P44=1;P42=1;P3=0xef; //让第四列按键为低电平
temp=P3; //把P3的值赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //判断第一列是否有按键按下
{
delayms(5); //延时5ms,用来按键消抖
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //再次判断第一列是否有按键按下
{
temp=P3; //把P3的值重新赋给temp
switch(temp)
{
case 0xee:num=19;break; //第四列第一个按键按下
case 0xed:num=18;break; //第四列第二个按键按下
case 0xeb:num=17;break; //第四列第三个按键按下
case 0xe7:num=16;break; //第四列第四个按键按下
}
while(temp!=0x0f) //无按键按下则进入循环
{
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
}
}
}
}
void delayms(int ms)//延时函数
{
uint i,j;
for(i=ms;i>0;i--)
for(j=845;j>0;j--);
}
void allinit()//初始化函数
{
P2=0XA0;P0=0X00; //关闭蜂鸣器继电器
P2=0X80;P0=0XFF; //关闭所有LED灯
P2=0XC0;P0=0XFF; //选中所有数码管段选
P2=0XFF;P0=0XFF; //关闭所有数码管
}
void display4(uchar qi,uchar ba)//第七、八段数码管函数
{
P2=0XC0;P0=0X40; //选中第七个数码管段选
P2=0XFF;P0=tab[qi]; //让第一个数码管显示qi指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X80; //选中第八个数码管段选
P2=0XFF;P0=tab[ba]; //让第一个数码管显示ba指向的值
delayms(1); //延时1ms
}