STM32 Uart中断发送打印乱码问题记录

这篇具有很好参考价值的文章主要介绍了STM32 Uart中断发送打印乱码问题记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

print 和scanf 重定向

这里需要解决2个问题;

1. print 和scanf重定向 编写对应的内部函数

2. 编译器兼容MDK和GCC

参考内容

基于 VsCode + GCC + STM32 环境下的串口输入输出重定向_gcc libc 重定向-CSDN博客

修改后的参考代码,亲自用VSCODE GCC和MDK测试 ok

#include "stdio.h"


// 条件编译
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(void)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif /* __GNUC__ */




/* 告知连接器不从C库链接使用半主机的函�???????? */
// 标准库需要的支持函数                 
struct __FILE 
{ 
    int handle; 
}; 
 
// 定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
    x = x; 
} 
 
FILE __stdout;




/**
  * 函数功能: 重定�??? c库函�??? printf�??? DEBUG_USARTx
  * 输入参数: �???
  * �??? �??? �???: �???
  * �???    明:�???
  */
PUTCHAR_PROTOTYPE
{

  /***********等待上一次发送完成************/
	while(huart1.gState == HAL_UART_STATE_BUSY_TX);
  // HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFF); //阻塞式无限等�???
  HAL_UART_Transmit_IT(&huart1, (uint8_t *)&ch, 1); //中断方式
  // HAL_UART_Transmit_DMA(&huart1, (uint8_t *)&ch, 1); //DMA方式
  return ch;
}


/**
  * 函数功能: 重定�??? c库函�??? getchar,scanf�??? DEBUG_USARTx
  * 输入参数: �???
  * �??? �??? �???: �???
  * �???    明:�???
  */
GETCHAR_PROTOTYPE
{
  uint8_t ch = 0;

  // HAL_UART_Receive(&huart1, &ch, 1, 0x0FF);
  HAL_UART_Receive_IT(&huart1, &ch, 1);
  //  HAL_UART_Receive_DMA(&huart1, &ch, 1);
    
  return ch;
}


#ifdef __GNUC__
// 禁用半主机:
#pragma import(__use_no_semihosting)     //关闭半主机模式,只需要在任意�????????个C文件中加入即可�??
int _write(int file, char *ptr, int len)
{
    int DataIdx;
    for (DataIdx = 0; DataIdx < len; DataIdx++) 
    { 
        __io_putchar(*ptr++); 
    }
    return len;
}

int _read(int file, char *ptr, int len)
{
  int DataIdx;

  for (DataIdx = 0; DataIdx < len; DataIdx++)
  {
    *ptr++ = __io_getchar();
  }

  return len;
}
#endif

总结几个内容:

1.不同编译环境下的输入/输出重定向

在 gcc环境下,printf重定向跟以往的在 MDK上的重定向有点不同。

  • Keil、IAR等MDK上面,都是用以下方式重定向的 
int fputc(int ch, FILE *f)
int fgetc(FILE *f)
  • gcc环境下,使用的是如下方式:
int _write(int file, char *ptr, int len)
int _read(int file, char *ptr, int len)

因此用条件编译兼容两种情况

2. 禁用半主机也是在GCC下才使用,因此全部防止到了如下条件编译中

注意,如下的_wirte和_read 也调用了前面的PUTCHAR_PROTOTYPE和GETCHAR_PROTOTYPE

#ifdef __GNUC__
// 禁用半主机:
#pragma import(__use_no_semihosting)     //关闭半主机模式,只需要在任意�????????个C文件中加入即可�??
int _write(int file, char *ptr, int len)
{
    int DataIdx;
    for (DataIdx = 0; DataIdx < len; DataIdx++) 
    { 
        __io_putchar(*ptr++); 
    }
    return len;
}

int _read(int file, char *ptr, int len)
{
  int DataIdx;

  for (DataIdx = 0; DataIdx < len; DataIdx++)
  {
    *ptr++ = __io_getchar();
  }

  return len;
}
#endif

通过以上修改后已经完成了重定向

2.printf打印不全(或打印乱码问题)

最初参考代码如下,此处此时了三种方式,只有阻塞式可以完整打印

PUTCHAR_PROTOTYPE
{


  // HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFF); //阻塞式
  HAL_UART_Transmit_IT(&huart1, (uint8_t *)&ch, 1); //中断方式
  // HAL_UART_Transmit_DMA(&huart1, (uint8_t *)&ch, 1); //DMA方式
  return ch;
}

,其它两种方式打印效果如下

while1内容如下

printf("Hello, uart printf simple!");

HAL_Delay(1000);

 实际打印效果如下

STM32 Uart中断发送打印乱码问题记录,stm32,嵌入式硬件,单片机

 原因是没有发送完成又被新的中断打断了

查找参考资料:【stm32使用CMSIS-Driver printf串口重映射打印不完整的问题】_cmsis 重写printf-CSDN博客

修改增加等待不忙发送,即增加如下红色部分后测试中断方式正常,DMA应该也正常.

PUTCHAR_PROTOTYPE

{

  /***********等待上一次发送完成************/

  while(huart1.gState == HAL_UART_STATE_BUSY_TX);

  // HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFF); //阻塞式无限等�???

  HAL_UART_Transmit_IT(&huart1, (uint8_t *)&ch, 1); //中断方式

  // HAL_UART_Transmit_DMA(&huart1, (uint8_t *)&ch, 1); //DMA方式

  return ch;

}

发送修改后测试ok

STM32 Uart中断发送打印乱码问题记录,stm32,嵌入式硬件,单片机

