树莓派学习–串口收发
wiringPi库
wiringPi是一个很棒的树莓派IO控制库,使用C语言开发,提供了丰富的接口:GPIO控制,中断,多线程,等等
我们可以通过以下命令查看wiringPi信息
gpio -v
如果没有则需要安装
sudo apt-get install wiringpi
以下是树莓派3b的引脚图
上图显示的是物理引脚编号和wiring库编号,我们可通过输入gpio readall
来查看IO口状态
wiringpi库函数介绍
硬件初始化函数
使用wiringPi时,你必须在执行任何操作前初始化树莓派:
int wiringPiSetup (void) | 返回:执行状态,-1表示失败 | 当使用这个函数初始化树莓派引脚时,程序使用的是wiringPi 引脚编号表。引脚的编号为 0~16,需要root权限 |
---|---|---|
int wiringPiSetupGpio (void) | 返回执行状态,-1表示失败 | 当使用这个函数初始化树莓派引脚时,程序中使用的是BCM GPIO 引脚编号表。 |
wiringPiSetupPhys(void) | 不常用,不做介绍 | / |
wiringPiSetupSys (void) ; | 不常用,不做介绍 | / |
串口通信函数
int serialOpen (char *device, int baud) | device:串口的地址,在Linux中就是设备所在的目录。默认一般是"/dev/ttyAMA0",我的是这样的。 baud:波特率返回:正常返回文件描述符,否则返回-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’结尾 | 发送一个字符串到串口 |
void serialPrintf (int fd, char *message, …) | fd:文件描述符message:格式化的字符串 | 像使用C语言中的printf一样发送数据到串口 |
int serialDataAvail (int fd) | fd:文件描述符返回:串口缓存中已经接收的,可读取的字节数,-1代表错误 | 获取串口缓存中可用的字节数。 |
int serialGetchar (int fd) | fd:文件描述符返回:读取到的字符 | 从串口读取一个字节数据返回。如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1所以,在读取前,做好通过serialDataAvail判断下。 |
void serialFlush (int fd) | fd:文件描述符 | 刷新,清空串口缓冲中的所有可用的数据。 |
*size_t write (int fd,const void * buf,size_t count) | fd:文件描述符buf:需要发送的数据缓存数组count:发送buf中的前count个字节数据返回:实际写入的字符数,错误返回-1 | 这个是Linux下的标准IO库函数,需要包含头文件#include <unistd.h>当要发送到的数据量过大时,wiringPi建议使用这个函数。 |
*size_t read(int fd,void * buf ,size_t count); | fd:文件描述符buf:接受的数据缓存的数组count:接收的字节数.返回:实际读取的字符数。 | 这个是Linux下的标准IO库函数,需要包含头文件#include <unistd.h>当要接收的数据量过大时,wiringPi建议使用这个函数。 |
串口配置修改
在串口通信前,我们还要配置树莓派/boot/cmdline.txt
sudo vi /boot/cmdline.txt
删掉console=…,115200
dwc_otg.lpm_enable=0 console=tty1 console=serial0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
改完后reboot重启
串口发送和接受
测试代码:
#include <wiringPi.h>
#include <wiringSerial.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int fd;
wiringPiSetup(); //初始化树莓派引脚
char cmd;
char *str;
str=(char*)malloc(1024);
fd=serialOpen("/dev/ttyAMA0",9600); //打开并初始串口
while(1){
// serialPutchar(fd,'c');
// serialPuts(fd,"aaaaaaaaa\r\n");
while(serialDataAvail(fd)<=0); //获取串口缓存中可用的字节数
cmd = serialGetchar(fd); //从串口读取一个字节数据返回
// memset(str,0,1024);
// sprintf(str,"get cmd:%c\r\n",cmd);
// serialPuts(fd,str); //发送一个字符串到串口
printf("get data:cmd=%c\n",cmd);
serialPrintf (fd, "get cmd:%c\r\n", cmd); //发送数据到串口
if(cmd=='q'){
serialPuts(fd,"quit\r\n");
printf("quit\n");
break;
}
// delayMicroseconds(1000000);
}
free(str);
serialClose(fd); //关闭fd关联的串口
return 0;
}
gcc demo.c -lwiringPi
运行结果
字符串收发
#include <wiringPi.h>
#include <wiringSerial.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
int fd;
char cmd[128]={'\0'};
int n_read;
wiringPiSetup();
fd=serialOpen("/dev/ttyAMA0",9600);
while(1){
while(serialDataAvail(fd)<=0);
n_read=read(fd,cmd,sizeof(cmd));
printf("cmd:%s\n",cmd);
if(strstr(cmd,"quit")!=NULL){
printf("quit\n");
serialPrintf (fd, "get cmd:%s\r\n", cmd);
break;
}
memset(cmd,'\0',sizeof(cmd));
}
serialClose(fd);
return 0;
}
运行结果: