怎么把这段状态机代码移植到stc32?
typedef struct{
GPIO_TypeDef *gpiox; // 指向 GPIO 端口的指针,例如 GPIOA、GPIOB 等。
uint16_t pin; // 指定 GPIO 引脚,例如 GPIO_PIN_0、GPIO_PIN_1 等。
uint16_t ticks; // 用于计时的变量,通常用于去抖动处理。
uint8_t level; // 当前按键的电平状态,高电平或低电平。
uint8_t id; // 按键的唯一标识符,可以用于区分不同的按键。
uint8_t state; // 按键的当前状态,可能用于表示按键是否被按下或释放。
uint8_t debouce_cnt; // 按键去抖动计数器,用于防止按键抖动引起的误触发。
uint8_t repeat; // 按键重复按下的次数。
} button;
button btns; // 按键数组
// 按键初始化函数
void key_init(void)
{
// 初始化第一个按键
btns.gpiox = GPIOB; // 指定GPIO端口
btns.pin = GPIO_PIN_0; // 指定引脚
btns.level = 1; // 设置初始电平
btns.id = 0; // 设置按键ID
// 初始化第二个按键
btns.gpiox = GPIOB;
btns.pin = GPIO_PIN_1;
btns.level = 1;
btns.id = 1;
// 初始化第三个按键
btns.gpiox = GPIOB;
btns.pin = GPIO_PIN_2;
btns.level = 1;
btns.id = 2;
// 初始化第四个按键
btns.gpiox = GPIOA;
btns.pin = GPIO_PIN_0;
btns.level = 1;
btns.id = 3;
}
// 按键任务处理函数
void key_task(button *btn)
{
// 读取按键当前电平
uint8_t gpio_level = HAL_GPIO_ReadPin(btn->gpiox, btn->pin);
// 如果按键状态大于 0,则递增计时器
if (btn->state > 0)
btn->ticks++;
// 如果当前电平与按键记录的电平不同,进行去抖动处理
if (btn->level != gpio_level)
{
// 计数达到 3 次,确认电平变化
if (++(btn->debouce_cnt) >= 3)
{
btn->level = gpio_level; // 更新电平
btn->debouce_cnt = 0; // 重置去抖动计数器
}
}
else
{
btn->debouce_cnt = 0; // 电平没有变化,重置去抖动计数器
}
// 按键状态机
switch (btn->state)
{
case 0: // 初始状态
if (btn->level == 0) // 等待按键按下
{
btn->ticks = 0; // 重置计时器
btn->repeat = 1; // 初始按键重复计数
btn->state = 1; // 进入按键按下状态
}
break;
case 1: // 按键按下状态
if (btn->level != 0) // 等待按键松开
{
if (btn->ticks >= 30) // 按键长按
{
ucLed ^= 1; // 执行长按后的操作
btn->state = 0; // 返回初始状态
}
else
{
btn->ticks = 0; // 重置计时器
btn->state = 2; // 进入按键释放状态
}
}
else if (btn->ticks >= 30) // 按键长按
{
btn->repeat = 0; // 防止释放的时候再次触发单击事件
}
break;
case 2: // 按键释放状态
if (btn->ticks >= 15) // 计时器达到阈值
{
btn->state = 0; // 返回初始状态
if(btn->repeat == 1)
{
ucLed ^= 1; // 点亮对应的LED
}
else if(btn->repeat == 2)
{
ucLed ^= 1; // 点亮对应的LED
}
}
else
{
if (btn->level == 0) // 按键再次按下
{
btn->repeat++;// 递增重复计数
btn->ticks = 0; // 重置计时器
btn->state = 1; // 返回按键按下状态
}
}
break;
}
}
// 按键状态处理函数
void key_state(void)
{
for (uint8_t i = 0; i < 4; i++) // 遍历所有按键
{
key_task(&btns); // 处理每个按键的状态
}
}
就是松开后才允许下一次按下触发,直接重写一个好了,消抖可以定期执行这个函数,用运行其他程序的时间消抖 只有HAL_GPIO_ReadPin(btn->gpiox, btn->pin)这个函数不是不是STC32的,只要把这个改成合适的GPIO状态读取函数即可
其它代码都是通用的
页:
[1]