本帖最后由 hzocce 于 2019-1-18 16:44 编辑
玩一个按键状态机扫描程序,PB3通过电阻上拉到VCC,按键按下后短路到GND。
PG1接了一个LED,通过亮灭来观察按键是否被单片机识别到。
本来按键功能就是按下后翻转IO电平,表现的现象为LED亮灭,也就是通过按键来控制LED亮灭。
但是发现了一个问题,就是按下一次后,LED再都不会翻转了。
后面终于知道了程序为什么不执行原因,用串口输出当时读取到得数值后,发现竟然是8,为何???
求高手指点,谢谢!
#include "stm8s.h"
#include "usart2.h"
#include "stm8s_tim1.h"
unsigned char Flag_10ms=0;
extern u8 RxBuffer[RxBufferSize];
extern u8 UART_RX_NUM;
void Delay(uint16_t nCount)
{
while (nCount != 0)
{
nCount--;
}
}
//时钟配置
void CLK_Config(void)
{
CLK_HSICmd(ENABLE); //启动内部高速时钟
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //1分频
}
#define Key_Get GPIO_ReadInputPin(GPIOB, GPIO_PIN_3)
#define KEY_STATE_0 0 // 按键状态位
#define KEY_STATE_1 1
#define KEY_STATE_2 2
#define KEY_STATE_3 3
#define KEY_STATE_4 4
#define LONG_KEY_TIME 200 //长按的3秒时间
#define SINGLE_KEY_TIME 3 // 短按的消抖时间
#define N_Key 0 //无键
#define S_Key 1 //单键
#define D_Key 2 //双键
#define L_Key 10 //长键
#define T_Key 3 //3次点击
#define F_Key 4 //4次点击
#define V_Key 5 //5次点击
#define KEY_ON 0
#define KEY_OFF 1
unsigned char Scan_key(void)
{
static char key_state = 0; //按键的状态
unsigned char key_press=0; //按键是否被按下
unsigned char key_return = 0;
key_press=0;
key_press = Key_Get; // 读按键I/O电平
UART2_SendByte(key_press);//----------------------输出后发现读取到得竟然是8哎~~~~~~~~~~~~~~
switch (key_state)
{
case KEY_STATE_0: // 按键初始态
if(key_press==KEY_ON)//按下后为0,进入判断
{
key_state = KEY_STATE_1;// 键被按下,状态转换到键确认态下一阶段
}break;
case KEY_STATE_1: // 按键确认态
if(key_press==KEY_ON)
{
key_return = 1; // 按键仍按下,按键确认输出为“1”
key_state = KEY_STATE_2;// 状态转换到键释放态
}
else
{
key_state = KEY_STATE_0; // 按键已抬起,转换到按键初始态
}
break;
case KEY_STATE_2:
//if(key_press==KEY_OFF) //如果是判断1则永远都不会执行,为什么???????
if(key_press==8) //确认是否松开,若松开进入到初始
{
key_state = KEY_STATE_0;//按键已释放,转换到按键初始态
}
break;
}
return key_return; //返回按键值
}
void Do_Something_For_You(unsigned char Which)
{
switch(Which)
{
case S_Key: GPIO_WriteReverse(GPIOG,GPIO_PIN_0); //单击事件
break;
case D_Key: //双击事件
GPIO_WriteReverse(GPIOG,GPIO_PIN_1);
break;
case T_Key: //三击事件
break;
case F_Key: //四击事件
break;
case V_Key: //五击事件
break;
}
}
void Time1(void)
{
TIM1_DeInit();
TIM1_DeInit(); //恢复为默认值
//TIM1_TimeBaseInit(15, TIM1_COUNTERMODE_UP, 20000, 0x00); //不分频16MHz 计数值20000 80ms中断一次
//TIM1_TimeBaseInit(15, TIM1_COUNTERMODE_UP, 5000, 0x00); //不分频16MHz 计数值5000 20ms中断一次
TIM1_TimeBaseInit(15, TIM1_COUNTERMODE_UP, 10000, 0x00); //不分频16MHz 10ms中断一次
TIM1_GenerateEvent(TIM1_EVENTSOURCE_UPDATE); //手册里有说明,不设置的话就不会产生中断
TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE); //配置更新中断
TIM1_Cmd(ENABLE); //使能定时器
}
unsigned char KEY_Function=0;
void main(void)
{
// CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //使用内部高速时钟
CLK_Config();
Init_UART2(); //初始化串口2
Time1();
enableInterrupts();
GPIO_Init(GPIOG, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_Init(GPIOG, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_Init(GPIOB, GPIO_PIN_3, GPIO_MODE_IN_PU_NO_IT);
GPIO_WriteLow(GPIOG,GPIO_PIN_0);
GPIO_WriteLow(GPIOG,GPIO_PIN_1);
printf("\r\nHello%s\r\n"," Word!");
while (1)
{
if(Flag_10ms)
{
Flag_10ms=0;
KEY_Function=Scan_key();
Do_Something_For_You(KEY_Function);
};
}
}
INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11)
{
TIM1_ClearITPendingBit(TIM1_IT_UPDATE);
Flag_10ms=1;
// if(++Flag_10ms>=10)
// {
// Flag_10ms=0;
// GPIO_WriteReverse(GPIOG,GPIO_PIN_1);
// };
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval : None
*/
void assert_failed(u8* file, u32 line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|