|
按照马老师书上面介绍的矩阵按键,仿了一个4*2的按键。结果只有2 4 6 8 这4个按键可以。
其他1 3 5 7这4个键没有反应 。请问马老师是啥问题?
我检查了按键也都是完好的。
先把图和程序传下。麻烦马老师指教,我用的芯片是MEGA128L
//按键测试程序
#include "config.h" //此文件在项目里
#define No_key 255
#define K1_1 1
#define K1_2 2//ok
#define K2_1 3
#define K2_2 4//ok
#define K3_1 5
#define K3_2 6//ok
#define K4_1 7
#define K4_2 8//ok
//4*2 就用到PD0--PD5
#define Key_mask 0x03
unsigned char key_stime_counter=0,key_stime_ok=0;
/*端口初始化*/
void Port_Init(void)
{
//PORTA = 0xFF; //PB口配置为输出
//DDRA = 0xFF; //PB口初始值为"1"
PORTB = 0xFF; //PB口配置为输出
DDRB = 0xFF; //PB口初始值为"1"
//DDRA |= (1 << 7); //流水灯使能脚输出
//PORTA |= (1 << 7); //流水灯使能
//DDRA |= (1 << 0); //流水灯使能脚输出
//PORTA |= (1 << 0); //流水灯使能
//PORTA=0x70;
//DDRA=0xea;//pa0 IN 0b1110 1010
//DDRA &= ~(1 << PA0) & ~(1 << PA2) & ~(1 << PA3) & ~(1 << PA4) & ~(1 << PA5) & ~(1 << PA6) & ~(1 << PA7) ;//设置为输入,不上拉
//按键引脚
//PORTD |= (1 << PD0) | (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6) | (1 << PD7);//push
//DDRD |= (1 << PD2)|(1 << PD3)|(1 << PD4)|(1 << PD5)|(1 << PD6)|(1 << PD7); //out
//DDRD &= ~(1 << PD0) & ~(1 << PD1);//in
PORTD=0xff;
DDRD=0xfc;
//DDRF &= ~(1 << PF0) & ~(1 << PF2) & ~(1 << PF3) & ~(1 << PF4) & ~(1 << PF5) & ~(1 << PF6) & ~(1 << PF7) ;//
}
/*定时器0初始化*/
//64分频,即ADC时钟是250KHZ
//(255-5)*(1/250000)=250*4us=1000us=1ms
//1ms中断一次
void Timer0_Init(void) //
{
TCNT0 = 5; //给定时器赋初值
TIMSK |= ( 1<< TOIE0); //使能T0溢出中断
//SREG = 0x80; //使能全局中断
//sei();
_SEI();//使能全局中断
//TCCR0 |= (1 << CS01)|(1 << CS00);//64分频,开定时器 mega32,16set
TCCR0 |= (1 << CS02);//mega128set
}
unsigned char Read_KeyBoard(void)
{
static unsigned char key_state = 0, key_value, key_line;
unsigned char key_return = No_key,i;
switch (key_state)
{
case 0:
key_line = 0x04;//0b00000100
for (i=1; i<=4; i++) // 扫描键盘
{
PORTD = ~key_line; // 输出行线电平
PORTD = ~key_line; // 必须送2次!!!
key_value = Key_mask & PIND; // 读列电平
if (key_value == Key_mask)
key_line <<= 1; // 没有按键,继续扫描
else
{
key_state++; // 有按键,停止扫描
break; // 转消抖确认状态
}
}
break;
case 1:
if (key_value == (Key_mask & PIND)) // 再次读列电平,
{
switch (key_line | key_value) // 与状态0的相同,确认按键
{ // 键盘编码,返回编码值
case 0x06://0b00000110
key_return = K1_1;
break;
case 0x05://0b00000101
key_return = K1_2;
break;
case 0x0a://0b00001010
key_return = K2_1;
break;
case 0x09://0b00001001
key_return = K2_2;
break;
case 0x12://0b00010010
key_return = K3_1;
break;
case 0x11://0b00010001
key_return = K3_2;
break;
case 0x22://0b00100010
key_return = K4_1;
break;
case 0x21://0b00100001
key_return = K4_2;
break;
}
key_state++; // 转入等待按键释放状态
}
else
key_state--; // 两次列电平不同返回状态0,(消抖处理)
break;
case 2: // 等待按键释放状态
PORTD = 0x03; // 行线全部输出低电平0b00000011
PORTD = 0x03; // 重复送一次
if ( (Key_mask & PIND) == Key_mask)
key_state=0; // 列线全部为高电平返回状态0
break;
}
return key_return;
}
//main
void main(void)
{
unsigned int KeyCode = 0;
Port_Init(); //初始化IO
Timer0_Init(); //定时器0初始化
sys_initial(); //液晶IO初始化
lcd_initial(); //液晶初始化
Clear_LCM();//
//Display(0x91,Cursor);//
Display(0x92,WelcomeToUse); //开机界面显示欢迎使用
//WriteString(WelcomeToUse);
Display(0x8a,Electrical);//
DelayNms(1000);
Clear_LCM();//
send_command(0x80);
send_data('w'); //写data
send_data('a'); //写data
send_data('i'); //写data
send_data('t'); //写data
send_data(' '); //写data
send_data('k'); //写data
send_data('e'); //写data
send_data('y'); //写data
while(1)
{
if (key_stime_ok) // 10ms到,键处理
{
key_stime_ok = 0;
KeyCode = Read_KeyBoard();//调用按键扫描程序 10ms一次
}
if(KeyCode==K1_1)
{
Clear_LCM();//
send_command(0x80);
send_data('1'); //写data
}
if(KeyCode==K1_2)
{
Clear_LCM();//
send_command(0x80);
send_data('2'); //写data
}
if(KeyCode==K2_1)
{
Clear_LCM();//
send_command(0x80);
send_data('3'); //写data
}
if(KeyCode==K2_2)
{
Clear_LCM();//
send_command(0x80);
send_data('4'); //写data
}
if(KeyCode==K3_1)
{
Clear_LCM();//
send_command(0x80);
send_data('5'); //写data
}
if(KeyCode==K3_2)
{
Clear_LCM();//
send_command(0x80);
send_data('6'); //写data
}
if(KeyCode==K4_1)
{
Clear_LCM();//
send_command(0x80);
send_data('7'); //写data
}
if(KeyCode==K4_2)
{
Clear_LCM();//
send_command(0x80);
send_data('8'); //写data
}
}
}
/*定时器0中断服务程序*/
//1ms中断一次
/*#pragma interrupt_handler Timer0_Ovf:10*/
volatile unsigned int tc0_Cnt = 0,tc0_Cnt_Display = 0;
#pragma vector = TIMER0_OVF_vect//TIMER0 溢出中断入口地址
__interrupt void Timer0_Ovf(void)
{
TCNT0 = 5; //给定时器赋初值
if (++key_stime_counter >=10)
{
key_stime_counter = 0;
key_stime_ok = 1;// 10ms到
//Voice_ChoiceScanFlag = 1;//声音选择扫描
}
}
//图
(原文件名:key4x2.jpg)
开始我怀疑是硬件, 我仔细查了硬件,没有查出啥问题。
大家看看可是软件的问题,如果不是,我继续查硬件,但是郁闷查了,没有新的发现和不对的地方。 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|