关于stm32中串口重定向问题详解(找个时间好好理解下)

2023-05-16

usart这部分代码我也是从网上copy出来的,一下是作者的解释:
简单地说:想在mdk 中用printf,需要同时重定义fputc函数和避免使用semihosting(半主机模式), 
标准库函数的默认输出设备是显示器,要实现在串口或LCD输出,必须重定义标准库函数里调用的与输出设备相关的函数. 
例如:printf输出到串口,需要将fputc里面的输出指向串口(重定向),方法如下: 
#ifdef __GNUC__ 
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf 
     set to 'Yes') calls __io_putchar() */ 
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) 
#else 
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) 
#endif /* __GNUC__ */ 
PUTCHAR_PROTOTYPE 

 /* Place your implementation of fputc here */ 
 /* e.g. write a character to the USART */ 
 USART_SendData(USART1, (uint8_t) ch); 
 /* Loop until the end of transmission */ 
 while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); 
 return ch; 

因printf()之类的函数,使用了半主机模式。使用标准库会导致程序无法运行,以下是解决方法: 
方法1.使用微库,因为使用微库的话,不会使用半主机模式. 
方法2.仍然使用标准库,在主程序添加下面代码: 
#pragma import(__use_no_semihosting)  
_sys_exit(int x)  
{  
x = x;  
}  
struct __FILE  
{  
int handle;  
/* Whatever you require here. If the only file you are using is */  
/* standard output using printf() for debugging, no file handling */  
/* is required. */  
};  
/* FILE is typedef’ d in stdio.h. */  
FILE __stdout; 
如果使用的是MDK,请在工程属性的“Target“-》”Code Generation“中勾选”Use MicroLIB;今天参考了一下论坛,使用微库可以很好的解决这个问题。 
2.另一种方法:(其实大同小异)   
需要添加以下代码  
(论坛里应该有完整介绍这个的帖子,但是我没搜到,也许是沉了。) 
#pragma import(__use_no_semihosting)   
/******************************************************************************   
*标准库需要的支持函数   
******************************************************************************/   
struct __FILE   
{   
int handle;   
/* Whatever you require here. If the only file you are using is */   
/* standard output using printf() for debugging, no file handling */   
/* is required. */   
};   
/* FILE is typedef’ d in stdio.h. */   
FILE __stdout;  

/// <summary>   
/// 定义_sys_exit()以避免使用半主机模式   
/// </summary>   
/// <param name="x"></param>   
/// <returns></returns>   
_sys_exit(int x)   
{   
x = x;   
}  

 

int fputc(int ch, FILE *f)  
{  
    //USART_SendData(USART1, (u8) ch);  
    USART1->DR = (u8) ch;  
      
    /* Loop until the end of transmission */  
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) 
    {  
    } 

    return ch;  
}  
semihosting的作用,介绍如下  
Semihosting is a mechanism for ARM targets to communicate input/output requests  
from application code to a host computer running a debugger. This mechanism could be  
used, for example, to allow functions in the C library, such as printf() and scanf(), to use the screen and keyboard of the host rather than having a screen and keyboard on the target system.  
This is useful because development hardware often does not have all the input and  
output facilities of the final system. Semihosting allows the host computer to provide these facilities.  
Semihosting is implemented by a set of defined software interrupt (SWI) operations.  
The application invokes the appropriate SWI and the debug agent then handles the SWI  
exception. The debug agent provides the required communication with the host.  
In many cases, the semihosting SWI will be invoked by code within library functions. The application can also invoke the semihosting SWI directly. Refer to the C library descriptions in the ADS Compilers and Libraries Guide for more information on support for semihosting in the ARM C library.  
 按我的理解,这个模式是用来调试的,通过仿真器,使用主机的输入输出代替单片机自己的,也就是说即便单片机没有输出口也能printf到电脑上。反过来,由于这个模式更改了printf()等的实现方式,输入输出就不走单片机的外设了,所以只重定义fputc不起作用。 

