下图是电脑收到单片机经过串口发送的信息, 那么电脑是如何与单片机进行串口通信的呢?
首先,任何一种通信都要包括硬件物理接口和软件通信协议。
串口通信物理接口如下图。单片机通过发送端将数据从左往右一位一位按顺序发送;且在发送前,我们需要事先约定好帧格式,和波特率,这种规则被称为串口通信协议。
通过波形测试,我们可以看到发送端的数据线里的波形如下图:
那么帧格式如何定义呢?
下图便是一帧完整的串行通信数据,它一共有10位,并从左往右依次把数据给发送出去。起始位永远是低电平,停止位永远是高电平,中间的是8位二进制数据(用户自定义)。按照这种规则,我们把图中处于高电平状态的数据位相加得到65,从ASCII码表中查到65对应的就是A,通过8个数据位我们便可得到256种不同的信息组合(如下图)。
因此,我们想发送什么数据,就按照ASCII表上的值让微控制器去发送高低电平就可以了。
那么波特率在串口通信中有啥作用呢,可不可以随意设置波特率呢?
在发送数据的同时必须要有时间间隔。这里的时间间隔就得看串口通信的波特率了。在第一章图中,我们使用的波特率为9600/s,也就是1每位数据之间的间隔约为100us。
即每隔100us,微控制器向电脑发送一次高低电平(比如微控制器发送65,电脑收到的就是A)。如果想要使数据更快的发送,可以选择更高的波特率,比如115200/s(即发送时间间隔为8.7us)。
但是我们在编程时设置的串口发送时间间隔必须要和波特率严格对应上,若对应不上,则会出现下图情况。
即当我们将数据发送过去,接收方可能已经过了接收时间,可能导致数据错乱。
以上就是串口发送数据的底层原理。
但是我们用串口发送数据时,不需要向上面设置的那么繁琐。以Arduino为例,在程序的最开头设置好波特率,然后直接把C用这个函数发送出去,无需我们设置时间间隔,也无需按照ASCII表像刚才那样一位一位的去发送数据,但该函数底层编程是按照这种思想编写代码,我们只需调用相关库文件和函数即可。
注:视频教程来自B站UP:爱上半导体