unsigned char count //0.5ms次数标识
sbit pwm =P2^7 //PWM信号输出
sbit jan =P2^5 //角度减少按键检测IO口
unsigned char jd//角度标识
void delay(unsigned char i)//延时
{
unsigned char j,k
for(j=ij>0j--)
for(k=125k>0k--)
}
void Time0_Init() //定时器初始化
{
TMOD = 0x01 //定时器0工作在方式1
IE = 0x82
TH0 = 0xfe
TL0 = 0x33//11.0592MZ晶振,0.5ms
TR0=1//定时器开始
}
void Time0_Int() interrupt 1 //中断程序
{
TH0 = 0xfe//重新赋值
TL0 = 0x33
if(count<jd) //判断0.5ms次数是否小于角度标识
pwm=1 //确实小于,PWM输出高电平
else
pwm=0 //大于则输出低电平
count=(count+1) //0.5ms次数加1
count=count%40//次数始终保持为40 即保持周期为20ms
}
void keyscan() //按键扫描
{
if(jia==0) //角度增加按键是否按下
{
delay(10) //按下延时,消抖
if(jia==0) //确实按下
{
jd++//角度标识加1
count=0 //按键按下 则20ms周期从新开始
if(jd==6)
jd=5 //已经是180度,则保持
while(jia==0) //等待按键放开
}
}
if(jan==0)//角度减小按键是否按下
{
delay(10)
if(jan==0)
{
jd--//角度标识减1
count=0
if(jd==0)
jd=1 //已经是0度,则保持
while(jan==0)
}
}
}
void main()
{
jd=1
count=0
Time0_Init()
while(1)
{
keyscan() //按键扫描
}
}
取那么多、那么长时间的平均值干什么?连续取 20 次,其中有10 次,按的是这个键,有10 次,按的是那个键,
平均一下,判定结果:是按下了一个根本就没有按的键。
========
#include<reg52.h>
#include<intrins.h>
unsigned char code k_AD[] = {
10, 40, 70, 100, 130, 160, 190, 210, 230}//九个按键所对应的ADC值
unsigned char code duan[] = { //共阳段码
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}
//--------------------------------------------
void delay(int x)
{
int i
while(x--) for(i = 115i >0i--)
}
//--------------------------------------------
unsigned char keyscan()
{
unsigned char k1, k2
k1 = GetADCResult(0)//读出
if(k1 <238) { //按下了
delay(20)//延时
k2 = GetADCResult(0) //再次读出
if((k1 >(k2 - 5) &&(k1 <(k2 + 5)) { //两者相差无几
k1 /= 2 k2 /= 2 k1 += k2//两次的平均值
for(k2 = 0k2 <9k2++) //在表格中查找9次
if(k1 >(k_AD[k2]) - 5) &&(k1 <(k_AD[k2]) + 5)) //找到了
return(k2) //就返回键值
}
}
return(255) //没有按键
}
//--------------------------------------------
void main()
{
unsigned char key
while(1) {
key = keyscan()
if(key != 255) P0 = duan[key]//显示键值
}
}
//--------------------------------------------
本程序未经验证,仅供参考。
矩阵键盘最好在IO口跟IO口之间加一个小电阻
数码管不亮很有可能是按键检测的时候进行了延时,延时时间过长导致数码管不亮。或者存在检测按下或松手的语句,导致一直在处于检测按键的状况
矩阵键盘可以参考下面的代码
获取一次按键扫描的值 ,如果是255代表没有按键按下,否则返回按键的值。
#define KEY P3#define K1 P3_4
#define K2 P3_5
#define K3 P3_6
#define K4 P3_7
unsigned char GetKey(void)
{
KEY=0xff
K1=0
swithc(KEY&0x0f)
{
case 0x0E:return 0
case 0x0D:return 1
case 0x0B:return 2
case 0x07:return 3
}
KEY=0xff
K2=0
swithc(KEY&0x0f)
{
case 0x0E:return 4
case 0x0D:return 5
case 0x0B:return 6
case 0x07:return 7
}
KEY=0xff
K3=0
swithc(KEY&0x0f)
{
case 0x0E:return 8
case 0x0D:return 9
case 0x0B:return 10
case 0x07:return 11
}
KEY=0xff
K4=0
swithc(KEY&0x0f)
{
case 0x0E:return 12
case 0x0D:return 13
case 0x0B:return 14
case 0x07:return 15
}
return 255
}
放在整个程序的循环中 只要检测到按键做相应的动作即可。
如果要用到延时的地方
可以把显示函数当做延时函数来用,或者把显示函数放到中断里面。
这样都不会影响到正常的显示。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)