keil使用虚拟的调试串口给调试助手发送数据

1下载: https://sourceforge.net/projects/com0com/

2安装com0com

3安装完成,打开设备管理器,如下图所示,没有黄色感叹号

安装之后有人会出现带黄色感叹号这种,操作系统设置-高级启动-禁用强制驱动程序签名就可以,或者找其他博主的解决方案,因为我的电脑没出现,所以没办法验证方法的可行性。

在我的电脑里面看到com7,com8

4打开两个调试助手,第一个选择com7,第二个选择com8

5第一个调试助手发送,第二个调试助手收到消息

6关掉两个调试助手

7创建一个空文件usart_debug.ini-->输入内容:

MODE COM8 9600, 0, 8, 1

ASSIGN COM8 <S1IN> S1OUT

8打开keil

9点击魔法棒-->Debug-->(*)Use Simulator-->\*Limit Speed to Real-Time

\*Load Speed to Real-Time \*Run to main()

-->Initialization File:...,点击三个点-->选择usart_debug.ini-->OK

10假设你原来重定向的文件名usart.c,注释掉原来的内容,添加下面的内容,如下:

#if 0

extern UART_HandleTypeDef huart2;

#define DEBUG_SERIAL_HANDLE huart2

#define DEBUG_SERIAL_NUMBER USART2

//重定向

int fputc(int ch, FILE *f)

{

HAL_UART_Transmit(&DEBUG_SERIAL_HANDLE, (uint8_t *)&ch, 1, 1000);

return ch;

}

int fgetc(FILE *f)

{

uint8_t ch;

while(HAL_UART_Receive(&DEBUG_SERIAL_HANDLE, (uint8_t *)&ch, 1, 0xffff) != HAL_OK){}

return (int)ch;

}

#endif

#include <stdio.h>

#include <string.h>

// 1. 彻底关闭半主机模式(兼容新旧编译器)

#define __NO_SEMIHOSTING 1

#pragma import(__use_no_semihosting)

// 2. 定义标准输入输出流(输入必须定义__stdin)

struct __FILE {

int handle;

};

FILE __stdout; // 标准输出(若需同时输出可保留)

FILE __stdin; // 标准输入(核心:对应输入函数)

// 3. 补充半主机相关空函数(避免链接错误)

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

int _sys_open(const char *name, int mode) { return 0; }

void _ttywrch(int ch) { (void)ch; }

// 4. 重定向fputc(可选:若需同时输出调试信息,保留此函数)

int fputc(int ch, FILE *f) {

volatile uint32_t *USART1_SR = (volatile uint32_t *)(0x40013800);

volatile uint8_t *USART1_DR = (volatile uint8_t *)(0x40013804);

uint32_t timeout = 100000;

while ( ((*USART1_SR) & 0x40) == 0 && timeout-- > 0 );

if (timeout == 0) return -1;

*USART1_DR = (uint8_t)ch;

return ch;

}

// 5. 核心:重定向fgetc函数(从Keil内部UART #1读取字符,对应真实串口数据)

int fgetc(FILE *f) {

// 明确定义USART1寄存器地址(STM32F103 USART1)

volatile uint32_t *USART1_SR = (volatile uint32_t *)(0x40013800); // 状态寄存器

volatile uint8_t *USART1_DR = (volatile uint8_t *)(0x40013804); // 数据寄存器

uint32_t timeout = 500000; // 延长超时,确保能捕获到输入数据

uint8_t recv_ch = 0;

// 等待RXNE位(bit5)置1:表示接收数据寄存器非空(有数据可读)

while ( ((*USART1_SR) & 0x20) == 0 && timeout-- > 0 ) {

// 空循环等待,直到收到数据或超时

}

// 若超时,返回0(可自定义错误标识);若收到数据,读取DR寄存器

if (timeout > 0) {

recv_ch = *USART1_DR; // 读取接收到的字符

// 可选:回显字符(发送到输出窗口,便于确认接收成功)

fputc(recv_ch, stdout);

}

return (int)recv_ch;

}

11打开调试助手,选择com7

12keil进入调试状态,执行printf函数,发现已经输出到调试助手了。

相关推荐
桀人5 分钟前
认识AT24C02
stm32·单片机·嵌入式硬件
国科安芯1 小时前
星间激光通信终端CANFD控制网络的时延确定性与辐射可靠性
网络·嵌入式硬件·信息与通信·canfd·低轨卫星·商业航天·抗辐射
一直C1 小时前
嵌入式 Linux 驱动开发学习笔记:内核定时器、platform 总线与 I²C 驱动
linux·驱动开发·嵌入式硬件·学习·imx6ull
传感器与混合集成电路2 小时前
150MHz主频、8路DAC与6路PWM:JLH221360伺服控制SIP解析
嵌入式硬件
comyccccc2 小时前
STM32PID控制板设计全解析学习笔记
单片机·嵌入式硬件
碧海银沙音频科技研究院3 小时前
实现炬芯ATS308X的usb cdc 串口IAP 固件升级功能实现
人工智能·嵌入式硬件·深度学习·算法
恒锐丰科技林技术员3 小时前
EG1160 高压半桥驱动芯片:高压功率变换的实用驱动方案
经验分享·嵌入式硬件·硬件工程
智购科技自动售卖机厂家4 小时前
双摄像头方案F1-score只有0.85,排查发现是上下视角的融合逻辑写反了~YH
python·单片机·嵌入式硬件·算法·eclipse
llilian_164 小时前
脉冲时间间隔及计数如何精准测试?
功能测试·嵌入式硬件·51单片机·软件工程
路上有只喵5 小时前
认识元器件 · 牛角型电解电容· 规格书解读
嵌入式硬件