04 使用Keil模拟器和Debug (printf) Viewer窗口实现scanf输入,并进行串口收发回环,无需fgetc重定向

作者将狼才鲸
创建日期2022-11-05

Gitee工程和源码地址:才鲸嵌入式 / ARM-Cortex-M3从汇编到C_从Boot到应用教程
CSDN文章阅读地址:ARM Cortex-M3从汇编到C,从Boot到应用的教程
Bilibili视频讲解地址(待完成):才鲸嵌入式

4)04_Uart_loopback

  • 使用Keil模拟器和Debug (printf) Viewer窗口实现scanf输入,并进行串口收发回环。

    • 工程和源码在本文档同级目录\src\04_Uart_loopback\下
    • Keil配置的Debug栏要选择Use Simulator,不能选择默认的ULINK2/ME Cortex Debugger
    • 创建工程方法:在Keil上新建一个工程,勾选CMSIS中的CORE,勾选Device中的Startup,一定要勾选Compiler–IO下的STDEER、STDIN、STDOUT,并将右侧的Breakpoint都改为ITM;不用重定向fgetc和fputc,直接使用scanf和printf即可。
    • 如果有报错Error: L6218E: Undefined symbol Image A R M L I B S T A C K ARM_LIB_STACK ARMLIBSTACKZI$$Limit Not enough information to list image,则按网址中的描述配置一下链接器.sct文件路径。
    • 在国内和国外的网站上都没找到介绍使用fgetc输入重定义,用scanf从Keil Debug (printf) Viewer窗口获取数据的方法,最终从Keil官网找到了。
    • 这是有效的方法:µVision User’s Guide - Debug (printf) Viewer
    • 在网上还找到了使用ITM_CheckChar()和ITM_ReceiveChar()来实现fgetc,但需要需要添加core_cm3.h头文件和stm32f1xx.h头文件,而我直接使用的是M3核,并没有stm32的头文件,所以这个方法失败。
    • MDK的Debug (printf) Viewer窗口不像C51的UART #1窗口,UART #1在网上能很容易的找到教程,通过VSD虚拟串口软件,将Keil C51的调试串口和电脑的虚拟串口相绑定,这样就能使用SSCOM或者PUTTY等串口软件收发二进制数据了;Debug (printf) Viewer窗口我还没找到绑定的方法,所以当前scanf不能获取到16进制和int型的数据,只能获取到字符和字符串,但是这对使用模拟器仿真程序来说够用了。
  • 实现调试终端串口收发的主要是Keil的配置,所以工程里就只有一个main.c文件,里面的内容也很简单。

  • main.c

/******************************************************************************
 * \brief	使用Keil自带的调试窗口Debug(printf) Viewer实现串口输入输出
 * \author	将狼才鲸
 * \date	2022-11-10
 * \note	File format: UTF-8
 * \note	配置中的Debug页面勾选使用模拟器。
 *			MDK的Debug (printf) Viewer窗口不像C51的UART #1窗口,UART #1在网上能
 *			很容易的找到教程,通过VSD虚拟串口软件,将Keil C51的调试串口和电脑的
 *			虚拟串口相绑定,这样就能使用SSCOM或者PUTTY等串口软件收发二进制数据了;
 *			Debug (printf) Viewer窗口我还没找到绑定的方法,所以当前scanf不能
 *			获取到16进制和int型的数据,只能获取到字符和字符串,但是这对使用
 *			模拟器仿真程序来说够用了。
 * \note	参考网址:
 *			* 报错解决[Error: L6218E: Undefined symbol Image$$ARM_LIB_STACK$$ZI$$Limit Not enough information to list image]
 *			  (https://blog.csdn.net/qq_41200467/article/details/124958685)
 *			* 如何配置工程[µVision User's Guide - Debug (printf) Viewer]
 *			  (https://developer.arm.com/documentation/101407/0537/Debugging/Debug-Windows-and-Dialogs/Debug--printf--Viewer)
 * \warning	Keil Debug(printf) Viewer获取单个字符时有个bug,第一次输入的值获取不到,以后每次获取到的字符都是你前一次按下
 *			的字符推测因为软件模拟的中断收发实际上都是用的键盘键值,一个键由好几个字符组成,Keil TIM工具再将键值转成
 *			ASCII的单个字符,中间有点bug;但是字符串输入是正常的,不会丢数据。
 ******************************************************************************/

/********************************** 头文件 ************************************/
#include <stdio.h>

/********************************** 宏定义 ************************************/
//#define CHAR_LOOPBACK		/* 收到一个字符就返回一个字符 */
#define STRING_LOOPBACK	/* 收到一行后再返回一行,如果接收buffer满则先返回整个buffer数据 */
#define BUF_MAX_SIZE 256	/* 设置长一点,防止按回车键前数据溢出 */
/* Keil使用自带的模拟器运行时,输入的换行是\r,但输出换行却是\r\n */
#define FIX_KEIL_EMULATOR_AND_SSCOM32_UART_LINE_FEED_ISSUE

/********************************* 全局变量 ***********************************/
static char rcv_buf[BUF_MAX_SIZE] = {0};	/* 完整的一行接收缓存,输入时以回车键结尾,值为\r\n的组合 */

/********************************* 接口函数 ***********************************/
/**
 * \brief	入口函数
 */
int main()
{
	/* 1. 打印提示信息 */
	printf("====\r\n");
	printf("| Check your terminal line end format.\r\n");
	printf("| \r \\r \r");
	printf("| \n \\n \n");
	printf("| \n\r \\n\\r \n\r");
	printf("| \r\n \\r\\n \r\n");
	printf("====\r\n\r\n");

	printf("====\r\n");
#ifdef STRING_LOOPBACK
	printf("Now is string loopback mode\r\n");
	printf("Please input string, and end with 'Enter' key(value is\\r or \\n).\r\n");
#else
	printf("Now is char loopback mode\r\n");
	printf("Please input char\r\n");
#endif

	/* 3. 打印从串口中断收到的信息 */
	while (1) {
#ifdef STRING_LOOPBACK
		scanf("%s", rcv_buf);
		printf("Your Input: ");
		printf(rcv_buf);  /* 把接收到的字符串发送回去 */
#	ifdef FIX_KEIL_EMULATOR_AND_SSCOM32_UART_LINE_FEED_ISSUE
		printf("\n");
#	endif
#else
		scanf("%c", &rcv_buf[0]);
		printf(">"); /* 防止有人不知道串口中断输入是没有回显的,原样输出会以为只是自己的输入 */
		printf("%c", rcv_buf[0]);
#endif
	}

	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值