用代码关闭此模式后,需要同时更新一下__stdout 和__stdin 的定义,所以有后面的语句。 

以上仅为个人理解,如有错误请指正。 


另外,勾选microlib之后,也许编译的时候就不把开启semihosting的文件包进去了,所以没事。

C库函数重定向: 
用户能定义自己的C语言库函数,连接器在连接时自动使用这些新的功能函数。这个过程叫做重定向C语言库函数,如下图所示。 
举例来说,用户有一个I/O设备(如UART)。本来库函数fputc()是把字符输出到调试器控制窗口中去的,但用户把输出设备改成了UART端口,这样一来,所有基于fputc()函数的printf()系列函数输出都被重定向到UART端口上去了。 
下面是实现fputc()重定向的一个例子: 
externvoidsendchar(char*ch); 
intfputc(intch,FILE*f) 
{/*e.g.writeacharactertoanUART*/ 
chartempch=ch; 
sendchar(&tempch); 
returnch; 
} 
这个例子简单地将输入字符重新定向到另一个函数sendchar(),sendchar()假定是个另外定义的串口输出函数。在这里,fputc()就似乎目标硬件和标准C库函数之间的一个抽象层。

第二个问题,路径:D:\Keil3.80\ARM\Examples\ST\STM32F10xFWLib\Examples
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于stm32中串口重定向问题详解(找个时间好好理解下) 的相关文章

  • stm32的HAL库函数flash无法写入的问题

    记录一下对flash编程操作时出现的问题以及解决办法 问题 在使用HAL库中的HAL FLASH Program uint32 t TypeProgram uint32 t Address uint64 t Data 函数时发现总是没办法写
  • STM32在Debug时程序运行时间不对,Debug时定时器中断每次进入断点时间不对,定时器一开启就进入中断的解决办法

    一 Debug时程序时间不对解决办法 1 点击魔术棒 2 点击Debug 点击Settings 3 点击Trace 在Core Clock里修改为你的系统时钟 二 Debug时定时器中断每次进入断点时间不对 在Debug时 程序停下来 定时
  • 如何更改闪存的起始地址?

    我正在使用 STM32F746ZG 和 FreeRTOS Flash的起始地址是0x08000000 但我想把它改成0x08040000 我通过谷歌搜索了这个问题 但没有找到解决方案 我更改了链接器脚本 如下所示 MEMORY RAM xr
  • 140-基于stm32单片机智能晾衣杆控制系统Proteus仿真+源程序

    资料编号 140 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 光敏传感器 蜂鸣器 LED灯 制作一个基于stm32单片机智能晾衣杆控制系统Proteus仿真 2 通过光敏传感器
  • 136-基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真+源程序

    资料编号 136 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 蜂鸣器 制作一个基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真 2 通过DHT11传感器检测当前温湿度 并且显示到L
  • 135-基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真+源程序

    资料编号 135 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 电机 超声波传感器 制作一个基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真 2 通过DHT11传感器检测当前
  • STM32F4 通过软复位跳转到引导加载程序,无需 BOOT0 和 BOOT1 引脚

    我问这个问题是因为可以在这里找到类似问题的答案 通过应用程序跳转到 STM32 中的引导加载程序 即从用户闪存在引导模式下使用引导 0 和引导 1 引脚 用户 JF002 JF002回答 当我想跳转到引导加载程序时 我在其中一个备份寄存器中
  • 匹配 STM32F0 和 zlib 中的 CRC32

    我正在研究运行 Linux 的计算机和 STM32F0 之间的通信链路 我想对我的数据包使用某种错误检测 并且由于 STM32F0 有 CRC32 硬件 并且我在 Linux 上有带有 CRC32 的 zlib 所以我认为在我的项目中使用
  • STM32F103概要

    The STM32F103x4 STM32F103x6 STM32F103xC STM32F103xD and STM32F103xE are a drop in replacement for STM32F103x8 B medium d
  • 擦除后无法写入闪存

    所以我不能在擦除后直接写入内部闪存 如果写操作之前没有擦除操作 那么我可以 有什么想法吗 编程函数返回 成功写入 值 但查看内存时 没有写入任何数据 这是代码 uint32 t pageAddress 0x08008000 uint16 t
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • STM32F4XX的12位ADC采集数值超过4096&右对齐模式设置失败

    文章目录 一 前言 二 问题1 数值超过4096 三 问题1的排错过程 四 问题2 右对齐模式设置失败 五 问题2的解决方法 5 1 将ADC ExternalTrigConv设置为0 5 2 使用ADC StructInit 函数 一 前
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • STM32H5 Nucleo-144 board开箱

    文章目录 开发板资料下载 目标 点亮LD1 绿 LD2 黄 和LD3 红 三个LED灯 开箱过程 博主使用的是STM32CubeMX配置生成代码 具体操作如下 打开STM32CubeMX File gt New project 选择开发板型
  • systick定时器

    systick定时器 文章目录 前言 一 前期疑惑 二 解答 1 关于systick是阻塞的吗 2 非阻塞 三 软件编写 总结 前言 这边记录systick相关知识点 一 前期疑惑 在学习systick志气啊 其实对于systick还是一脸
  • 通过JTAG恢复STM32 MCU磨掉的标记

    我有一块可能带有 STM32 MCU 的板 我想为该板制作定制固件 因为库存板有很多问题 不幸的是 电路板制造商很友善地磨掉了所有标记 有没有办法通过 jtag 获取设备 系列 ID 并将其交叉引用到型号 我能找到的一切都是关于获取芯片的唯
  • 嵌入式 C++11 代码 — 我需要 volatile 吗?

    采用 Cortex M3 MCU STM32F1 的嵌入式设备 它具有嵌入式闪存 64K MCU固件可以在运行时重新编程闪存扇区 这是由闪存控制器 FMC 寄存器完成的 所以它不像a b那么简单 FMC 获取缓冲区指针并将数据刻录到某个闪存

