STM32 按键输入 |V1.0.0 LED灯的程序已经差不多了,咱们接下来可以写写别的一些东西了,比如按键的采集。 说到这个按键输入呀,我一直觉得挺难做的。实际运用的时候,真的比学的时候难多了。 大家想想呀,按键,有单击,双击,甚至三击,多击。单击,又分短按,长按。 其中,除了单击,其他的都需要计算时间,双击的间隔多少时间才合适,短按和长按的时间也需要考虑。细想起来,这个按键采集真的不是简单的事。 今天呢,就从简单的单击开始设计。 一个键的单击功能,我想大家基本也知道该怎么写,就是读IO口的电平,IO有信号了,就处理相应的程序。 IO初始化时,我们需要将IO口的模式设置为输入模式,并需要定时去读取该IO的信号。 同样的,咱们依然用正点原子的硬件,这次咱们只用一个按键。 按键的硬件 按键挂载的IO口 从硬件上就知道,按键按下,IO口就是低电平,由于外部电路没有上拉电阻,我们要把IO口模式设为上拉输入。 - //按键初始化函数
- void KEY_Init(void) //IO初始化
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//使能PORTE时钟
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//KEY0
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
- GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE4
- }
复制代码
还有,读取IO的值,有信号输入时,输出1, - /** @brief 读键值
- * @param[in] 无
- * @param[out] 无
- * @retval 类型
- * @note 10ms
- */
- u8 sKEY_GetValue(void)
- {
- u8 data = 0;
-
- if(KEY0 == 0)
- data |= 0x01;
- return data;
- }
复制代码
然后,咱们设置一个循环函数,按一下按键,切换一次LED的模式。 我们把这个函数放在10ms的循环里,这样,就相当于每10ms读一次IO口的值,可以不需要延时来防抖。 - /** @brief KEY循环
- * @param[in] 无
- * @param[out] 无
- * @retval 类型
- * @note 10ms
- */
- void sKEY_Loop(void)
- {
- static u8 LastValue;
- static u8 LedType = 0;
-
- if( sKEY_GetValue() & 0x01 )
- {
- if(LastValue == 0)
- {
- LastValue = 1;
-
- LedType = (LedType +1) % 3;
- sLED_SetType(LedType);
- }
- }
- else
- LastValue = 0;
- }
复制代码
当然,主函数也是要做相应的修改的,加入KEY的初始化函数,以及KEY的循环函数。 我们先设置LED使能,并设置LED的故障码为5。然后开始执行程序。 - int main(void)
- {
- delay_init(); //延时函数初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
- LED_Init(); //LED端口初始化
- KEY_Init();
- TIM3_Int_Init(99,7199); //10Khz的计数频率,计数到100为10ms
-
-
- while(1)
- {
- sLED_Enable(ENABLE);
- sLED_SetErrNum(5);
-
- if(GetTimerFlag()) //10ms
- {
- sLED_Loop();
- sKEY_Loop();
- }
- }
- }
复制代码
这样就可以了。 今晚就不放视频了,先到这里,明天见。 文章出处: Yue無缺
|