UART简介
UART是一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收。在嵌入式设计中,UART用来主机与辅助设备通信,如汽车音响与外接AP之间的通信,与PC机通信包括与监控调试器和其它器件,多用于上位机与下位机的通信。
在UART通信中,两个UART直接相互通信。 发送UART将控制设备(如CPU)的并行数据转换为串行形式,以串行方式将其发送到接收UART。只需要两条线即可在两个UART之间传输数据,数据从发送UART的Tx引脚流到接收UART的Rx引脚:

波特率:每秒传输二进制位数。
例:1分钟传输数据57600BYTE,帧格式10位,求波特率?
二进位:57600*10=576000/60 = 9600bit/s
UART属于异步通讯,这意味着没有时钟信号,取而代之的是在数据包中添加起始和停止位。这些位定义了数据包的开始和结束,通过识别起始位和结束位可以解析出数据。
帧格式:1位起始位+(5-8)位数据+1位奇偶校验位+(1~2)位停止位 =10位
奇校验:数据位上的1的个数+校验位上1的个数和位奇数。

数据包的传输示意图:

上图来自此文
①串口是什么?
串口就是一种通信方式(TX和RX)
②串口通信的特点
异步 全双工 串行
③串口通信数据帧
起始位 数据位(8) 【奇偶校验】 停止位
有关串口的详细介绍参考此文

树莓派使用UART与串口屏通信

今天主要借助陶晶驰串口屏配合树莓派4B实现一个通信效果。

串口屏简介
串口屏内置一块STM32,构建了相对独立的系统,有配套的软件能够进行图形化编程,极大地降低了界面设计的时间和难度,而且还有各种控件以便于灵活实现更多功能,可以通过串口完成对各类控件的操作,有很强的实用性。

有关陶晶驰串口屏的具体使用可以参考官网的资料

硬件连接
将串口屏的TX、RX与树莓派的UART硬件接口连接,注意交叉。(没有屏幕的同学也可以使用USB转TTL连接树莓派,然后安装陶晶驰的开发环境,在线仿真也可。)

配置串口接口
树莓派一共有两个串口如下图所示:(来自B站树小悉

这里还需要注意,树莓派的串口分为了主串口和辅助串口;
硬件串口标识符为ttyAMA0;主串口标识符为serial0;辅助串口的标识符为serial1)。本此介绍使用的是硬件串口和主串口,利用引脚通信。

树莓派打开UART接口
跟之前类似,打开Serial Port,关闭Serail Console,点击OK,会提示重启。

点击Yes等待重启。

重启完毕后,打开命令终端,输入ls /dev -al 回车。(若重启失败,先把串口屏拔下来,重启完毕后再接上去)

下拉找到串口,此时发现,主串口(serial0)指向了mini串口,辅助串口(serial1)指向了硬件串口(ttyAM0);这与我们所需要将主串口指向硬件串口,所以需要进一步修改配置。

利用nano编辑器打开并修改config.txt,具体步骤如下:
(1)在终端输入:sudo nano /boot/config.txt 回车,弹出下图画面,利用滚轮来到文件末尾。

(2)添加如下代码:
dtoverlay=pi3-miniuart-bt
force_turbo=1

按Ctrl+S保存,Ctrl+X返回。
然后再次重启树莓派,输入sudo reboot 等待重启完成
再次打开终端,输入ls /dev -al 回车此时上滑找到串口发现已经修改为主串口指向硬件串口了。

树莓派安装串口调试助手
为了验证树莓派串口有没有真的工作,需要安装一个minicom的串口助手来验证一下。
安装步骤:打开终端输入:sudo apt-get install minicom回车等待下载和安装,安装过程中有提示,直接输入Y回车。

安装完成后需要先将USB转TTL连接到树莓派,然后打开电脑的串口调试助手,连接到CH340(波特率9600八位数据一位停止)。

同时打开树莓派的串口助手:
在终端输入命令: minicom -D /dev/ttyAMA0 -b 9600回车即可进入。


在电脑端输入abcd点击发送,可以发现在树莓派上有了显示,表示串口开启OK。此时我们需要退出minicom ,退出步骤:首先Ctrl+A,然后按Z;最后按X,选是即可退出。


编程实现
验证了串口功能后,我们开始利用串口编程,在编程之前,根据前面的经验,我还是需要先了解一下WiringPi的串口库给我们提供了哪些可以调用的函数。
之前一直没提这个库是怎么查询的,在这里说明一下:
安装后wiringpi的库后我们可以载可以在/usr/linclude找到wiringPi相关的头文件如下图所示:
wiringPi.h 基本IO驱动和常用配置定义;
wiringPiI2C.h I2C驱动的头文件;
wiringPiSPI.h SPI驱动的头文件;
wiringSerial.h Serial驱动的头文件;

wiringSerial.h Serial简介
双击wiringSerial.h Serial.h,我们可以看见有以下几个函数:

