STM32 Sequencer 是 STMicroelectronics 提供的一个软件工具,用于在 STM32 微控制器上创建和执行任务序列。
在STM32的BLE程序中,会自动集成Sequencer完成相关的调度工作。
下面用STM32 Sequencer 实现按键控制 LED来演示Sequencer的工作原理。
1、开启一个新的工程,按照开发板的资源做个最小配置

将Utilities下的2个文件加入工程,并include相关路径

2、定义按键和LED的GPIO
#define BUTTON_PIN GPIO_PIN_3 #define BUTTON_PORT GPIOB #define LED_PIN GPIO_PIN_1 #define LED_PORT GPIOB
按键:PB3,gpio_input,上拉
LED:PB1,gpio_out
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2|GPIO_PIN_1, GPIO_PIN_RESET);
/*Configure GPIO pins : PB3 PB4 */
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : PB2 PB1 */
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/**/
HAL_PWREx_EnableGPIOPullUp(PWR_GPIO_B, PWR_GPIO_BIT_3|PWR_GPIO_BIT_4);
/**/
HAL_PWREx_DisableGPIOPullUp(PWR_GPIO_B, PWR_GPIO_BIT_2|PWR_GPIO_BIT_1);
/**/
HAL_PWREx_DisableGPIOPullDown(PWR_GPIO_B, PWR_GPIO_BIT_2|PWR_GPIO_BIT_1);
/* USER CODE BEGIN MX_GPIO_Init_2 */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2|GPIO_PIN_1, GPIO_PIN_SET);
/* USER CODE END MX_GPIO_Init_2 */
}2、常量定义
#define TASK_ID_BUTTON_CHECK 0 //按键TASK id #define TASK_ID_LED_TOGGLE 1 //LED翻转TASK id #define EVT_BUTTON_PRESSED (1U << 0) //TASK 优先权 #define EVT_BUTTON_DETECT (1U << 0) //TASK 优先级 #define DEBOUNCE_TIME 30 //按键防抖时间
对于Sequencer来说,只有优先级设为0,TASK才能立即执行
3、初始化及注册TASK
定义了2个任务:ButtonCheckTask,
LedToggleTask
UTIL_SEQ_Init();//初始化SEQ
//注册2个任务
UTIL_SEQ_RegTask(1U << TASK_ID_BUTTON_CHECK, UTIL_SEQ_RFU, ButtonCheckTask);
UTIL_SEQ_RegTask(1U << TASK_ID_LED_TOGGLE, UTIL_SEQ_RFU, LedToggleTask);
//直接执行按键任务ButtonCheckTask
UTIL_SEQ_SetTask(1U << TASK_ID_BUTTON_CHECK, EVT_BUTTON_DETECT);
while (1)
{
UTIL_SEQ_Run(UTIL_SEQ_DEFAULT);//运行任务
UTIL_SEQ_Idle();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}4、按键监测任务
当监测到按键按下执行LedToggleTask任务。
函数末尾,重新执行UTIL_SEQ_SetTask将ButtonCheckTask优先级设置为0,继续立即执行。
static void ButtonCheckTask(void)
{
static uint32_t last_tick = 0;
if(HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) == GPIO_PIN_RESET)
{
uint32_t current_tick = HAL_GetTick();
if((current_tick - last_tick) > DEBOUNCE_TIME)
{
UTIL_SEQ_SetTask(1U << TASK_ID_LED_TOGGLE, EVT_BUTTON_PRESSED);
}
last_tick = current_tick;
}
UTIL_SEQ_Idle();
UTIL_SEQ_SetTask(1U << TASK_ID_BUTTON_CHECK, EVT_BUTTON_DETECT);//继续执行当前任务
}5、LED 任务
// LED Task
static void LedToggleTask(void)
{
printf("LedToggleTask\r\n");
HAL_GPIO_TogglePin(LED_PORT, LED_PIN);
while(HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) == GPIO_PIN_RESET)
{
UTIL_SEQ_Idle();
}
}以上,通过Sequencer实现了按键控制LED
6、源文件
我要赚赏金
