STM32F103R6 PROTEUS9.0 FREERTOS实现双任务流水灯
本文展示了一个基于STM32F1和FreeRTOS的双LED控制程序。主要内容包括系统配置使用HSI时钟源通过PLL倍频至64MHz配置系统时钟和外设时钟GPIO初始化设置PA1-PA3为红色LED输出PB0-PB2为绿色LED输出FreeRTOS任务创建TaskRedLED以400ms周期切换红色LED组TaskGreenLED以1000ms周期切换绿色LED组辅助功能系统时钟配置错误处理函数数字转换工具函数程序采用FreeRTOS实时操作系统管理两个独立LED控制任务实现不同频率的LED闪烁效果展示了基本的RTOS任务创建和调度方法。main.c/** ****************************************************************************** * File Name : main.c * Description : Dual LED Toggle with FreeRTOS (native API) ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include stm32f1xx_hal.h #include FreeRTOS.h #include task.h /* Peripheral handles (required by other modules for linker resolution) */ DMA_HandleTypeDef hdma_spi1_tx; DMA_HandleTypeDef hdma_usart1_tx; SPI_HandleTypeDef hspi1; UART_HandleTypeDef huart1; /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); void Error_Handler(void); static void MX_GPIO_Init(void); static void TaskRedLED(void *pvParameters); static void TaskGreenLED(void *pvParameters); int main(void) { /* MCU Configuration----------------------------------------------------------*/ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); /* Create the Red LED toggle task (PA1/PA2/PA3), period 400ms */ xTaskCreate(TaskRedLED, RedLED, configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY 1, NULL); /* Create the Green LED toggle task (PB0/PB1/PB2), period 1000ms */ xTaskCreate(TaskGreenLED, GreenLED, configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY 1, NULL); /* Start scheduler */ vTaskStartScheduler(); /* We should never get here as control is now taken by the scheduler */ while (1) { } } /** System Clock Configuration * HSI - PLL (x16) - 64MHz SYSCLK, HCLK32MHz, APB18MHz, APB216MHz */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue 16; RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSI_DIV2; RCC_OscInitStruct.PLL.PLLMUL RCC_PLL_MUL16; if (HAL_RCC_OscConfig(RCC_OscInitStruct) ! HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV2; RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_0) ! HAL_OK) { Error_Handler(); } HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0); } /** Configure GPIO pins for LED control * PA1/PA2/PA3 - Red LED (Output Push-Pull) * PB0/PB1/PB2 - Green LED (Output Push-Pull) */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /* Configure PA1, PA2, PA3 as output push-pull for Red LED */ GPIO_InitStruct.Pin GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); /* Configure PB0, PB1, PB2 as output push-pull for Green LED */ GPIO_InitStruct.Pin GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2; 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); /* Set initial output level low (LEDs off) */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_PIN_RESET); } /* TaskRedLED: Toggle Red LED on PA1/PA2/PA3, period 400ms */ static void TaskRedLED(void *pvParameters) { for(;;) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); vTaskDelay(pdMS_TO_TICKS(200)); } } /* TaskGreenLED: Toggle Green LED on PB0/PB1/PB2, period 1000ms */ static void TaskGreenLED(void *pvParameters) { for(;;) { HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2); vTaskDelay(pdMS_TO_TICKS(500)); } } /* TIM1 Period Elapsed Callback - provides HAL time base */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim-Instance TIM1) { HAL_IncTick(); } } /* itoa: convert n to characters in s (required by SSD1306 module) */ void itoa(int n, char s[]) { int i, sign; if ((sign n) 0) n -n; i 0; do { s[i] n % 10 0; } while ((n / 10) 0); if (sign 0) s[i] -; s[i] \0; /* reverse the string */ int j, k; char c; for (j 0, k i - 1; j k; j, k--) { c s[j]; s[j] s[k]; s[k] c; } } /** * brief This function is executed in case of error occurrence. */ void Error_Handler(void) { while(1) { } } #ifdef USE_FULL_ASSERT /** * brief Reports the name of the source file and the source line number * where the assert_param error has occurred. */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf(Wrong parameters value: file %s on line %d\r\n, file, line) */ } #endif /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/