前言
相信有很多人跟我一样,对串口通信这一块非常着迷。学会了这个东西,你就能实现单片机与电脑的通信,以及单片机与单片机的通信。
这次有了之前的知识,你已经对各个寄存器有了一些初步了解,也知道寄存器如何使用了。
我会给大家总结以下你可能忽略的重要知识。
预备知识
正文
知识点1:
波特率、串行口控制寄存器SCON、SBUF寄存器
波特率:单片机或计算机再串口通信时的速率用波特率表示,定义为每秒传输二进制代码的位数,即1波特=1/秒,即bps。(我们只需要知道我们再=在进行传输数据的时候,需要两边的波特率相同,否则会出现乱码)
串行口控制寄存器SCON:选择串行口的工作方式和控制串行口的状态
SM0与SM1:设置串行口的工作方式
(这里我们只说方式1,方式1涉及到之后的智能家居小项目于)
SM2:多机控制位,有兴趣可以自己查资料看一下(我们默认为0)
REN:允许串行接收位。REN=1,允许串行口接收数据;REN=0时,禁止串行口接收数据;
TB8和RB8:有兴趣可以自己查资料阅读下(我们默认为0)
TI:发送中断标志位。发送完一串数据,会由硬件置1(不需要人为操作)并且申请串口中断,之后我们必须用软件置0(人为操作),才能从中断跳出来
RI:接收中断标志位。同发送一样,只不过这个是我们接收完一次数据,会产生的中断,也是硬件置1,触发中断,需要软件清0.
SBUF寄存器:用来接收和发送数据的寄存器。
知识点2:
这边主要整理一下大家可能出现的疑问。
1、我们知道方式1的波特率与定时器1有关,可是为什么用定时器的工作方式2,而不是用定时器的工作方式1?
答:我们知道定时器工作方式1在工作的时候,必须要打开定时器中断进行重新装初值,这个过程中容易产生时间上微小的误差,多次操作时的微小误差不断积累,终会产生错误。而工作方式2不用进入中断进行装值,而是每次溢出后,单片机会自动为其装初值。所以单片机进行串口通信时用工作方式2.
2、我们在发送一次数据或者接收一次数据必须要进入中断么?
答:不是的先看下图,
可以看到无论我们去不去中断,数据都会发出去,只不过串口中断的触发是由T1或R1置1触发的。
3、SBUF寄存器是如何发送和接收数据的呢?
答:只要我们给SBUF赋值,就会自动把数据发送出去,如
SBUF = 1;
就相当于把1给发出去了。接收数据的时候,如果数据来了,会自动储存到SBUF寄存器中,取值
a = SBUF; //让SBUF的值储存在a变量里面
知识点3:
printf函数的使用。在51单片机中printf函数就是将一串数据发送到串行口,待会我们具体应用一下。
配置过程
1、设置定时器1的工作方式2
TMOD = 0x20;
2、计算TH1和TL1的初值,计算波特率(这里我们可以直接用辅助软件算,设置的波特率为9600)
TH1 = 0xFD;
TL1 = 0xFD;
3、确定串行口工作方式
SM0 = 0;
SM1 = 1; //设置为方式1
REN = 1; //允许接收数据
3、可以选择打开中断(可选可不选)
EA = 1; //打开全局中断
ES = 1; //打开串口中断
4、打开定时器1
TR1 = 1;
简单实践一下
用电脑给单片机的LED灯打开;
用单片机给电脑发送:hello world!;
#include <reg52.h>
#include <stdio.h>
#define uint unsigned int
#define uchar unsigned char
sbit key = P3^2; //定义一个按键用于给单片机给电脑发信息
void delayms(uint z) //延时函数 ms级
{
uint i,y;
for(i=z;i>0;i--)
for(y=110;y>0;y--);
}
void Key() //定义一个按键发送数据函数
{
if(key == 0)
{
delayms(10);
if(key == 0)
{
ES = 0;
TI = 1;
printf("hello world!");
while(!TI);
ES = 1;
}
}
}
void main()
{
TMOD = 0x20;
TH1 = 0xFD;
TL1 = 0xFD;
SM0 = 0;
SM1 = 1;
REN = 1;
TR1 = 1; //初始化串口通信
EA = 1;
ES = 1;
while(1)
{
Key();
}
}
void zhongduan() interrupt 4
{
RI = 0;
P2 = SBUF;
}
可以看到串口调试助手显示了hello world!这就是printf函数在51单片机中的作用
我们从串口助手往单片机发送十六进制的55,结果可以看到是一致的。
总结
其实发现串口通信也不是特别难,就是几个寄存器的控制,以及波特率的设置。
(受惠于互联网,感恩于互联网。加油!)