1.串口配置函数
上一讲的讲解是让大家对《手把手教你学51单片机》文档的第十一章的第一个例程的辅助理解,我们没有写单片机接收电脑端发送回来的数据字节做处理的代码。因为这些都是IO端口模拟的串口通信,由于51单片机本身集成有串口模块,所以我们使用其硬件资源即可,无需在软件方面做过多的细节描写,如有兴趣了解串口更多细节,请反复阅读《手把手教你学51单片机》文档的第十一章。
那么宋老师已经很详细地把串口的相关知识讲解清楚,我们直接模仿他的编程思想来实现我们想实现的功能即可。
串口配置函数我们直接运用宋老师的代码,这里讲解一两处配置的知识。
首先“SCON=0x50;”是让SCON寄存器的第4位和第6位都置1,其他位置0,在文档的表11-2已有讲解。
“TH1 = 256 - (11059200/12/32)/baud;”是波特率设置的计算公式,可不用深究,由于串口的使用要占用定时器1,那么定时器1的定时中断将不能使用,所以必须使“ET1=0;”禁止其产生定时中断,也就是使用了串口,那么“void
TIM1_IRQHandler() interrupt 3”将不能再出现在程序书写中。
不过呢,串口也有相应的中断函数,像ET0,ET1一样,这些都是子开关,串口中断的子开关为ES,“ES=1;”和“EA=1;”就开启了串口的中断函数。我们串口发送数据的时候会产生中断,接收到数据的时候也会产生中断,这两个瞬间我们在中断函数里需要执行相关任务。
要知道串口有动作的时候,总会有RI或者TI被置1,前者意为接收到完整的8位的数据,也就是接收到一个字节然后RI就被置1。后者意为单片机发送完一个完整的字节了,TI被置1。这些瞬间都需要我们在串口中断函数中让其清0,以备下次它们能再次被置1。
我们现在要实现的功能很简单,就是电脑端通过串口发送一个数据给单片机,这个数据被单片机接收到之后,让这个数据再加1,然后单片机再通过串口把加1后的数据发送回去给电脑端让它在窗口上显示。
2.代码
#include <reg52.h>
#include <function.h>//详见第六章第8讲
#include <timer.h> //详见第八章第11讲
u8 RXDBUF;
void ConfigUART(u16 baud)
{
SCON = 0x50;
TMOD &= 0x0F;
TMOD |= 0x20;
TH1 = 256 - (11059200/12/32)/baud;
TL1 = TH1;
ET1 = 0;
ES = 1;
TR1 = 1;
}
void main()
{
LED_Init();
EA = 1;
ConfigUART(9600);
while (1);
}
void InterruptUART() interrupt 4
{
if (RI)
{
RI = 0;
RXDBUF = SBUF;
SBUF = RXDBUF+1;
}
if (TI)
{
TI = 0;
}
}
|
这里讲解一下串口中断函数,像“if(RI){RI=0;}”和“if(TI){TI=0;}”这些都是在串口中断函数中必须要去执行的任务,当然如果在其他函数里有清0这两个位,可不用在串口中断函数中书写,但一定要保证每次都要清0。
SBUF是名字相同作用却不同的缓冲区。
“RXDBUF = SBUF;”SBUF在等于号后面意为这个是单片机接收电脑端数据的缓存区。
“SBUF = RXDBUF+1;”SBUF在等于号前面意为这个是单片机发送给电脑端数据的缓存区,一旦出现“SBUF
= xxxx”这样的语句,那就是单片机开始通过串口发送数据出去了。
实验现象如下,与上一讲不同,我们这次选用的是“十六进制显示”模式,我们电脑端发送给单片机的数据也是在“十六进制发送”模式,打上7点击发送,电脑端发送的数据其实是0x07,单片机接收到电脑端发来的数据之后加1:0x07+1=0x08。
0x08这个数据再通过单片机发送回去给电脑端,这样电脑端就显示“08”了。
|