做RCT时钟的时候涉及到时间设置的问题,然后发现如果按一次加一次不好,因为你要从30分加到59分就要按30次,所以就想着长按连加的办法我针对的是仿真图写的图的连接如下图不同连接方法可能需要稍微修改下按键值得计算方式。 这里认为设定了1 2 键有连加功能 3 4 键无连加功能做对比
针对上图给出如下示例代码,写的不好的还 望各路大神指点
#include "reg51.h"
#define uint unsigned int
#define uchar unsigned char
#define key_port P1 //矩阵键盘使用的IO口
uchar code yang[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共阳极数码管编码
/////函数申明///
void delay_ms(uint ms);
uchar key_4X4_scan();//4*4矩阵键盘
/////////////////////////
void main()
{
uchar key,k=0;
P2=yang[0];
while(1)
{
if(key=key_4X4_scan())
{
if(key==1) //如果是1键数码管值从k开始自增有连加功能
{
k++;
k&=0x0f; //不大于15
P2=yang[k];
}
else if(key==2) //如果是2数码管值从k自减 有连加功能
{
k--;
k&=0x0f; //不大于15
P2=yang[k];
}
else if(key==3) //如果是3键数码管值从k开始自增无连加 对比
{
k++;
k&=0x0f; //不大于15
P2=yang[k];
}
else if(key==4) //如果是4数码管值从k自减 无连加 对比
{
k--;
k&=0x0f; //不大于15
P2=yang[k];
}
}
delay_ms(10);
}
}
void delay_ms(uint ms)
{
uint i,j;
for(i=ms;i>0;i--)//当晶振为11.0592M的时候计数112大概用时是1ms
for(j=112;j>0;j--);
}
uchar key_4X4_scan()
{
static uchar press_flag=1,key; //松键标志位
static uint i,j;
key_port=0xf0; //一半高一半低判断是否有键按下
if(key_port!=0xf0) //如果不等于说明有键按下
{
if(press_flag) //如果已经松开过按键则扫描否则当做没有按键处理
{ //如果不做松键判断处理 如果是按下键数码管值加1的情况下按一下数码管会加好几次
delay_ms(10); //去抖
if(key_port==0xf0)return 0;//再判断误判则返回无按键按下
press_flag=0; //松键标志位清0在松键之前这个值都将是0
j=0;
for(i=1;i<5;i++)
{
key_port=~(0x01<<i-1); //进行列试探 1到4列进行试探
switch(key_port&0xf0) //判断是哪一行 清除列的影响
{
case 0xe0: return key= 4*0+i; break; //i指的是当前在第i列 e=1110 指的是第一行 则计算当前按键值下同
case 0xd0: return key= 4*1+i; break; //这里的计算方式要根据矩阵键盘连接方法来计算
case 0xb0: return key= 4*2+i; break;
case 0x70: return key= 4*3+i; break;
}
}
}
else
{
j++;
if(j>=150)//长按超过1.5S 扫描一次10ms 150就是1.5s 看调用的间隔时间来设置此值
{
j=500; //防止加到溢出
i++; //设置连加的间隔时间
if(i==10)//100ms的速度返回上一次的按键值 按调用次函数的时间来设置
{
i=0;
if(key==1||key==2) //这里可以设置希望哪几个按键有连加功能,如果希望所有按键都有则可以不要这句这里设置只有1和2键有这功能
return key;//key静态变量记录了上一次的按键值
}
}
}
}
else press_flag=1; //按键松开后按键标志位重新置1允许下次按键
return 0; //无键按下
}
#include "reg51.h" #define uint unsigned int #define uchar unsigned char #define key_port P1 //矩阵键盘使用的IO口 uchar code yang[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共阳极数码管编码 /////函数申明/// void delay_ms(uint ms); uchar key_4X4_scan();//4*4矩阵键盘 ///////////////////////// void main() { uchar key,k=0; P2=yang[0]; while(1) { if(key=key_4X4_scan()) { if(key==1) //如果是1键数码管值从k开始自增有连加功能 { k++; k&=0x0f; //不大于15 P2=yang[k]; } else if(key==2) //如果是2数码管值从k自减 有连加功能 { k--; k&=0x0f; //不大于15 P2=yang[k]; } else if(key==3) //如果是1键数码管值从k开始自增无连加 对比 { k++; k&=0x0f; //不大于15 P2=yang[k]; } else if(key==4) //如果是2数码管值从k自减 无连加 对比 { k--; k&=0x0f; //不大于15 P2=yang[k]; } } delay_ms(10); } } void delay_ms(uint ms) { uint i,j; for(i=ms;i>0;i--)//当晶振为11.0592M的时候计数112大概用时是1ms for(j=112;j>0;j--); } uchar key_4X4_scan() { static uchar press_flag=1,key; //松键标志位 static uint i,j; key_port=0xf0; //一半高一半低判断是否有键按下 if(key_port!=0xf0) //如果不等于说明有键按下 { if(press_flag) //如果已经松开过按键则扫描否则当做没有按键处理 { //如果不做松键判断处理 如果是按下键数码管值加1的情况下按一下数码管会加好几次 delay_ms(10); //去抖 if(key_port==0xf0)return 0;//再判断误判则返回无按键按下 press_flag=0; //松键标志位清0在松键之前这个值都将是0 j=0; for(i=1;i<5;i++) { key_port=~(0x01<<i-1); //进行列试探 1到4列进行试探 switch(key_port&0xf0) //判断是哪一行 清除列的影响 { case 0xe0: return key= 4*0+i; break; //i指的是当前在第i列 e=1110 指的是第一行 则计算当前按键值下同 case 0xd0: return key= 4*1+i; break; //这里的计算方式要根据矩阵键盘连接方法来计算 case 0xb0: return key= 4*2+i; break; case 0x70: return key= 4*3+i; break; } } } else { j++; if(j>=150)//长按超过1.5S 扫描一次10ms 150就是1.5s 看调用的间隔时间来设置此值 { j=500; //防止加到溢出 i++; //设置连加的间隔时间 if(i==10)//100ms的速度返回上一次的按键值 按调用次函数的时间来设置 { i=0; if(key==1||key==2) //这里可以设置希望哪几个按键有连加功能,如果希望所有按键都有则可以不要这句这里设置只有1和2键有这功能 return key;//key静态变量记录了上一次的按键值 } } } } else press_flag=1; //按键松开后按键标志位重新置1允许下次按键 return 0; //无键按下 }