博士
最后登录1970-1-1
在线时间 小时
注册时间2014-5-11
|
本帖最后由 西点 于 2015-8-1 16:53 编辑
最近有个项目需要用到按键扫描,奋斗几天弄出来了,但是结果发现 这程序存在BUG。。。。
​程序开机时刻跑的很正常,一个小时左右却跑死了,主函数里面LED 灯不再闪烁,停在某一状态,复位后,程序又如开机一样可以跑了。
​很纠结,一个按键扫描程序居然跑死了,
​
​求高手指点指点,不甚感激。
​
​精简的源码如下:
#define USART1_REC_LEN 7​​
​#define Key_Press 1 //按键按下
#define Key_On 0 // 按键弹起
​
​volatile u16 g_u16_currentkey = 0;
​volatile u8 Scankeystatus = 0;​
u8 temp_key = 0; ​
​u8 TxD_ToPC[8] = {0x71,0,0,0,0,0,0,0x71}; // 发送到上位机的信息
u8 USART1_RX_BUF[USART1_REC_LEN]; //
u8 USART1_RX_num = 0;
u8 RXD_FromPC[USART1_REC_LEN]; //
​// 按键扫描​
u8 Scan_key(void)
{
u8 key = 0;
​
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0) == Key_Press) key |= 0x01;
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1) == Key_Press) key |= 0x02;
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2) == Key_Press) key |= 0x04;
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3) == Key_Press) key |= 0x08;
return key;
}
​// 接收上位机的命令
​void ReceivedFromPC_order(void)
{
u8 cmd;
cmd = RXD_FromPC[0];
switch(cmd)
{
case 0x71:
Scankeystatus = 1; // 采集键盘状态标识 发送一次即可
break;
case 0x72:
Scankeystatus = 0;
break;
}​
​
​// 键盘状态重新打包发送
​void Send_key_status(void)
{
u8 sum,i;
​ TxD_ToPC[0] = 0x71;
TxD_ToPC[1] = temp_key;
TxD_ToPC[2] = g_u16_currentkey;
TxD_ToPC[3] =0x22;
TxD_ToPC[4] = 0x55; // 原来是采集别的数据,现在用固定的数代替
TxD_ToPC[5] =0x66;
TxD_ToPC[6] = 0xff;
sum = 0;
for(i = 0;i < 7; i++)
{
sum += TxD_ToPC;
}
TxD_ToPC[7] = sum;
USART1_transmitS(TxD_ToPC,8);
}
​
​//串口1发送函数
​void USART1_transmit(unsigned char byte)
{
USART_SendData(USART1,byte);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}
void USART1_transmitS(unsigned char *dat,unsigned char num)
{
unsigned char i;
for(i=0;i<num;i++)
{
USART1_transmit(dat);
}
}
// 串口1中断接收上位机函数​
​void USART1_IRQHandler(void)
{
u8 i;
if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)
{
USART1_RX_BUF[USART1_RX_num] = USART_ReceiveData(USART1); //(USART1->DR)
USART1_RX_num++;
if(USART1_RX_num >= USART1_REC_LEN)
{
USART1_RX_num = 0;
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
for(i = 0;i<7;i++)
{
RXD_FromPC = USART1_RX_BUF;
}
ReceivedFromPC_order();
USART_ITConfig( USART1,USART_IT_RXNE, ENABLE);
}
}
​}
​// 定时器3 /20ms / 发送开关状态给上位机
​void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
if(Scankeystatus == 1)
{
Send_key_status();
}
}
​
​// 主函数
​
​int main(void)
{
LED_GPIO_Config(); // LED2
delay_init();
uart1_init(115200);
TIM3_Int_Init(200,7199);
​ KEY_GPIO_Config();
temp_key = Scan_key();
g_u16_currentkey = temp_key; // 第一次记录按键状态
​
delay_ms(100);
while(1)
{
temp_key = Scan_key();
if(temp_key != g_u16_currentkey )
​{
delay_ms(10);
temp_key = Scan_key();
if(temp_key != g_u16_currentkey )
{
g_u16_currentkey = Scan_key(); // 记录真实键值
}
}
LED2 = 0;
delay_ms(180);
LED2 = 1;
delay_ms(180);
}
​}
​
串口、按键、LED、 定时器的初始化再次就不再啰嗦,基本是按照 例子改编的。
​
​困扰了好几天了,主程序老是跑死,定时器依然活着。 不知道哪里出了问题了。。。
​
​求高手破解。
​ |
|