【STM32】HAL库 新建MDK工程
【STM32】HAL库 串口轮询发送
【STM32】HAL库 LED闪烁、流水灯
【STM32】HAL库 定时器中断
【STM32】HAL库 外部中断
使用STM32F103C8T6开发板,用STM32CubeMX配置FreeRTOS,可以适配正点原子FreeRTOS所有实验的基础工程
PA0和PA1输出模式,驱动两个LED灯。
PB4、PB6和PB11输入模式,PB1外部中断下降沿触发,全部上拉,检测按键。
定时器4,设置为1000Hz的10到100倍,100倍为100000Hz。用于测任务运行时间。
把定时器3优先级改为6,生成工程文件后,再将定时器2优先级改为4。
定时器1优先级改为最高,可以在任务中使用HAL_Delay代替正点原子的delay_ms
void LED0_TOGGLE(void)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
}
void LED1_TOGGLE(void)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
}
void task1(void *argument)
{
/* USER CODE BEGIN task1 */
/* Infinite loop */
for(;;)
{
LED0_TOGGLE();
osDelay(500);
}
/* USER CODE END task1 */
}
void task2(void *argument)
{
/* USER CODE BEGIN task2 */
/* Infinite loop */
for(;;)
{
LED1_TOGGLE();
osDelay(500);
}
/* USER CODE END task2 */
}
#include
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch ,1,1000);
return (ch);
}
void task1(void *argument)
{
/* USER CODE BEGIN task1 */
/* Infinite loop */
uint32_t task1_num = 0;
for(;;)
{
printf("task1_num:%d\r\n",++task1_num);
LED0_TOGGLE();
osDelay(500);
}
/* USER CODE END task1 */
}
void task2(void *argument)
{
/* USER CODE BEGIN task2 */
/* Infinite loop */
uint32_t task2_num = 0;
for(;;)
{
printf("task2_num:%d\r\n",++task2_num);
LED1_TOGGLE();
osDelay(500);
}
/* USER CODE END task2 */
}
uint8_t key_scan(uint8_t mode);
#define KEY0 HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)
#define KEY1 HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)
#define KEY2 HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)
#define WK_UP HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11)
#define KEY0_PRES 1
#define KEY1_PRES 2
#define KEY2_PRES 3
#define WKUP_PRES 4
uint8_t key_scan(uint8_t mode)
{
static uint8_t key_up = 1;
uint8_t keyval = 0;
if (mode) key_up = 1;
if (key_up && (KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WK_UP == 0))
{
HAL_Delay (10);
key_up = 0;
if (KEY0 == 0) keyval = KEY0_PRES;
if (KEY1 == 0) keyval = KEY1_PRES;
if (KEY2 == 0) keyval = KEY2_PRES;
if (WK_UP == 0) keyval = WKUP_PRES;
}
else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 1)
{
key_up = 1;
}
return keyval;
}
void task3(void *argument)
{
/* USER CODE BEGIN task3 */
/* Infinite loop */
uint8_t key = 0;
for(;;)
{
key = key_scan(0);
if(key) printf("key = %d\r\n",key);
osDelay(10);
}
/* USER CODE END task3 */
}
修改定时器2的优先级
HAL_NVIC_SetPriority(TIM2_IRQn, 4, 0);
打开定时器中断
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_Base_Start_IT(&htim3);
定时器回调函数,打印定时器的优先级
uint32_t FreeRTOSRunTimeTicks;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
uint32_t preemptPriority, subPriority;
/* USER CODE END Callback 0 */
if (htim->Instance == TIM1) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
if (htim->Instance == TIM2) {
HAL_NVIC_GetPriority(TIM2_IRQn, NVIC_PRIORITYGROUP_4, &preemptPriority, &subPriority);
printf("TIM2_Priority:%d\r\n",preemptPriority);
}
if (htim->Instance == TIM3) {
HAL_NVIC_GetPriority(TIM3_IRQn, NVIC_PRIORITYGROUP_4, &preemptPriority, &subPriority);
printf("TIM3_Priority:%d\r\n",preemptPriority);
}
if (htim->Instance == TIM4) {
FreeRTOSRunTimeTicks++;
}
/* USER CODE END Callback 1 */
}
开启定时器4,用于任务运行时间统计
void configureTimerForRunTimeStats(void)
{
HAL_TIM_Base_Start_IT(&htim4);
}
unsigned long getRunTimeCounterValue(void)
{
return FreeRTOSRunTimeTicks;
}
#define configUSE_QUEUE_SETS 1 /* 1: 使能队列集, 默认: 0 */