树莓派Qt读写串口
- 前言
- 一、添加树莓派Qt串口模块
- 二、配置树莓派串口
- 1.查看原理图,了解树莓派管脚及其相应的原理
- 2.配置串口
- 3.测试串口
- 三、添加树莓派代码
前言
记录一下树莓派Qt 串口配置,省的后面忘记了
一、添加树莓派Qt串口模块
已经安装的跳过
1、没有配置国内源和没安装QT的自己找下教程
2、安装Qt串口模块
树莓派上的QSerialport并没有和qt5绑定需要额外安装
sudo apt-get install libqt5serialport5
sudo apt-get install libqt5serialport5-dev
安装完后,开始配置树莓派的串口
二、配置树莓派串口
1.查看原理图,了解树莓派管脚及其相应的原理
抄个定义:
树莓派4b本身是两个串口,一个称之为硬件串口(/dev/ttyAMA0),一个称之为mini串口(/dev/ttyS0)。硬件串口由硬件实现,有单独的波特率时钟源,性能高、可靠,mini串口性能低,功能也简单,并且没有波特率专用的时钟源而是由CPU内核时钟提供,因此mini串口有个致命的弱点是:波特率受到内核时钟的影响。内核若在智能调整功耗降低主频时,相应的这个mini串口的波特率便受到牵连了,虽然你可以固定内核的时钟频率,但这显然不符合低碳、节能的口号。在所有的树莓派板卡中都通过排针将一个串口引出来了,目前除了树莓派3代以外 ,引出的串口默认是CPU的那个硬件串口。而在树莓派3代中,由于板载蓝牙模块,因此这个硬件串口被默认分配给与蓝牙模块通信了,而把那个mini串口默认分配给了排针引出的GPIO Tx Rx。
2.配置串口
使用命令查看下串口
ls /dev -al
确实是2个
如果只有一个serial1 -> ttyAMA0那也不要急
输入命令
sudo raspi-config
选5 interfacing-再选serial
是否开机脚本打开 选NO 选NO 选 NO!!!
最后就这个样子
在boot目录下找到config.txt文件,在最后添加一行内容如下:
在打开的文件后面添加:
sudo nano /boot/config.txt
#ENABLE UART
enable_uart=1
dtoverlay=pi3-miniuart-bt
好像听说现在改了可以把pi3 去掉我用下面的可以
dtoverlay=miniuart-bt
Ctrl+O 写入 Enter 确定写入 Ctrl+Z 退出
重启电脑
sudo reboot
查看下设备 发现映射完的结果已经改变
3.测试串口
看原理图 GPIO14(TXD) 连接到CH340(RXD) 和GPIO15(RXD)连接到CH340(TXD) GND和GND
共地
下载 minicom
sudo apt-get install minicom
要打开这个串口/dev/ttyS0 ,我们映射的是ttyS0
minicom -D /dev/ttyS0 -b 9600
电脑发送数据 minicom 可以接受到数据 这时硬件就准备好了,可以用QT 写个串口测试一下
三、添加树莓派代码
写个串口代码
QT代码
pro添加
QT += serialport
ctlserialport.h文件
#ifndef CTLSERIALEPORT_H
#define CTLSERIALEPORT_H
#include <QtSerialPort>
#include <QSerialPortInfo>
#include <QString>
#include <QTime>
#include <QQueue>
class CtlSerialPort:public QObject
{
Q_OBJECT
public:
CtlSerialPort();
~CtlSerialPort();
public:
QSerialPort *m_SerialPort;
bool m_isPortOk;
bool m_isDynamicOk;
protected:
public:
bool OpenPort(QString portName,int baudRate,int index_parity,int index_dataBit,int index_stopBit);
void ClosePort();
private slots:
void on_recvPortData();
};
#endif
//ctlserialport.Cpp文件
/*******************************************************************
** 函数名: SearchPort
** 函数描述: 搜索对应的串口号
** 参数:
** 返回:
********************************************************************/
QStringList CtlSerialPort::SearchPort(void)
{
QSerialPort serial;
QStringList portNameList;
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
serial.setPortName(info.portName());
if(serial.open(QIODevice::ReadWrite)){
portNameList<<info.portName();
append(6, "检测到串口"+info.portName());
serial.clear();
serial.close();
}else{
//qDebug()<<"OpenPortFailed"+info.portName();
}
}
return portNameList;
}
/*******************************************************************
** 函数名: QudpSocket
** 函数描述: 构造函数
** 参数:
** 返回:
********************************************************************/
CtlSerialPort::CtlSerialPort()
{
m_isPortOk = false;
m_SerialPort = nullptr;
m_SerialPort = new QSerialPort();
connect(m_SerialPort, SIGNAL(readyRead()), this, SLOT(on_recvPortData()), Qt::AutoConnection);
}
/*******************************************************************
** 函数名: ~QudpSocket
** 函数描述: 析构
** 参数:
** 返回:
********************************************************************/
CtlSerialPort::~CtlSerialPort()
{
ClosePort();
}
/*******************************************************************
** 函数名: OpenPort
** 函数描述: 初始化串口
** 参数: portName:串口名
** baudRate:波特率
** index_parity: 校验位
** index_dataBit:数据位
** index_stopBit:停止位
** 返回:
********************************************************************/
bool CtlSerialPort::OpenPort(QString portName,int baudRate,int index_parity,int index_dataBit,int index_stopBit)
{
if(m_SerialPort == nullptr){
m_SerialPort = new QSerialPort;
}
bool ok = false;
QString portinfo;
m_SerialPort->setPortName(portName); //打开串口
ok = m_SerialPort->open(QIODevice::ReadWrite);
m_SerialPort->setBaudRate(baudRate); //设置波特率
switch(index_parity){ //设置校验位
case 0:
m_SerialPort->setParity(QSerialPort::NoParity); //无校验
break;
case 1:
m_SerialPort->setParity(QSerialPort::OddParity);//奇校验
break;
case 2:
m_SerialPort->setParity(QSerialPort::EvenParity);//偶校验
break;
case 3:
m_SerialPort->setParity(QSerialPort::MarkParity);//标志校验
break;
case 4:
m_SerialPort->setParity(QSerialPort::SpaceParity);
break;
default:
m_SerialPort->setParity(QSerialPort::NoParity);
break;
}
switch(index_dataBit){
case 0:
m_SerialPort->setDataBits(QSerialPort::Data8);
break;
case 1:
m_SerialPort->setDataBits(QSerialPort::Data7);
break;
case 2:
m_SerialPort->setDataBits(QSerialPort::Data6);
break;
case 3:
m_SerialPort->setDataBits(QSerialPort::Data5);
break;
default:
m_SerialPort->setDataBits(QSerialPort::Data8);
break;
}
switch(index_stopBit){
case 0:
m_SerialPort->setStopBits(QSerialPort::OneStop);
break;
case 1:
m_SerialPort->setStopBits(QSerialPort::OneAndHalfStop);
break;
case 2:
m_SerialPort->setStopBits(QSerialPort::TwoStop);
break;
default:
m_SerialPort->setStopBits(QSerialPort::OneStop);
break;
}
m_SerialPort->setFlowControl(QSerialPort::NoFlowControl); //设置流控制
connect(m_SerialPort,SIGNAL(readyRead()),this,SLOT(on_recvPortData()),Qt::QueuedConnection);
return ok;
}
/*******************************************************************
** 函数名: ClosePort
** 函数描述: 关闭串口
** 参数:
** 返回:
********************************************************************/
void CtlSerialPort::ClosePort()
{
if(m_SerialPort->isOpen()){
disconnect(m_SerialPort, SIGNAL(readyRead()), this, SLOT(on_recvPortData()));
m_SerialPort->clear();
m_SerialPort->close();
m_SerialPort->deleteLater();
m_isPortOk = false;
delete m_SerialPort;
if(m_SerialPort != nullptr){
m_SerialPort = nullptr;
}
}
}
/*******************************************************************
** 函数名: receivePortData
** 函数描述: 串口槽函数处理
** 参数:
** 返回:
********************************************************************/
void CtlSerialPort::on_recvPortData(void)
{
if(m_SerialPort->isOpen()){
if(m_SerialPort->bytesAvailable() >= 1){
QByteArray info = m_SerialPort->readAll();
QString buffer;
buffer.prepend(info);
}
}
}
打开串口就能正常接收到数据了