随机推荐

  • AutoSar之微控制器抽象层MCAL

    微控制器抽象层位于AUTOSAR BSW的最底层 xff0c 包含内部驱动 xff0c 可直接访问微控制器和外设芯片 从具体应用来看 xff0c MCAL主要包括微控制器驱动 存储器驱动 通信驱动和输入输出驱动四个部分 xff0c 各部分又
  • 【高效】【IDE】VSCode 插件

    Docuemnt This 加注释文档 选中你的函数名字 xff0c 按两次ctrl 43 alt 43 D xff1b Better Comments 注释高亮 Live Server 实时预览页面 Live Server会启动一个本地服
  • 嵌入式软件算法优化

    嵌入式软件算法优化 一 算法优化原则二 算法优化方法1 系统优化2 算法优化 xff08 需要理解算法原理 xff09 3 代码优化4 使用硬件资源 xff08 需要熟悉芯片架构及资源 xff09 5 汇编 一 算法优化原则 xff08 1
  • CAN总线原理简介

    一 xff0e CAN总线简介 xff1a 是一种串行通信协议 xff0c 能有效的支持具有很高安全等级的分布实时控制应用范围十分广泛 xff0c 从高速网络到低价位的多路接线都可以使用CAN主要运用于汽车电子航天等行业 xff0c 使用C
  • freeRTOS 任务切换

    使用PendSV实现任务切换 上下文切换被触发的场合可以是 xff1a 1 执行一个系统调用 2 系统滴答定时器 SysTick 中断 br PendSV中断服务函数 br TaskSelectHighestPrior的两种方法 br br
  • make -j 参数加快编译效率

    对于大型项目 xff0c 在使用cmake控制编译时 xff0c 仅仅执行make指令效率较低 xff0c 使用make j后面跟一个数字 xff0c 比如make j4 make j6 make j14等 含义是 让make最多允许n个编
  • cmake中add_dependencies的基本作用

    假设我们需要生成一个可执行文件 该文件生成需要链接a so b so c so d so四个动态库 正常来讲 我们一把只需要以下两条指令即可 ADD EXECUTABLE span class token punctuation span
  • 命令行给cmake传递参数

    我们期望在编译前将一些信息缓存起来 然后用CMakeLists txt进行构建时 希望可以访问之前缓存给cmake的变量 比如我们希望缓存TARGET CPU 并且他的值为X86 那么我们可以在命令行或者脚本中执行一下操作 cmake DT
  • 在CMakeLists.txt如何执行脚本?execute_process

    execute process span class token punctuation span COMMAND span class token function bash span SCRIPT PATH name sh WORK P
  • C++运算符重载中有些方法为什么需要定义为友元函数

    C 43 43 提供运算符重载主要目的 xff1a 希望对象之间的运算看起来可以和编译器内置类型一样丝滑 xff1b 相当于是告知编译器 xff0c 类对象之间运算应该如何去做处理 通过实现一个复数类 xff0c 来阐述本文章的主题 xff
  • linux网络编程之socket,bind,listen,connect,accept

    socket span class token macro property span class token directive hash span span class token directive keyword include s
  • Linux网络发送和接收内核缓冲区大小的设置

    socket属性 xff1a SO SNDBUF 发送缓冲区 SO SNDBUF Sets or gets the maximum socket send buffer span class token keyword in span by
  • docker查看运行时容器的IP地址

    使用inspect来查看容器的信息 span class token function docker span inspect span class token punctuation span docker name span class
  • python基础梳理(一)

    一 python程序的组成 表达式 xff1a 建立并且处理数据对象且能返回数据对象的引用关系 示例 xff1a 1 43 2 系统会产生1和2俩个对象 xff0c 并且进行处理生产对象3 xff0c 将对象3返回回去 二 核心的数字类型
  • 串级PID结构及参数调整见解

    在设计控制系统中 xff0c 常用的控制算法为PID xff0c 即比例 积分 微分控制器 能够实现对控制对象的物理特性的控制 xff0c 以期达到特定的运行效果 此外由于PID控制器的灵活特性 xff0c 可以与其它控制算法进行灵活的组合
  • freeRTOS 开启关闭调度器、挂起恢复调度器、vTaskStepTick

    1 开启调度器 br vTaskStartScheduler 43 vPortSetupTimerInterrupt 设置systick xff0c 初始化低功耗运行系统补偿时间 br 43 xPortStartScheduler 43 p
  • 通过Flask框架封装Tushare获取的日线股票数据

    概要介绍 概要介绍 xff08 TuShare id 282782 xff09 当我们需要进行量化交易分析 xff0c 或者通过代码进行股票的数据计算 xff0c 研究金融时 xff0c 我们需要获取最基本的股票价格 xff0c 开盘价收盘
  • linux系统安装硬盘分区建议

    笔者使用linux也很长时间了 xff0c 但总有在使用一段时间之后感觉系统分区不是很合理 xff0c 这里就算是给自己总结一下 xff0c 也跟大家一起分享吧 一 常见挂载点的情况说明 一般来说 xff0c 在linux系统中都有最少两个
  • Python3.4简单爬虫实现之抓取糗事百科段子

    网上的python教程大都是2 X版本的 xff0c python2 X和python3 X相比较改动比较大 xff0c 好多库的用法不太一样 xff0c 我安装的是3 4 1 xff0c 就用3 4 1实现一下网页内容抓取 首先是库 xf
  • 关于stm32中串口重定向问题详解(找个时间好好理解下)

    usart这部分代码我也是从网上copy出来的 xff0c 一下是作者的解释 xff1a 简单地说 xff1a 想在mdk 中用printf xff0c 需要同时重定义fputc函数和避免使用semihosting 半主机模式 xff09