那么接收是否需要增加状态判断,判断不忙或者IDLE时再接收?

最近简单使用了STM32,如上简单记录下.

串口配置参考

【STM32F4+CubeMX零基础快速入门】串口收发全攻略_哔哩哔哩_bilibili 

printf重定向参考

基于 VsCode + GCC + STM32 环境下的串口输入输出重定向_gcc libc 重定向-CSDN博客

STM32 gcc与mdk下的printf重定向方式_gcc printf与keil printf-CSDN博客 文章来源地址https://www.toymoban.com/news/detail-793419.html

到了这里,关于STM32 Uart中断发送打印乱码问题记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 UART串口通信IDLE空闲中断的使用步骤

    参考了各路大神的资料,蒙蔽了半天,终于学会了,记录一下,以后忘了可以回来复习参考。 一、首先在stm32cube中配置打开对应uart串口的中断 二、工程main函数调用 __HAL_UART_ENABLE_IT(huart1,UART_IT_IDLE);//hal库宏定义,使能串口空闲中断     HAL_UART_Receive_DMA(huart1,data,sizeof(data));//使

    2024年02月12日
    浏览(32)
  • 【STM32笔记】HAL库UART串口配置及重定向(解决接收中断与scanf不能同时工作、重定向卡死、低功耗一直唤醒的问题)

    【STM32】HAL库UART串口配置及重定向(解决接收中断与scanf不能同时工作、重定向卡死、低功耗一直唤醒的问题) 注意:这里用的编译器版本为ARMCC(也就是第5代编译器 而不是AC6) 首先 要使用printf和scanf 必不可少的就是 这里需要做的就是配置单片机的UART 并且使其能够被pri

    2023年04月08日
    浏览(35)
  • STM32学习笔记-SMT32使用HAL库UART中断方式使用

    目录 1、引言 2、配置 3、流程 近来需要使用蓝牙模块,再了解到蓝牙模块等无线模块许多使用串口透传,便决定在研究一下串口UART 的使用方法。 由于用的板子种类每次都不一样,有F103 有G0 有G4 还有公司的8位自研芯片,所以每次用起来都需要重头开始复习 每次使用UART的目

    2023年04月12日
    浏览(37)
  • 【STM32+HAL库+CubeMX】UART轮询收发、中断收发、DMA收发方法及空闲中断详解

    Author: DrinkCat(szt@drinkcat.com) Copyright © 2023 DrinkCat Original link: DrinkCat’s Blog UART是一种异步串行通信接口,常用于通过串口与外部设备进行通信。它通过发送和接收数据帧来实现数据传输,使用起来相对简单。UART通常包含发送器(Transmitter)和接收器(Receiver),通过两根信号线

    2024年02月10日
    浏览(32)
  • STM32CubeMX-HAL库-UART串口接收中断回调函数代码分析

            CubeMx中HAL库函数的调用不同于库函数调用,在学习CubeMx串口通信时,不理解HAL库中的回调函数是怎么被调用的,于是查看每个的定义,参考其他人写的博客,总算弄明白了HAL库中断调用与库函数不同之处。写下这篇博客一是加深自己的理解,二是希望对不理解HA

    2024年02月02日
    浏览(42)
  • (stm32之HAL库)UART工作在DMA模式要打开串口中断吗?

    最近学习了stm32(F4xx)的串口在DMA模式下的使用,期间以ST官方提供的例程进行参考学习,发现其初始化过程中是打开了UART的中断的,而且HAL库中stm32f4xx_hal_uart.c文件中的DMA模式使用说明里也有这么一句话: 即在非循环模式下(也就是发完一次数据就停止的常用模式)需要配置

    2024年02月12日
    浏览(26)
  • STM32F407ZGT6 LQFP144 uart 打印输出

    STM32F407ZGT6 +AX58100 ETHERCAT芯片软件,需要查看SSC 协议栈运行情况,UART输出状态信息。 STM32F407ZGT6 驱动库使用标准库,虽然老,但是够用。 STM32F407ZGT6 作为AX58100 的主控 STM32F407ZGT6 +AX58100 ETHERCAT 从站开发板 2.0 硬件连接图 AX58100 核心板的UART 采用UART1 PB6 PB7 PIN 2.1 UART1配置

    2024年02月09日
    浏览(54)
  • STM32串口映射printf——发送中文字符乱码

    简介         在将之前的工程使用Notepad++修改代码后,加载到现有工程中,使用串口打印输出测试串口功能,发现输出的中文字符全为乱码。对照keil设置,确保与之前工程中设置一样,莫名的就是不能输出中文字符。 解决过程         此处串口已输出为乱码,说明移植过来

    2024年02月12日
    浏览(35)
  • STM32 DMA定长发送+完成中断

    代码测试完成,可以正常运行。 DMA发送需用到串口,故需配置串口。 串口配置很简单,照抄就行,这里用的正点原子的源码。 串口配置主要分为定义句柄、开启时钟、配置IO并写入相关寄存器、配置串口模式、开启中断(本代码没有用到接收,所以无所谓)、 定义相关句柄

    2024年02月15日
    浏览(30)
  • 【STM32】HAL库 串口中断发送与接收

    【STM32】HAL库 新建MDK工程 【STM32】HAL库 串口轮询发送 使用stm32串口中断发送和中断接收 在主函数前开启中断,接受字节数为5 接受5个字节后,进入中断接收完成回调函数,重新再开启中断,并把接收到的数据返回 修改接收数组长度,改为开启串口空闲中断 接收事件回调函数

    2024年02月08日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包