本讲我们主要通过实验操作来熟悉ASCII码与通信数据之间的关系。
我们现在实现这样的功能,在电脑端上发送“十六进制”模式或“字符格式”模式的字节给单片机,数码管则显示出这些数据的十进制值,然后观察数码管上显示的数值与发送数据的关系。
1.代码
#include <reg52.h> #include <function.h>//详见第六章第8讲 #include <timer.h> //详见第八章第11讲 u8 RXDBUF;//缓存接收到的数据 void ConfigUART(u16 baud) { SCON = 0x50; //配置串口为模式1 TMOD &= 0x0F; //清零T1的控制位 TMOD |= 0x20; //配置T1为模式2 TH1 = 256 - (11059200/12/32)/baud;//计算T1重载值 TL1 = TH1; //初值等于重载值 ET1 = 0; //禁止T1中断 ES = 1; //使能串口中断 TR1 = 1; //启动T1 } void main() { LED_Init(); //初始化LED硬件模块 EA = 1; //闭合总中断开关 ConfigUART(9600); TIM0_Init(1000,0); //定时1ms,用来刷新数码管显示,定时精度要求不高可不微调 while(1) { ShowNumber(RXDBUF); } } void TIM0_IRQHandler() interrupt 1 { TH0 = T0RH; //重新加载重载值 TL0 = T0RL; SEG_Scan(); } void InterruptUART() interrupt 4 { if (RI) //RI等于1就满足if条件语句,意为接收到字节 { RI = 0; //手动清零接收中断标志位 RXDBUF = SBUF; //接收到的数据保存到接收缓存变量中 SBUF = RXDBUF; //接收到的数据又直接发回,叫作-"echo", //用以提示用户输入的信息是否已正确接收 } if (TI) //TI等于1满足if条件语句,意为字节发送完毕 { TI = 0; //手动清零发送中断标志位 } }
2.实验观察分析
在发送窗口和接收窗口都选“十六进制”模式,电脑端发送一个8的数据(也就是0x08)的字节给单片机,然后单片机会发送回来这个数据给电脑端显示在窗口中。
此时开发板上的数码管显示的是8。
接着我们在电脑端发送的是10,这是0x10,不要与十进制的10混淆。
数码管显示的是16,所以发送的数据用十进制显示在数码管上是正确的。
接着我们切换到“字符格式”模式下发送字符“A”。
数码管显示的是65,电脑端接收到单片机发送回来的数据是0x41,也就是十进制下的65。
找到ASCII表,字符“A”对应的数刚好是65。
如果把电脑端接收窗口改为“字符格式”显示,那么显示的内容就跟发送窗口的字符一样了。
剩下的留给大家自己思考。
3.注意
如果我们在电脑端发送窗口输入一串字符比如“ABCD123”点击发送给单片机,如果我们看到的是下面这个现象
那么结合以下的程序代码分析
RXDBUF = SBUF;
SBUF = RXDBUF;
也就是电脑端先发送字符“A”给单片机,单片机马上发送回字符“A”给电脑端,接着电脑端又发送字符“B”,如此执行下去,直到发送完最后一个字符“3”。
这些发送和接收过程是非常快的,因为单片机接收缓存区SBUF每次只能暂存一个字节,所以前面6个字节都会很快被替换,导致数码管在一瞬间里只显示字符“3”的ASCII码值51。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程