6 8051使用Keil模拟器和调试输出窗口实现串口收发回环
admin
2024-01-18 07:53:24
0
  • 本仓库相关网址:
    CSDN文章地址
    Gitee工程和源码地址

  • 相关仓库:
    嵌入式整体介绍,里面也描述了部分8051的内容:
    才鲸嵌入式 / 嵌入式知识图谱WiKi
    C语言框架讲解,让你对C语言要学哪些东西有一个完整的了解:
    embedded_programming_skills/ 0_doc / 02-C语言框架讲解.md

6)Keil调试输出窗口串口回环

  • 本工程主要演示使用Keil创建一个默认工程,然后添加串口0的回环收发用例,在Keil的调试串口进行串口收发,并且可以使用虚拟串口,通过SSOM32与Keil通信来进行串口收发。

  • 工程文件:本文档同级目录/06_uart0_loopback/06_uart0_loopback.uvproj

  • 将Keil的UART #1调试输出串口与SSCOM32等串口软件绑定的话,需要用到VSPD软件。

  • 参考网址:

    • Keil实例仿真AT89C51串口UART收发数据(附程序)
    • keil MDK 中使用虚拟串口调试串口
    • 虚拟串口 VSPD 的使用
  • 代码展示:

/******************************************************************************** \brief	进行串口0的回环输入输出* \details	可以通过Keil的UART #1调试串口直接输出串口信息和接收串口的输入,*			也可以通过VSPD虚拟串口软件与PC上的SSCOM32等串口软件进行绑定,通过*			串口软件收发信息。* \attention	Keil UART #1和SSCOM32窗口输入的行尾是\r,不是\r\n,*				但是输出又是以\r\n来处理的。Keil模拟器模式下,*				晶振不管设置为多少,UART0不管是否初始化,设置多少波特率,Keil*				UART #1调试串口的收发总是115200的波特率。* \author	将狼才鲸* \date	2022-10-30* \note	参考网址:*			[Keil实例仿真AT89C51串口UART收发数据(附程序)]*			(https://blog.csdn.net/tj_nonstoper/article/details/124271543)*			[keil MDK 中使用虚拟串口调试串口]*			(https://blog.csdn.net/NICHUN12345/article/details/124423615)*			[虚拟串口 VSPD 的使用]*			(https://blog.csdn.net/qq_17351161/article/details/89607458)******************************************************************************//********************************** 头文件 ************************************/
#include 	/* 8051通用的寄存器定义 *//********************************** 宏定义 ************************************/
#define CHAR_LOOPBACK		/* 收到一个字符就返回一个字符 */
//#define STRING_LOOPBACK	/* 收到一行后再返回一行,如果接收buffer满则先返回整个buffer数据 */
/* Keil使用自带的模拟器运行时,输入的换行是\r,但输出换行却是\r\n */
#define FIX_KEIL_EMULATOR_AND_SSCOM32_UART_LINE_FEED_ISSUE#define BUF_MAX_SIZE 16		/* 设置短一点,即使没输入正确的换行符,也能及时有数据返回 *//********************************* 全局变量 ***********************************/
static char rcv_buf[BUF_MAX_SIZE] = {0};	/* 完整的一行接收缓存 */
static int rcv_cnt = 0;	/* 接收的字节数 */
static char rcv_str_end_flag = 0; /* 0 is false, !0 is true */static void uart0_init(void);
static void send_str(char *str);
static void send_char(char c);//如果要使用printf,需要进行putchar输出重定义
//不使用printf,直接往串口写数据也能输出到UART #1
///**
// * \brief		printf重定向的函数,这里重定向到串口0
// * \param[in]	c	承接printf中传入的一个字符
// * \note		这里的函数注释格式是Doxygen,有兴趣的可以自行去了解
// * \return		正常时返回c,错误时返回错误码
// */
//char putchar(char c)
//{
//	ES = 0;				/* 关串口中断 */
//	SBUF = c;           
//	while (TI != 1);	/* 等待发送成功,产生发送中断 */
//	TI = 0;				/* 清除发送中断标志 */
//	ES = 1;				/* 开串口中断 *///	return c;
//}/********************************* 接口函数 ***********************************/
/*** \brief	入口函数*/
int main()
{/* 1. 串口初始化 */uart0_init();/* 2. 打印提示信息 */send_str("====\r\n");send_str("| Check your terminal line end format.\r\n");send_str("| \r \\r \r");send_str("| \n \\n \n");send_str("| \n\r \\n\\r \n\r");send_str("| \r\n \\r\\n \r\n");send_str("====\r\n\r\n");send_str("====\r\n");
#ifdef STRING_LOOPBACKsend_str("Now is string loopback mode\r\n");send_str("Please input string, and end with \\r or \\n.\r\n");
#elsesend_str("Now is char loopback mode\r\n");send_str("Please input char\r\n");
#endif/* 3. 打印从串口中断收到的信息 */while (1) {  	 if (rcv_str_end_flag) {/* 如果收到数据,则进行回环输出 */rcv_str_end_flag = 0;
#ifdef STRING_LOOPBACKsend_str("Your Input: ");send_str(rcv_buf);  /* 把接收到的字符串发送回去 */
#else/* 防止有人不知道串口中断输入是没有回显的,原样输出会以为只是自己的输入 */send_char('>');send_char(rcv_buf[0]);
#	ifdef FIX_KEIL_EMULATOR_AND_SSCOM32_UART_LINE_FEED_ISSUEif (rcv_buf[0] == '\r')send_char('\n');
#	endifsend_char(' ');
#endifrcv_buf[0] = '\0'; /* 清空字符串,直接写个字符串结尾 */}}
}	/********************************* 私有函数 ***********************************/
/*** \brief		串口0初始化* \attention	Keil模拟器模式时可以不初始化,即使配置了参数,也始终以115200波特率输出* \note		不初始化的话能输出数据,但是进不了接收中断,接收不了信息*/
static void uart0_init(void)
{/* 串口参数配置函数,这里配置为9600波特率,1位停止位,8位数据位,无校验 */TMOD = 0x20;  /* Timer1以定时模式工作在方式2:8位常数自动装入定时器/计数器 */SCON = 0x40;  /* SM0 = 0,SM1 = 1,方式1,10位UART "0 D0~D7 1",波特率可变 */REN  = 1;     /* 允许串口接收数据位 *//** \warning 不管设置多少波特率,Keil模拟器在UART #1中的收发始终是115200 */TH1  = 0xFD;  /* 9600波特率:晶振的频率/(12 * (256 - 初值)) = 波特率 * 32 */TL1  = 0xFD;  /* 方式2的TH1,TL1是相等的,TL1自动重装TH1初值 */PCON = 0x00;  /* SMOD = 0波特率不加倍 */IE   = 0x90;  /* 允许总中断,允许串口中断,禁止其他中断 */PS   = 0;     /* 设置串行口中断优先级 */TR1  = 1;     /* 当GATE=0,TR1置“1” 启动定时器1 */
}/*** \brief		发送一个字符* \param[in]	c	发送的字符*/
static void send_char(char c)
{SBUF = c;		/* SBUF是指串行口同地址的两个缓冲寄存器,一个是发送寄存器,一个是接收寄存器,通过读和写来区分 */       while (!TI);		/* 等待一个字符发送完毕 */TI = 0;			/* TI软件清零,等待下一次发送后的置位 */
}/*** \brief		发送一个字符串* \param[in]	str	要发送的字符串指针*/
static void send_str(char *str)
{ES = 0; /* 发送前关闭串口中断,以防发送完每个字符都没必要地进入中断程序 */while (*str != '\0')		/* 持续发送直到字符串结尾 */send_char(*str++);	/* 先取值再自增 */ES = 1; /* 发送完打开串口中断 */
}/*** \brief	串口0中断处理函数* \note	中断默认优先级:0外部中断0 > 1定时/计数器0 > 2外部中断1 > 3定时/计数器1 > 4串行中断*/
void uart0_irq(void) interrupt 4 
{if (RI == 1) {/* RI置位表示一帧数据接收完毕,中断处理后RI必须用软件清0 */RI = 0; /* 中断标志位清零 */ES = 0; /* 关闭串口中断,防止下面程序执行时被打断,防止中断嵌套 */
#ifdef STRING_LOOPBACKif (rcv_cnt < BUF_MAX_SIZE - 2) {/* 接收缓冲区未溢出 */rcv_buf[rcv_cnt] = SBUF; /* 存放1个字节 */if (rcv_buf[rcv_cnt] == '\r' || rcv_buf[rcv_cnt] == '\n') {/* 如果接收到结束符(当前Keil UART #1和SSCOM都是\r) */rcv_str_end_flag = 1;	/* 接收了完整的字符串 */
#ifdef FIX_KEIL_EMULATOR_AND_SSCOM32_UART_LINE_FEED_ISSUErcv_buf[rcv_cnt - 1] = '\n';
#endifrcv_buf[rcv_cnt] = '\0';	/* 在字符串末尾补字符串结束 */rcv_cnt = 0; /* 接收长度清0 */} else {rcv_cnt++;}} else {/* 接收缓冲区溢出 */rcv_str_end_flag = 1;rcv_buf[rcv_cnt] = '\0';rcv_cnt = 0;}
#elsercv_buf[0] = SBUF; /* 存放1个字节 */rcv_str_end_flag = 1;
#endifES = 1;	/* 中断处理完重新打开串口中断 */}
}

相关内容

热门资讯

电视安卓系统哪个品牌好,哪家品... 你有没有想过,家里的电视是不是该升级换代了呢?现在市面上电视品牌琳琅满目,各种操作系统也是让人眼花缭...
安卓会员管理系统怎么用,提升服... 你有没有想过,手机里那些你爱不释手的APP,背后其实有个强大的会员管理系统在默默支持呢?没错,就是那...
安卓系统软件使用技巧,解锁软件... 你有没有发现,用安卓手机的时候,总有一些小技巧能让你玩得更溜?别小看了这些小细节,它们可是能让你的手...
安卓系统提示音替换 你知道吗?手机里那个时不时响起的提示音,有时候真的能让人心情大好,有时候又让人抓狂不已。今天,就让我...
安卓开机不了系统更新 手机突然开不了机,系统更新还卡在那里,这可真是让人头疼的问题啊!你是不是也遇到了这种情况?别急,今天...
安卓系统中微信视频,安卓系统下... 你有没有发现,现在用手机聊天,视频通话简直成了标配!尤其是咱们安卓系统的小伙伴们,微信视频功能更是用...
安卓系统是服务器,服务器端的智... 你知道吗?在科技的世界里,安卓系统可是个超级明星呢!它不仅仅是个手机操作系统,竟然还能成为服务器的得...
pc电脑安卓系统下载软件,轻松... 你有没有想过,你的PC电脑上安装了安卓系统,是不是瞬间觉得世界都大不一样了呢?没错,就是那种“一机在...
电影院购票系统安卓,便捷观影新... 你有没有想过,在繁忙的生活中,一部好电影就像是一剂强心针,能瞬间让你放松心情?而我今天要和你分享的,...
安卓系统可以写程序? 你有没有想过,安卓系统竟然也能写程序呢?没错,你没听错!这个我们日常使用的智能手机操作系统,竟然有着...
安卓系统架构书籍推荐,权威书籍... 你有没有想过,想要深入了解安卓系统架构,却不知道从何下手?别急,今天我就要给你推荐几本超级实用的书籍...
安卓系统看到的炸弹,技术解析与... 安卓系统看到的炸弹——揭秘手机中的隐形威胁在数字化时代,智能手机已经成为我们生活中不可或缺的一部分。...
鸿蒙系统有安卓文件,畅享多平台... 你知道吗?最近在科技圈里,有个大新闻可是闹得沸沸扬扬的,那就是鸿蒙系统竟然有了安卓文件!是不是觉得有...
宝马安卓车机系统切换,驾驭未来... 你有没有发现,现在的汽车越来越智能了?尤其是那些豪华品牌,比如宝马,它们的内饰里那个大屏幕,简直就像...
p30退回安卓系统 你有没有听说最近P30的用户们都在忙活一件大事?没错,就是他们的手机要退回安卓系统啦!这可不是一个简...
oppoa57安卓原生系统,原... 你有没有发现,最近OPPO A57这款手机在安卓原生系统上的表现真是让人眼前一亮呢?今天,就让我带你...
安卓系统输入法联想,安卓系统输... 你有没有发现,手机上的输入法真的是个神奇的小助手呢?尤其是安卓系统的输入法,简直就是智能生活的点睛之...
怎么进入安卓刷机系统,安卓刷机... 亲爱的手机控们,你是否曾对安卓手机的刷机系统充满好奇?想要解锁手机潜能,体验全新的系统魅力?别急,今...
安卓系统程序有病毒 你知道吗?在这个数字化时代,手机已经成了我们生活中不可或缺的好伙伴。但是,你知道吗?即使是安卓系统,...
奥迪中控安卓系统下载,畅享智能... 你有没有发现,现在汽车的中控系统越来越智能了?尤其是奥迪这种豪华品牌,他们的中控系统简直就是科技与艺...