文章目录
- STM32CubeMx使用FreeRTOS搭建printf输出串口打印-----基于正点原子开发板阿波罗
- 1.输入目标芯片
- 2.选择RCC时钟
- 3.配置调试模式
- 4.USART的配置
- 5.配置中断
- 6.printf的重定向功能
- 7.代码添加
- 8.修改中断函数
- 9.添加全局变量
- 10.增加FreeRTOS支持
- 11.在FreeRTOS中添加源码
STM32CubeMx使用FreeRTOS搭建printf输出串口打印-----基于正点原子开发板阿波罗
1.输入目标芯片
使用的开发板是正点原子的STM32F429IGT6开发板
2.选择RCC时钟
在 STM32 中,一共有 5 个时钟源,分别是 HSI 、 HSE 、 LSI 、 LSE 、 PLL 。
①HSI 是高速内部时钟, RC 振荡器,频率为 8MHz ;
②HSE 是高速外部时钟,可接石英 / 陶瓷谐振器,或者接外部时钟源,频率范围是 4MHz – 16MHz ③LSI 是低速内部时钟, RC 振荡器,频率为 40KHz ;
④LSE 是低速外部时钟,接频率为 32.768KHz 的石英晶体;
⑤PLL 为锁相环倍频输出,严格的来说并不算一个独立的时钟源, PLL 的输入可以接 HSI/2 、 HSE 或者 HSE/2 。PLL倍频可选择为 2 – 16 倍,但是其输出频率最大不得超过 72MHz
1.Crystal/Ceramic Resonator(晶振/陶瓷谐振器)表示的是选择 HSE(外部高速时钟)
2.BYPASS Clock Source(旁路时钟源)就是由外部给定一个时钟信号,是单向的,猜测一般用于作为同步时钟
3.Disable(禁用)
3.配置调试模式
比较重要的一部:非常重要的一步,否则会造成第一次烧录程序后续无法识别调试器
配置JTAG模式
配置Serial Wire
4.USART的配置
Asynchronous (异步的),
Synchronous(同步的),
Single Wire (Half-Duplex)(单线(半双工)),
Multiprocessor Communication(多处理器通信),这里为我们配置的模式。
IrDA(红外通讯),介绍链接http://www.stmcu.org.cn/module/forum/thread-610633-1-1.html
LIN(LIN总线协议),介绍链接https://www.cnblogs.com/yangjiguang/p/6093240.html
SmartCard(智能卡),介绍链接https://baike.baidu.com/item/smart%20card
学习链接https://blog.csdn.net/xqhrs232/article/details/80904616
SmartCard with Card Clock (带卡时钟的智能卡) 。
Hardware Flow Control (RS232) 选项中选择 Disable 或者 Enable (在这种模式中只有在Mode中选择Asynchronous方可选择)
参考:https://blog.csdn.net/qq_26575553/article/details/97249848
5.配置中断
6.printf的重定向功能
因为 Microlib 进行了高度优化以使代码变得很小。它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。 某些库函数的运行速度也比较慢,想要使用printf(),必须开启
7.代码添加
在main函数添加
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN 4 */
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
/**
* @brief getchar,scanf USARTx
* @retval None
*/
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
/* USER CODE END 4 */
8.修改中断函数
stm32f4xx_it.c
中断服务函数文件,找到 USART1 中断的服务函数 USART1_IRQHandler()
中断服务函数里面就调用了串口中断处理函数 HAL_UART_IRQHandler()
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
然后再stm32f4xx_hal_uart.c 中找到 定时器中断处理函数原型 HAL_TIM_IRQHandler()
,他的主要作用是判断是哪个串口产生中断,清除中断标识位,然后再去调用中断回调函数 HAL_UART_RxCpltCallback()
在 stm32f1xx_it.c
这个文件的最下面添加 HAL_UART_RxCpltCallback()
的回调函数实现
/* USER CODE BEGIN 1 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
HAL_UART_Transmit(&huart1, (uint8_t *)Buffer, 1, 0xffff);
HAL_UART_Receive_IT(&huart1, (uint8_t *)Buffer, 1);
}
}
/* USER CODE END 1 */
9.添加全局变量
需要在 main.c 头部添加全局变量 Buffer
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
uint8_t Buffer[1];
/* USER CODE END PV */
需要在stm32f1xx_it.c 头部声明全局变量 Buffer
/* External variables --------------------------------------------------------*/
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */
extern uint8_t Buffer[1];
/* USER CODE END EV */
在 main.c 中,while 循环前,串口初始化后,添加接收中断开启函数
10.增加FreeRTOS支持
11.在FreeRTOS中添加源码
参考:https://www.jianshu.com/p/4f01bfd91e67