若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/79758975
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)
树莓派开发专栏(点击传送门)
上一篇:《树莓派开发笔记(五):GPIO引脚介绍和GPIO的输入输出使用(驱动LED灯、检测按键输入)》
下一篇:《树莓派开发笔记(七):GPIO口的SPI使用(BME280三合一传感器:测量温度、湿度、气压、海拔高度) 》
前话
前面使用了GPIO口的输入和输出,本篇重点是GPIO口的uart使用,使用uart与电脑串口通讯。
Demo:GPIO口的UART通讯
Pi3的蓝牙和GPIO口的UART不可兼得
树莓派3上用户目前无法正常是使用GPIO中的UART串口(GPIO14&GPIO15),,原因是树莓派CPU内部有两个串口,一个是硬件串口(官方称为PL011 UART),一个是迷你串口(官方成为mini-uart)。在树莓派2B/B+这些老版树莓派上,官方设计时都是将“硬件串口”分配给GPIO中的UART(GPIO14&GPIO15),因此可以独立调整串口的速率和模式。而树莓派3的设计上,官方在设计时将硬件串口分配给了新增的蓝牙模块上,而将一个没有时钟源,必须由内核提供时钟参考源的“迷你串口”分配给了GPIO的串口,这样以来由于内核的频率本身是变化的,就会导致“迷你串口”的速率不稳定,这样就出现了无法正常使用的情况。目前解决方法就是,关闭蓝牙对硬件串口的使用,将硬件串口重新恢复给GPIO的串口使用,也就意味着树莓派3的板载蓝牙和串口,现在成了鱼和熊掌,两者无法兼得。
恢复GPIO串口的方法
查看下当前系统的串口信息
编辑/boot目录下的config.txt文件
sudo vim/boot/config.txt
添加下面两行,
dtoverlay=pi3-miniuart-bt
注意:"pi3-miniuart-bt"是在文件夹/boot/overlays中可以找到的。如果没有,你可以下载一个"pi3-miniuart-bt-overlay"文件并将其拷贝至/boot/overlays文件夹中,并且将下面的语句更改为:dtoverlay=pi3-miniuart-bt-overlay即可。
再编辑cmdline.txt文件
sudo gdit /boot/cmdline.txt
修改以下内容
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
保存重启即可。
查看下重启后的串口信息
出现两个串口,表示操作成功
关闭蓝牙
我们不再使用蓝牙,所以为了节省能耗,关掉蓝牙
sudo systemctl diable hciuart sudo vim /lib/systemd/system/hciuart.service
将ttyAMA0改成ttyS0,如下图:
测试GPIO串口
短接GPIO14和GPIO15,先使用minicom环回测试。
安装串口工具minicom
sudo apt-get install minicom
运行工具
sudo minicom -s
选择第三项
配置参数
先内部环回测试,短接GPIO14和GPIO15,在mincom时打开回显(Ctrl+A,再全部松开按Z,跳出配置界面按E)
输入一个在字符,先回显字符,然后自己又接收到字符,如下图测试成功
对接电脑的USB转TTL,树莓派RX对TTL的TX,树莓派TX对TTL的RX,测试成功,如下图:
电路原理图
关键代码
初始化
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); _uart.open(); connect(&_uart, SIGNAL(recvData(QByteArray)), this, SLOT(recvData(QByteArray))); startTimer(1000); }
接收数据代码
void MainWindow::recvData(QByteArray data) { ui->label_uart->setText(QString(data)); }
每隔1s发送一次“test a agin!!!”
void MainWindow::timerEvent(QTimerEvent *event) { QByteArray data = QString("test a again!!!").toUtf8(); _uart.sendData(data); }
模块代码
uart.h
#ifndef UART_H #define UART_H #include <QObject> #include "wiringSerial.h" #include <QByteArray> class Uart : public QObject { Q_OBJECT public: explicit Uart(QObject *parent = 0); signals: void recvData(QByteArray); public slots: bool open(QString dev = QString("/dev/ttyAMA0"), int buad = 115200); void sendData(QByteArray data); void close(); protected slots: void loopRead(); private: int _fd; QByteArray _recvData; }; #endif // USART_H
uart.cpp
#include "uart.h" #include <QTimer> #include "wiringPi.h" Uart::Uart(QObject *parent) : QObject(parent) { _fd = 0; wiringPiSetup(); } bool Uart::open(QString dev, int buad) { _fd = serialOpen(dev.toUtf8().data(), buad); ...... } void Uart::sendData(QByteArray data) { ...... serialPuts(_fd, data.data()); ...... } void Uart::close() { if(_fd > 0) { serialClose(_fd); _fd = 0; } } void Uart::loopRead() { ...... int size = serialDataAvail(_fd); _recvData.clear(); for(int index = 0; index < size; index++) { _recvData.append((uchar)serialGetchar(_fd)); } …… }
运行效果
上一篇:《树莓派开发笔记(五):GPIO引脚介绍和GPIO的输入输出使用(驱动LED灯、检测按键输入)》
下一篇:《树莓派开发笔记(七):GPIO口的SPI使用(BME280三合一传感器:测量温度、湿度、气压、海拔高度) 》
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/79758975