树莓派教程 - 1.4 树莓派GPIO库wiringPi 树莓派串口ttyS0

Git例程源码仓库https://github.com/ZhiliangMa/raspberry.git

使用树莓派的串口前,需要先了解树莓派板载的两个串口的区别:

树莓派3为了增加蓝牙硬件,将独立时钟的硬件串口(/dev/ttyAMA0),默认分配给了蓝牙。

与CPU共用时钟的硬件串口(/dev/ttyS0),默认分配给了15、16。

而树莓派的CPU时钟不像单片机一般是固定的,而是根据负载来动态调整的,这就会导致有些问题:当CPU频率切换时,可能会造成串口有乱码现象。说人话就是 /dev/ttyAMA0更加稳定。

 

本节先讲 /dev/ttyS0 串口的用法,适用于对稳定性要求不是很严苛,但绝对能满足绝大部分需求的场合

/dev/ttyAMA0 挖坑留给下一节。

硬件连接:

 

开启ttyS0串口设置方法:

左上角的树莓图标 Menu - Preferences - Raspberry Pi Configuration

Serial Port 勾上 Enable,Serial Console 勾 Disable。之后需要重启,点击 YES。

重启后进入终端,ls /dev/ttyS*,如显示 /dev/ttyS0 则正确。

 

串口库用到的函数:

使用时需要添加 #include <wiringSerial.h>

函数语句函数功能
int serialOpen (char *device, const int baud)打开 *device设备地址的串口,波特率 baud
void serialClose(int fd)关闭 fd关联的串口
void serialFlush (int fd)清空串行缓冲区(TX和RX)
void serialPutchar(int fd, unsigned char c)通过串口发送一个字节的数据
void serialPuts (int fd, char *s)通过串口发送字符串
void serialPrintf (int fd, char *message, ...)串口打印,用法跟printf一样
int serialDataAvail (int fd)返回串口接收缓存区的可用字节数
int serialGetchar (int fd)从接收缓存区得到一个字节
  
  

 

c代码测试程序1:

Git例程源码仓库https://github.com/ZhiliangMa/raspberry.git

(从串口接收缓存区读取10个字节,并完整输出接收到的数据)

#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>

int main(void)
{
    int hs1;
    int snum = 0;

    wiringPiSetup();                        // 使用wiring编码去初始化GPIO序号
    hs1 = serialOpen("/dev/ttyS0", 115200); // 打开 /dev/ttyS0 串口设备,波特率115200

    printf("ttyS0 uart test1:\n");          // 终端打印
    serialPrintf(hs1, "Hello World!\r\n");  // 串口打印
    serialPrintf(hs1, "Enter 10 letters:\r\n");

    /* 串口缓存区读取10个字节,并完整输出接收到的数据 */
    do{
        snum = serialDataAvail(hs1);        // 获取串口接收缓存区的可用字节数
    }while(snum < 10);

    while(snum--)
    {
        serialPutchar(hs1,serialGetchar(hs1));  // 通过串口发送字节
    }
    serialPrintf(hs1, "\r\nserial close\r\n\r\n");  // 串口打印

    serialClose(hs1);                       // 关闭串口
    return 0;
}

 

c代码测试程序2:

(讲串口接收缓存区的内容记录到数组,遇到\n结束,并完整输出接收到的数据)

#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>

int main(void)
{
    int hs1;
    int snum = 0;
    int tnum = 0;
    unsigned char chrtmp[100];
    wiringPiSetup();                            // 使用wiring编码去初始化GPIO序号
    hs1 = serialOpen("/dev/ttyS0", 115200);     // 打开 /dev/ttyS0 串口设备,波特率115200

    printf("ttyS0 uart test2:\n");              // 终端打印
    serialPrintf(hs1, "Hello World!\r\n");      // 串口打印
    serialPrintf(hs1, "Enter a paragraph and end with Enter:\r\n");

    /* 串口缓存区记录到数组,遇到\n结束,并完整输出接收到的数据 */
    while (1)
    {
        snum = serialDataAvail(hs1);            // 获取串口接收缓存区的可用字节数
        if(snum > 0)
        {
            chrtmp[tnum] = serialGetchar(hs1);  // 从接收缓存区读取一个字节
            tnum ++;
            if(chrtmp[tnum - 1] == '\n') break;
        }
        //delay(2000);
        //printf("%d  ,  %d\n",snum,tnum);
    }

    int i = 0;
    while (tnum--)
    {
        serialPutchar(hs1,chrtmp[i++]);         // 通过串口发送字节
    }
    serialPrintf(hs1, "\r\nserial close\r\n\r\n");  // 串口打印

    serialClose(hs1);                           // 关闭串口
    return 0;
}

 

波特率范围:

从 wiringSerial.c 中截取的一段代码,里面定义了波特率的设置,串口波特率只能选择其中的值使用。

  switch (baud)
  {
    case      50:	myBaud =      B50 ; break ;
    case      75:	myBaud =      B75 ; break ;
    case     110:	myBaud =     B110 ; break ;
    case     134:	myBaud =     B134 ; break ;
    case     150:	myBaud =     B150 ; break ;
    case     200:	myBaud =     B200 ; break ;
    case     300:	myBaud =     B300 ; break ;
    case     600:	myBaud =     B600 ; break ;
    case    1200:	myBaud =    B1200 ; break ;
    case    1800:	myBaud =    B1800 ; break ;
    case    2400:	myBaud =    B2400 ; break ;
    case    4800:	myBaud =    B4800 ; break ;
    case    9600:	myBaud =    B9600 ; break ;
    case   19200:	myBaud =   B19200 ; break ;
    case   38400:	myBaud =   B38400 ; break ;
    case   57600:	myBaud =   B57600 ; break ;
    case  115200:	myBaud =  B115200 ; break ;
    case  230400:	myBaud =  B230400 ; break ;
    case  460800:	myBaud =  B460800 ; break ;
    case  500000:	myBaud =  B500000 ; break ;
    case  576000:	myBaud =  B576000 ; break ;
    case  921600:	myBaud =  B921600 ; break ;
    case 1000000:	myBaud = B1000000 ; break ;
    case 1152000:	myBaud = B1152000 ; break ;
    case 1500000:	myBaud = B1500000 ; break ;
    case 2000000:	myBaud = B2000000 ; break ;
    case 2500000:	myBaud = B2500000 ; break ;
    case 3000000:	myBaud = B3000000 ; break ;
    case 3500000:	myBaud = B3500000 ; break ;
    case 4000000:	myBaud = B4000000 ; break ;

    default:
      return -2 ;
  }

 

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值