STM32CubeMx使用FreeRTOS搭建printf输出串口打印-----基于正点原子开发板阿波罗

STM32CubeMx使用FreeRTOS搭建printf输出串口打印-----基于正点原子开发板阿波罗

1.输入目标芯片

使用的开发板是正点原子的STM32F429IGT6开发板
在这里插入图片描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ABV5DpdV-1675233100755)(C:\Users\lan\AppData\Roaming\Typora\typora-user-images\image-20230201095021027.png)]

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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kvcMc5qX-1675233100757)(C:\Users\lan\AppData\Roaming\Typora\typora-user-images\image-20230201095211087.png)]
1.Crystal/Ceramic Resonator(晶振/陶瓷谐振器)表示的是选择 HSE(外部高速时钟)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ImdwZujU-1675233100757)(C:\Users\lan\AppData\Roaming\Typora\typora-user-images\image-20230201102028162.png)]
2.BYPASS Clock Source(旁路时钟源)就是由外部给定一个时钟信号,是单向的,猜测一般用于作为同步时钟
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4rriIgTz-1675233100758)(C:\Users\lan\AppData\Roaming\Typora\typora-user-images\image-20230201102102050.png)]
3.Disable(禁用)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-USpNPDg2-1675233100758)(C:\Users\lan\AppData\Roaming\Typora\typora-user-images\image-20230201102145562.png)]

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.代码添加

7.1 在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 */

7.2 提前告知编译器不使用半主机模式

void _sys_exit(int x)
{
    x = x;
}

/* 标准库需要的支持类型 */
struct __FILE
{
    int handle;
};

FILE __stdout;

7.3 GCC中使用标准库重定向

int _write(int fd, char *ptr, int len)  
{  
  HAL_UART_Transmit(&huart1, (uint8_t*)Buffer, sizeof(Buffer), 0xFFFF);
  return len;
}

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 循环前,串口初始化后,添加接收中断开启函数

uint8_t Buffer[]="hello world";
HAL_UART_Receive_IT(&huart1,Buffer,1);
HAL_UART_Transmit_IT(&huart1,Buffer,sizeof(Buffer),100);

在这里插入图片描述

10.增加FreeRTOS支持

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

11.在FreeRTOS中添加源码

在这里插入图片描述

参考:https://www.jianshu.com/p/4f01bfd91e67

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
stm32cubemx是一个用于生成STM32微控制器初始化代码的工具,而FreeRTOS是一个实时操作系统,串口DMA(直接存储器访问)是一种在数据传输时减少CPU负荷和提高效率的方式。当使用STM32CubeMX结合FreeRTOS来接收不定长数据时,可以按照以下步骤进行操作。 首先,在CubeMX中配置串口和DMA的初始化参数,使其支持不定长数据接收。可以选择需要的串口和对应的DMA通道,配置串口的波特率、数据位和停止位等参数。然后,配置DMA以支持循环传输和变化长度的数据接收。 其次,生成初始化代码并在FreeRTOS中集成。CubeMX可以生成针对FreeRTOS的初始化代码,将配置好的串口和DMA初始化函数添加到FreeRTOS任务中,并在任务中实现数据接收的逻辑。可以利用FreeRTOS提供的任务管理和事件控制功能,让串口DMA在后台接收数据,同时不影响其他任务的运行。 最后,根据实际需求处理不定长数据。在串口DMA接收到数据后,根据数据长度进行相应的处理,可以通过消息队列或者信号量将数据传递给其他任务进行后续处理,也可以在接收完成后发送一个事件信号通知其他任务进行处理。需要根据具体需求来设计数据处理的流程,确保数据能够被准确地接收和处理。 总之,在使用STM32CubeMXFreeRTOS进行串口DMA接收不定长数据时,需要合理配置串口和DMA参数,并在FreeRTOS任务中实现数据接收和处理的逻辑,以实现高效、稳定地数据传输和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值