树莓派ZeroW学习笔记【2】wiringPi串口编程

一、树莓派ZeroW串口(UART)使用环境搭建

根据官方信息(https://www.raspberrypi.org/documentation/configuration/uart.md),树莓派ZeroW的CPU内部有两个串口,一个PL001 UART和一个Mini UART。其中Mini UART没有时钟源,必须由内核提供时钟源。因为内核频率本身是变化的,从而导致Mini UART速率不稳,基本无法使用。另外树莓派ZeroW没有将PL011 UART分配GPIO中的UART(GPIO14和GPIO15)上,而是将其分配给了蓝牙模块。所以我们需要关闭蓝牙释放PL011 UART转移到GPIO14/15上,才能正常使用PL011 UART。

树莓派ZeroW学习笔记【2】wiringPi串口编程

【1】查看映射关系

$ sudo ls -l /dev

树莓派ZeroW学习笔记【2】wiringPi串口编程

如上图所示:serial0是GPIO14/15上的UART,ttyAMA0是PL001 UART,这是我已经修改好环境将两者连接起来的结果。

(1)修改cmdline.txt文件

$ sudo vim /boot/cmdline.txt

删除console对应的字段

(2)关闭板载蓝牙

$ sudo systemctl disable hciuart

编辑config.txt文件

$ sudo vim /boot/config.txt

增加如下一行:

dtoverlay=pi3-disable-bt

重启树莓派

$ sudo reboot

(3)禁用串口的控制台功能

再次编辑config.txt文件,增加如下一行:

enable_uart=1

然后重启树莓派

至此GPIO14/15的UART串口应该就能正常使用了。

 

二、wiringPi串口函数定义:

  函数 功能 参数 返回值 备注
1 int serialOpen (char *device, int baud)   打开并初始化串口

device

串口的地址,也就是Linux中就是设备所在的目录,树莓派ZeroW用的是"/dev/ttyAMA0"。

 

baud

波特率

正常返回文件描述符,否则返回-1失败。  
2 void serialClose (int fd)  关闭fd关联的串口

fd

文件描述符

   
3 void serialPutchar (int fd, unsigned char c)  串口发送一个字节的数据

fd

文件描述符

 

c

要发送的数据    

   
4 void serialPuts (int fd, char *s)  串口发送一个字符串

fd

文件描述符

 

s

发送的字符串,字符串要以’\0’结尾

   
5 void serialPrintf (int fd, char *message)  和系统函数printf一样发送数据到串口

fd

文件描述符

 

message

格式化的字符串

  系统函数printf是将信息打印到shell中
6 int serialDataAvail (int fd) 获取串口接收缓存中的字节数,以便后续能准确接收。

fd

文件描述符

串口缓存中已经接收的,可读取的字节数,如果返回-1表示错误  
7 int serialGetchar (int fd)   从串口缓存中读取一个字节数据

fd

文件描述符

读取到的字符,如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1。 为了提高接收效率,在读取缓存前,先获取接收缓存的有效字节数,然后根据需要读取,避免出现等待。
8 void serialFlush (int fd) 刷新,清空串口缓冲中的所有可用的数据

fd

文件描述符

   
9 size_t write (int fd,const void * buf,size_t count)  这个是Linux下的标准IO库函数,需要包含头文件#include <unistd.h>,用于通过串口大量发送数据。

buf

需要发送的数据缓存数组

 

count

发送buf中的前count个字节数据

实际写入缓存的字符数,错误返回-1 

当要需要大量发送时,wiringPi建议使用这个函数。
10 size_t read(int fd,void * buf ,size_t count)  这个是Linux下的标准IO库函数,需要包含头文件#include <unistd.h>,用于通过串口大量接收数据。

buf

接收的数据缓存数组

 

count

接收的字节数

实际从缓存中读取的字符数 当要需要大量接收时,wiringPi建议使用这个函数。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

三、串口通信实例

#include <stdio.h> 
#include <errno.h>
#include <string.h>

#include <wiringSerial.h> //使用wiringPi串口函数库

int main(int argc, char *argv[])
{
    int fd;
    if ((fd = serialOpen("/dev/ttyAMA0", 115200)) < 0) //初始化串口并获取文件描述符保存到fd变量里
    {
     fprintf(stderr, "Unable to open serial device: %s\n", strerror(errno));
     return 1 ;
    }

    serialPuts(fd, "Raspi Zero W UART Test Start!");

    for (;;)
    {
      if (serialDataAvail(fd) > 0) //查询接收缓存是否有数据
      {
       serialPutchar(fd,serialGetchar(fd)); //从接收缓存中读取一个字节数据并送入发送缓存中,实现串口环回。
      }

    }

    return 0;
}

将上述代码保存为uart_inout.c

$ gcc uart_inout.c -o uart_inout -l wiringPi

编译后输出uart_inout文件并执行

$ ./uart_inout

 

 

上一篇:ZYNQ EMIO UART使用


下一篇:Micropython学习笔记--Python语言实现串口读写