目录
一 串口说明
二 USB—TTL模块
● usb-ttl模块接口
三 串口通信常用的API
四 修改串口的配置文件
五 串口通信代码验证
● 发送一个字符/字符串到串口
● 树莓读取串口数据(字符)
● 代码拓展(双方)
一 串口说明
我在基于全志H6实现Linux串口通信这篇文章中也有详解介绍:点击查看详细内容
① 串口通信经常使用在多机通信中。不管是软件还是硬件,都存在模块化的编程思想。
● 半双工:A传数据给B,B只接收数据,什么也不能做;
● 全双工:A传数据给B的同时,B也能给A传输数据;
② 实现串口多机通信的协议设置:串口号,数据格式和波特率。
● 串口号:CH340软件来接收或生成串口号;
● 波特率:好比人的语速,常用的115200,9600;
● 数据格式:可以比作人交流的语种。数据位;奇偶校验位;停止位。
类似于人和人在交流沟通时,都必须使用同一种语言和语速,这样通信双方才能明白对方的内容。
二 USB—TTL模块
作用:将通信双方识别的电平转换为通信电平。
● 我们常用的单片机,引出来的串口,如果不加其他的接口电路,出来的信号就是TTL电平;
● 如果需要看串口的打印信息,一般是需要接一个上位机的,常规的就是电脑,而现在的电脑一般的通信接口只有USB;
● 对于USB口而言,是没法和TTL串口直接通信的,因为接口不匹配,电平也不匹配,这时候就需要借助其它设备来实现接口与电平的转换;
● 常规操作是使用CH340这种芯片所制作的USB转串口模块,这个模块就可以实现TTL串口和USB之前的转换。
● usb-ttl模块接口
● RXD :数据输入引脚,数据接收;
● TXD :数据发送引脚,数据发送;
接线说明:如图
在树莓派接入USB-TTL模块时,除了交叉连接RXD和TXD两端,最好在接入GND,保持电平的稳定。
三 串口通信常用的API
头文件:#include <wiringSerial.h>
① int serialOpen (char *device, int baud)
作用:打开并初始化串口
● device:串口的地址,在Linux中就是设备所在的目录。默认一般是"/dev/ttyAMA0"。
● baud:波特率,
● 返回值:正常返回文件描述符fd,否则返回-1失败。
② void serialClose (int fd)
作用:关闭fd关联的串口
● fd:文件描述符
③ void serialPutchar (int fd, unsigned char c)
作用:发送一个字节的数据到串口
● fd:文件描述符
● c:要发送的字符数据
④ void serialPuts (int fd, char *s)
作用:发送一个字符串到串口
● fd:文件描述符
● s:发送的字符串,字符串要以'\0'结尾
⑤ int serialDataAvail (int fd)
作用:获取串口缓存中可用的字节数。
● fd:文件描述符
● 返回:串口缓存中已经接收的,可读取的字节数,-1代表错误
⑥ int serialGetchar (int fd)
作用:从串口读取一个字节数据返回。
说明:如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1。所以,在读取前,做好通过serialDataAvail判断下。
● fd:文件描述符
● 返回值:读取到的字符
四 修改串口的配置文件
在使用串口通信之前,一定要修改相关配置文件,不然容易出错。
① cd /boot/ :进入系统根目录中的boot目录;
② sudo vim cmdline.tx :用超级用户权限打开cmdline.tx文件,内容如图:
③ 删除圈中的部分,保存退出;
④ sudo reboot重启即可
五 串口通信代码验证
● 发送一个字符/字符串到串口
#include <stdio.h>
#include <wiringSerial.h>//串口头文件
#include <wiringPi.h>int main()
{int fd; //文件描述符if(wiringPiSetup() == -1){ //初始化库printf("init wiringPi error!\n");return -1;}fd = serialOpen("/dev/ttyAMA0",115200);//初始/打开/创建串口,并设置波特率while(1){// serialPutchar(fd,'a'); //发送一个字符serialPuts(fd,"hello pi!\r\n"); //发送一个字符串到串口,\r\n串口中换行delayMicroseconds(1000000); //延时设置1000000us = 1s,每隔1s就发送}return 0;
}
● 树莓读取串口数据(字符)
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>int main()
{int fd;int cmd;if(wiringPiSetup() == -1){printf("init wiringPi error!\n");return -1;}fd = serialOpen("/dev/ttyAMA0",115200);while(serialDataAvail(fd) != -1){ //初始化serialDataAvail()函数cmd = serialGetchar(fd); //cmd接收该函数的返回值,一个字符printf("get data:%c\n",cmd);}serialClose(fd);//退出return 0;
}
● 代码拓展(双方)
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>int main()
{int fd;int cmd;if(wiringPiSetup() == -1){printf("init wiringPi error!\n");return -1;}fd = serialOpen("/dev/ttyAMA0",115200);while(serialDataAvail(fd) != -1){ //初始化serialDataAvail()函数cmd = serialGetchar(fd); //cmd接收该函数的返回值,一个字符printf("get data:%c\n",cmd);if(cmd == '2'){serialPuts(fd,"hello 2\r\n");//串口中换行\r\n结合使用}if(cmd == '3'){ //树莓收到字符3时,就发送hello 3这个字符串到串口serialPuts(fd,"hello 3\r\n");}if(cmd == '4'){serialPuts(fd,"hello 4\r\n");}}serialClose(fd);//退出return 0;
}