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