#include "uart.h"
#include "unistd.h"
#include <QtSerialPort/QtSerialPort>
#include <QTimer>
#include <QByteArray>
#include <QThread>
#include <QDebug>
std::vector<QSerialPortInfo> Uart::serialPorts_;
Uart::Uart(const QString& uartName, uint baudRate, int ms_rcv/*=-1*/)
: uart_(nullptr)
, uartName_(uartName)
, baudRate_(baudRate)
, serialConnect_(false)
, thread_(nullptr)
, timer_(nullptr)
, enWork_(false)
{
uart_ = new QSerialPort;
Q_CHECK_PTR(uart_);
if (ms_rcv > 0)
{
qDebug("== Use a separate thread to receive serial:%s data. ==", uartName.toLatin1().constData());
thread_ = new QThread;
Q_CHECK_PTR(thread_);
timer_ = new QTimer(this);
Q_CHECK_PTR(timer_);
timer_->setInterval(ms_rcv/2);
connect(timer_, &QTimer::timeout, this, [=](){
timer_->stop();
if (buf_.length()>0)
{
recvData(buf_);
buf_.clear();
}
});
connect(uart_, &QSerialPort::readyRead, this, &Uart::onReadyRead);
this->moveToThread(thread_);
uart_->moveToThread(thread_);
connect(thread_, &QThread::started, this, [=](){
createUartIntance(uartName_, baudRate_);
if (!serialConnect_)
{
QTimer::singleShot(30*1000, this, SLOT(onReconnect()));
}
});
thread_->start();
}
else
{
qDebug("** Use GUI-thread to receive serial:%s data. **", uartName.toLatin1().constData());
createUartIntance(uartName_, baudRate_);
if (!serialConnect_)
{
QTimer::singleShot(30*1000, this, SLOT(onReconnect()));
}
}
}
Uart::~Uart()
{
if (timer_ != nullptr)
{
timer_->stop();
delete timer_;
timer_ = nullptr;
}
uart_->close();
delete uart_;
if (thread_ != nullptr)
{
if (thread_->isRunning())
{
thread_->quit();
thread_->wait(500);
}
}
}
void Uart::onReadyRead()
{
QByteArray by = uart_->readAll();
if (by.size() <= 0) return;
if (!enWork_)
{
if (!buf_.isEmpty())
{
buf_.clear();
}
return;
}
buf_.append(by);
if (buf_.size() >= 0)
{
timer_->start();
}
}
int Uart::InitAvaliablePorts()
{
qDebug("Avaliable SerialPorts: ");
serialPorts_.clear();
int i = 0;
foreach (const QSerialPortInfo & info, QSerialPortInfo::availablePorts())
{
qDebug("- [%d] %s, Desc:%s\t", i,
info.portName().toLatin1().data(),
info.description().toLatin1().data());
serialPorts_.push_back(info);
++i;
}
return serialPorts_.size();
}
bool Uart::GetSerialPortInfo(QSerialPortInfo& serialChosen, const QString& uartName)
{
int portIndex = -1;
for (size_t i=0; i<Uart::serialPorts_.size(); ++i)
{
if (serialPorts_[i].portName() == uartName)
{
portIndex = i;
break;
}
}
if (portIndex == -1) return false;
serialChosen = Uart::serialPorts_[portIndex];
return true;
}
void Uart::onReconnect()
{
serialConnect_ = (ConnectUart(serialChosen_, baudRate_)>=0);
if (!serialConnect_)
{
qWarning() << QString("### Err: !! Serial %1 Not Connect !! ###").arg(serialChosen_.portName()).toLatin1().constData();
QTimer::singleShot(30*1000, this, SLOT(onReconnect()));
}
}
void Uart::createUartIntance(const QString& uartName, uint baudRate)
{
int count = 0;
int portIndex = -1;
do {
for (size_t i=0; i<Uart::serialPorts_.size(); ++i)
{
if (Uart::serialPorts_[i].portName() == uartName)
{
portIndex = i;
break;
}
}
if (portIndex != -1) break;
usleep(500*1000);
count++;
} while (count<6);
if (portIndex == -1)
{
portIndex = 0;
return;
}
serialChosen_ = Uart::serialPorts_[portIndex];
serialConnect_ = (ConnectUart(serialChosen_, baudRate)>=0);
if (!serialConnect_)
{
qWarning() << "Err: !! Serial Not Connect !!";
qWarning() << "Err: !! Serial Not Connect !!";
qWarning() << "Err: !! Serial Not Connect !!";
}
}
int Uart::ConnectUart(const QSerialPortInfo& serialChosen, uint baudRate)
{
uart_->setPort( serialChosen );
if (!uart_->open(QIODevice::ReadWrite))
{
int retries = 10; //30
while (retries-- > 0 && uart_->error() == QSerialPort::PermissionError)
{
qDebug() << QString("Cannot open %1").arg(uart_->portName()).toLatin1().data();
usleep(500*1000);
if (uart_->open(QIODevice::ReadWrite))
{
uart_->clearError();
break;
}
}
if (uart_->error() != QSerialPort::NoError)
{
qWarning() << QString("Failed to open Serial Device: %1 (E%2)").arg(uart_->portName()).arg(uart_->error());
return -1;
}
}
uart_->setBaudRate(QSerialPort::BaudRate(38400));
uart_->setParity(QSerialPort::NoParity);
uart_->setDataBits(QSerialPort::Data8);
uart_->setStopBits(QSerialPort::OneStop);
uart_->setFlowControl(QSerialPort::NoFlowControl);
uart_->clearError();
uart_->clear();
if (timer_ == nullptr)
{
connect(uart_, &QSerialPort::readyRead, this, [=](){
QByteArray by = uart_->readAll();
if (by.size() <= 0) return;
if (!enWork_) {
return;
}
recvData( by );
});
}
qDebug() << QString("%1 is ready.").arg(uart_->portName()).toLatin1().data();
return 0;
}
void Uart::recvData(QByteArray by)
{
if (!_yReadHead)
{
if (!_recvData.isEmpty())
_recvData.clear();
}
_recvData.append(by);
m_hander->checkData(_recvData, _yReadHead); //virtual
}
void Uart::onSendData(const unsigned char* ch, int count, int retry/*=3*/)
{
qDebug()<<QByteArray((char*)ch,count);
int ret = justSend(ch, count, retry);
if (ret == 0) //<0: not connect
{
qDebug("Err: Uart Send fail (%d).", ret);
}
}
int Uart::justSend(const uchar* ch, int count, int retry)
{
if (!serialConnect_) return -1;
int i = 0;
bool success = true;
while (1)
{
if (uart_->write((const char*)ch, count) != count)
{
if (++i >= retry)
{
success = false;
break;
}
usleep(10*1000);
}
else
{
success = true;
break;
}
}
return (success?1:0);
}
没有合适的资源?快使用搜索试试~ 我知道了~
蓝牙串口调试学习代码(本人学习示例不建议下载)
共33个文件
cpp:7个
o:7个
h:5个
需积分: 0 9 下载量 120 浏览量
2023-07-07
19:25:26
上传
评论
收藏 1.61MB ZIP 举报
温馨提示
蓝牙串口调试学习代码
资源推荐
资源详情
资源评论
收起资源包目录
MSerialPort.zip (33个子文件)
MSerialPort
widget.ui 441B
usersadministratorappdatalocaltemptmpcr24so 0B
uart.cpp 7KB
ui_widget.h 1KB
widget.cpp 598B
usersadministratorappdatalocaltemptmpdro43r 0B
uart.h 1KB
usersadministratorappdatalocaltemptmpg7ohzd 0B
Makefile 33KB
MSerialPort.pro.user 44KB
bluetoothhandler.h 2KB
main.cpp 175B
debug
bluetoothhandler.o 361KB
moc_uart.cpp 4KB
MSerialPort.exe 2.7MB
moc_widget.cpp 3KB
moc_widget.o 424KB
main.o 515KB
moc_bluetoothhandler.cpp 5KB
uart.o 756KB
moc_uart.o 318KB
moc_bluetoothhandler.o 323KB
widget.o 321KB
moc_predefs.h 14KB
release
usersadministratorappdatalocaltemptmpv9lruu 0B
Makefile.Release 77KB
usersadministratorappdatalocaltemptmp7brwu5 0B
MSerialPort.pro 1KB
Makefile.Debug 77KB
.qmake.stash 1KB
usersadministratorappdatalocaltemptmpafzohn 0B
bluetoothhandler.cpp 2KB
widget.h 399B
共 33 条
- 1
资源评论
东方忘忧
- 粉丝: 1w+
- 资源: 34
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于Vue的medical-vue医疗挂号系统设计源码
- Python解析网页.xmind
- PMV185XN-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- PMV170UN-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- 基于Java的长理教务管理系统设计源码
- PMV16UN-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- 永磁同步电机-用STM32F103C8T6实现PMSM矢量控制.rar
- PMV160UP-VB一款P-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- 3dmax超级弯曲 暴力弯曲插件
- candence原理图批量换网络的快捷操作
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功