/* * drv_key.c * * Created on: Jun 11, 2023 * Author: gxms0 */ #include "drv_key.h" KEY_t key1; KEY_t key2; KEY_t key3; KEY_t key4; void key_init(void) { key_config(&key1, GPIOD, GPIO_Pin_2, 0); key_config(&key2, GPIOB, GPIO_Pin_3, 0); key_config(&key3, GPIOB, GPIO_Pin_4, 0); key_config(&key4, GPIOB, GPIO_Pin_5, 0); } void key_thread(void) { key_update(&key1); key_update(&key2); key_update(&key3); key_update(&key4); } void key_config(KEY_ptr ptr, GPIO_TypeDef *GPIO, uint32_t Pin, uint8_t type) { ptr->GPIO = GPIO; ptr->Pin = Pin; ptr->type = type; ptr->delay = 20;//20ms ptr->state = release;//定义按下是的电平,如果按下时高电平,赋值0x01,如果按下时,电平信号为低电平,那么赋值为0x00; ptr->last = release; ptr->current = release; //初始化IO口 GPIO_InitTypeDef GPIO_InitStructure = {0}; uint32_t RCC_Periph; if(ptr->GPIO == GPIOA)RCC_Periph = RCC_APB2Periph_GPIOA; else if(ptr->GPIO == GPIOB)RCC_Periph = RCC_APB2Periph_GPIOB; else if(ptr->GPIO == GPIOC)RCC_Periph = RCC_APB2Periph_GPIOC; else if(ptr->GPIO == GPIOD)RCC_Periph = RCC_APB2Periph_GPIOD; else if(ptr->GPIO == GPIOE)RCC_Periph = RCC_APB2Periph_GPIOE; RCC_APB2PeriphClockCmd(RCC_Periph, ENABLE); GPIO_InitStructure.GPIO_Pin = ptr->Pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(ptr->GPIO, &GPIO_InitStructure); } void key_update(KEY_ptr ptr) { uint8_t gpio_bit = (GPIO_ReadInputDataBit(ptr->GPIO,ptr->Pin))?(0x01):(0x00); switch(ptr->type) { case 0x00:{ ptr->current = (gpio_bit)?(release):(pressed);//如果是0,认为是按下 }break; case 0x01:{ ptr->current = (gpio_bit)?(pressed):(release);//如果是1,认为是按下 }break; } if((get_ticks_usec() - ptr->tick ) >= (ptr->delay * 1000)) { ptr->tick = get_ticks_usec(); if(ptr->state == release)//state::release { if(ptr->current != ptr->state) { if(ptr->last == ptr->state) { ptr->state = pressed; } } } else//state::press { if(ptr->current != ptr->state) { if(ptr->last == ptr->state) { ptr->state = release; } } } ptr->last = ptr->current; } }