具体解释转载与此文
extern int serialOpen (const char _device, const int baud) ;//打开串口,输入设备描述符和串口波特率,返回串口的设备ID
extern void serialClose (const int fd) ;//关闭串口,
extern void serialFlush (const int fd) ;//清空缓存区
extern void serialPutchar (const int fd, const unsigned char c) ;//输出一个字符
extern void serialPuts (const int fd, const char _s) ;//输出字符串
extern void serialPrintf (const int fd, const char *message, …) ;//格式化输出
extern int serialDataAvail (const int fd) ;//返回设备缓存区接收到的数据个数
extern int serialGetchar (const int fd) ;//从设备ID读取一个字符

C语言实现
此处转载的此文
打开Geany输入以下代码:

// An highlighted block
#include<wiringPi.h>
#include<wiringSerial.h>
#include<stdio.h>
#include<string.h>
#include<time.h>
void delay_ms(int ms);
int main()
{
    int filedevid;
    int recbytenum;
    int i;
    char buf[1024];
    memset(buf,0,1024);
    wiringPiSetup();
    if((filedevid=serialOpen("/dev/ttyAMA0",115200))<0)//打开串口
    {
        printf("/dev/ttyAMA0 Open Faild\r\n");
        return -1;
    }
    else
    {
        printf("/dev/ttyAMA0 Open with 115200, success\r\n");
        while(1)
        {
            recbytenum = serialDataAvail(filedevid);//记录接受到的数据个数
            if(recbytenum > 1)//如果接收到
            {
                i=0;
                while(recbytenum--)
                {
                    buf[i++] = serialGetchar(filedevid);//读出缓存区的数据
                }
               printf("Rpi uart recv: %s\r\n",buf);输出在终端
                serialPrintf(filedevid,"Rpi uart send: %s\r\n",buf);//通过串口打印到上位机啊。
                memset(buf,0,1024);
            }
        }
    }
}

上述代码效果如下:

树莓派UART与串口屏通信
C语言代码如下:

//树莓派通过串口屏输出两个通道正弦波形。
#include<wiringPi.h>
#include<wiringSerial.h>
#include<stdio.h>
#include<string.h>
#include<time.h>

#define uchar unsigned char
#define uint  unsigned int
int filedevid;
int second,minute,hour,day,month,week,year,zwc,fwc,wdc,bal,txt,wendu;
char endbuf[]={0xff,0xff,0xff};
char buf[64];

//唤醒屏幕准备通信
void UART_Send_start(void)
{
	 delay(10);
	 serialPuts (filedevid,(char *)endbuf);//发送结束标志0xff,0xff,0xff包尾
	 delay(10);
}
int main()
{
     uint ch0,ch1;
     signed int i,j;
     second=50;minute=48;hour=12;day=15;month=7;week=2;year=16;bal=0;txt=0;wendu=0;

    wiringPiSetup();
    if((filedevid=serialOpen("/dev/ttyAMA0",9600))<0)//打开串口
    {
        printf("/dev/ttyAMA0 Open Faild\r\n");
        return -1;
    }
    else
    {
        printf("/dev/ttyAMA0 Open with 9600, success\r\n");
        UART_Send_start();//初始化串口屏
        serialPuts (filedevid,"page 0");//切换到初始页面
        serialPuts (filedevid,(char *)endbuf);//发送结束标志0xff,0xff,0xff包尾
        delay(1000);//等待屏幕启动
        
        while(1)
        {
            j= 32;
			for(i=0;i<sizeof(zhengxianbo);i++) 	//正弦波显示
			{

			 ch0 = zhengxianbo[i]/3+40;
			 ch1 = zhengxianbo[j++]/3+40;
			 if(j>=sizeof(zhengxianbo))
			 j = 0;
			 sprintf(buf,"add 1,0,%d",ch0);//将波形数据打包
			 serialPuts(filedevid,(char *)buf);
	 		 serialPuts (filedevid,(char *)endbuf);//发送结束标志0xff,0xff,0xff包尾
			 sprintf(buf,"add 1,1,%d",ch1);//将波形数据打包
			 serialPuts(filedevid,(char *)buf);
	 		 serialPuts (filedevid,(char *)endbuf);//发送结束标志0xff,0xff,0xff包尾
        }
    }
}
}
//此处展示的代码不全,有需要的点赞收藏私信笔者免费获取。

效果如下:

总结
有关树莓派串口的记录就到这里,到此笔者关于树莓派的基础部分笔记也就结束了,后面会根据情况更新进阶版的,前面有关内容如果存在不妥之处欢迎批评指正,此系列到此基本画上了句号。如果觉得对你有帮助记得点赞收藏加关注。

树莓派4B入门学习笔记汇总
树莓派4B学习笔记——系统烧录及初次开机
树莓派4B学习笔记——点亮你的LED
树莓派4B学习笔记——IO输入检测
树莓派4B学习笔记——IO通信篇(I2C)
树莓派4B学习笔记——IO通信篇(SPI)
树莓派4B学习笔记——IO通信篇(1-Wire)
树莓派4B学习笔记——IO通信篇(UART)