Qt实现安卓手机蓝牙通信并控制stm32f103c8t6驱动VFD屏

2023-10-28 06:20

本文主要是介绍Qt实现安卓手机蓝牙通信并控制stm32f103c8t6驱动VFD屏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、Qt建立蓝牙通信

Qt具有跨平台的特性所以非常适合写通信的demo,但是在这个例程中Qt蓝牙部分不支持Windows平台,安卓平台使用没问题。
Qt蓝牙主要涉及到三个类的使用:
QBluetoothDeviceDiscoveryAgent //扫描周围蓝牙设备
QBluetoothLocalDevice //扫描本地蓝牙
QBluetoothSocket //建立蓝牙的socket读写

安卓不支持低功耗蓝牙,但是socket既可以使用经典蓝牙也可以使用低功耗蓝牙,本例程使用经典蓝牙socket收发数据

1、在.pro工程文件添加

Qt                   +=bluetooth

2、主要代码Widget.h和Widget.c

#ifndef WIDGET_H
#define WIDGET_H
#pragma execution_character_set("utf-8")   //解决中文乱码#include <QWidget>
#include <QObject>
#include <QtBluetooth/qbluetoothlocaldevice.h>
#include <qbluetoothaddress.h>
#include <qbluetoothdevicediscoveryagent.h>
#include <qbluetoothlocaldevice.h>
#include <qbluetoothsocket.h>
#include <QMap>
#include <QTimer>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void model2_Init();
public slots:void addBlueToothDevicesToList(const QBluetoothDeviceInfo&);void readBluetoothDataEvent();void bluetoothConnectedEvent();void bluetoothDisconnectedEvent();void onError(QBluetoothSocket::SocketError error);void open_BLE();void close_BLE();void scanFinished();
private:QBluetoothDeviceDiscoveryAgent *discoveryAgent;QBluetoothLocalDevice *localDevice;QBluetoothSocket *socket;QByteArray blueArray;QMap<QString,QBluetoothAddress>m;QBluetoothDeviceInfo remoteDeviceInfo;float ff;//随机数缓存float div;//每次下降数float sx;//上限float t;//时间QString ss;//字符判断是模式1还是模式2QTimer *time;private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_4_clicked();void on_pushButton_5_clicked();void on_pushButton_3_clicked();void on_pushButton_7_clicked();void on_pushButton_8_clicked();void on_pushButton_9_clicked();void on_pushButton_6_clicked();void timeProcess();void on_pushButton_10_clicked();void on_label_7_linkActivated(const QString &link);private:Ui::Widget *ui;
};
#endif // WIDGET_H
## Widget.c
#include "widget.h"
#include "ui_widget.h"
#include <QRandomGenerator>
#include <QLowEnergyController>//这个UUID要根据自己的使用情况来确定,我使用的是串口类的UUID,具体可https://www.jianshu.com/p/eb85cb690e86
static const QLatin1String serviceUuid("00001101-0000-1000-8000-00805F9B34FB");
//static const QLatin1String serviceUuid("FDA50693A4E24FB1AFCFC6EB07647825");
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->plainTextEdit->setDisabled(1);discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);localDevice = new QBluetoothLocalDevice(this);socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);time = new QTimer(this);connect(time,SIGNAL(timeout()),this,SLOT(timeProcess()));discoveryAgent->start();ui->pushButton_4->setDisabled(1);connect(discoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));//搜索结束connect(discoveryAgent,SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this,SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo)));connect(socket,SIGNAL(readyRead()),this,SLOT(readBluetoothDataEvent()));connect(socket,SIGNAL(connected()),this,SLOT(bluetoothConnectedEvent()));connect(socket,SIGNAL(disconnected()),this,SLOT(bluetoothDisconnectedEvent()));connect(socket,SIGNAL(error(QBluetoothSocket::SocketError)),this,SLOT(onError(QBluetoothSocket::SocketError)));}Widget::~Widget()
{delete ui;delete discoveryAgent;delete localDevice;delete socket;delete time;
}void Widget::onError(QBluetoothSocket::SocketError error)
{QString str;if(QBluetoothSocket::UnknownSocketError == error){str = "UnknownSocketError";}else if(QBluetoothSocket::NoSocketError == error){str = "NoSocketError";}else if(QBluetoothSocket::HostNotFoundError == error){str = "HostNotFoundError";}else if(QBluetoothSocket::ServiceNotFoundError == error){str = "ServiceNotFoundError";}else if(QBluetoothSocket::NetworkError == error){str = "NetworkError";}else if(QBluetoothSocket::UnsupportedProtocolError == error){str = "UnsupportedProtocolError";}else if(QBluetoothSocket::OperationError == error){str = "OperationError";}else if(QBluetoothSocket::RemoteHostClosedError == error){str = "RemoteHostClosedError";}qDebug()<<error;//emit backendRunMesgPost(str);//emit backendRunMesgPost("SocketError");
}void Widget::addBlueToothDevicesToList( const QBluetoothDeviceInfo &info )
{remoteDeviceInfo = info;qDebug()<<"进入addBlueToothDevicesToList函数!";QString label = QString("%1 %2").arg(info.address().toString()).arg(info.name());qDebug()<<label;ui->comboBox->addItem(info.name());if(label.contains("BT04-A")){//找到需要连接的蓝牙名字int index = label.indexOf(' ');if(index == -1){qDebug()<<"index";return;}QBluetoothAddress address(label.left(index));m[info.name()] = address;//关联蓝牙名字和addressQString name(label.mid(index + 1));qDebug() << "You has choice the bluetooth address is " << address<<name<<endl;//qDebug() << "The device is connneting.... ";//ui->plainTextEdit_2->setPlainText("You has choice the bluetooth address is "+name);//ui->plainTextEdit_2->setPlainText("The device is connneting.... ");//emit backendRunMesgPost("The device is connneting");//socket->connectToService(address, QBluetoothUuid(serviceUuid) ,QIODevice::ReadWrite);}
}void Widget::readBluetoothDataEvent()
{static int cnt = 0;QByteArray line = socket->readAll();if(line.startsWith("y") || line.startsWith("r"))ss = line;if(ss.startsWith("y")){//ss = "d";if(!line.startsWith('y')){blueArray.append(line);}if(cnt < 4){ui->plainTextEdit->appendPlainText(QString(blueArray));cnt++;}else{cnt = 0;ui->plainTextEdit->clear();}//ui->plainTextEdit->setPlainText(QString(blueArray));ui->plainTextEdit_2->setPlainText("模式1");emit ui->pushButton_3->clicked(1);}else if(ss.startsWith("r")){ss = "d";ui->plainTextEdit_2->setPlainText("模式2");model2_Init();emit ui->pushButton_10->clicked(1);emit ui->pushButton_7->clicked(1);ss = "d";}else if(line.startsWith("Flash")){ui->plainTextEdit_2->setPlainText(QString(line));ss = "d";}
}void Widget::bluetoothConnectedEvent()
{qDebug() << "The android device has been connected successfully!";ui->plainTextEdit_2->setPlainText("The android device has been connected successfully!");
}void Widget::bluetoothDisconnectedEvent()
{qDebug() << "The android device has been disconnected successfully!";
}void Widget::open_BLE()
{if( localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff)//开机没有打开蓝牙{localDevice->powerOn();//调用打开本地的蓝牙设备discoveryAgent->start();//开始扫描蓝牙connect(discoveryAgent,SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this,SLOT(addBlueToothDevicesToList(QBluetoothDeviceInfo)));ui->plainTextEdit_2->setPlainText("手机蓝牙已成功打开!");}else{qDebug() << "手机蓝牙已成功打开!";ui->plainTextEdit_2->setPlainText("手机蓝牙已成功打开!");}
}void Widget::close_BLE()
{socket->close();ui->plainTextEdit_2->setPlainText("蓝牙已断开!");
}void Widget::on_pushButton_clicked()//模式一
{//ui->plainTextEdit->clear();ui->pushButton_2->setDisabled(1);ui->pushButton_7->setDisabled(1);socket->write("y");
}void Widget::on_pushButton_2_clicked()//模式二
{model2_Init();ui->pushButton->setDisabled(1);ui->pushButton_3->setDisabled(1);if(socket->state() == QAbstractSocket::ConnectedState){socket->write("r");}
}void Widget::on_pushButton_4_clicked()//连接蓝牙
{discoveryAgent->stop();if(ui->comboBox->currentText().startsWith("BT04-A")){//低功耗蓝牙连接方式/*QLowEnergyController *lowBtControl = QLowEnergyController::createCentral(remoteDeviceInfo);lowBtControl->connectToDevice();*///经典蓝牙连接方式qDebug() << "连接到的蓝牙是" << m[ui->comboBox->currentText()]<<ui->comboBox->currentText();socket->connectToService(m[ui->comboBox->currentText()],QBluetoothUuid(serviceUuid) ,QIODevice::ReadWrite);ui->plainTextEdit_2->setPlainText("The device is connneting.... ");if(socket->state() == QAbstractSocket::ConnectedState)ui->plainTextEdit_2->setPlainText("蓝牙连接成功!");}else{ui->plainTextEdit_2->setPlainText("没有找到目标蓝牙!");}
}void Widget::on_pushButton_5_clicked()//断开连接
{close_BLE();
}void Widget::on_pushButton_3_clicked()//模式一修改数字
{if(socket->write("v")){QString str;str = ui->lineEdit_6->text();str.append('z');socket->write(str.toUtf8());ui->plainTextEdit_2->setPlainText("成功发送一条数据!v");}
}void Widget::on_pushButton_7_clicked()
{if(socket->write("s"))//发送随机数{QString str = QString("%1").arg(sx);if(str.length() > 4)str = str.left(4);str.append('x');socket->write(str.toUtf8());}
}void Widget::on_pushButton_8_clicked()//切换模式
{ui->pushButton->setEnabled(1);ui->pushButton_2->setEnabled(1);ui->pushButton_7->setEnabled(1);ui->pushButton_3->setEnabled(1);ui->plainTextEdit->setEnabled(1);ui->plainTextEdit->clear();ui->plainTextEdit->setDisabled(1);time->stop();
}void Widget::on_pushButton_9_clicked()
{open_BLE();
}void Widget::on_pushButton_6_clicked()
{this->close();
}void Widget::scanFinished()
{ui->pushButton_4->setEnabled(1);
}void Widget::timeProcess()
{sx = sx - div;QString str;str = QString("%1").arg(sx);qDebug()<<"sx is " + str<<endl;if(sx <= ff){sx = ff;time->stop();}ui->plainTextEdit_2->setPlainText("成功发送一条数据!s"+str);str = QString("%1").arg(div);qDebug()<<"div is " + str<<endl;emit ui->pushButton_7->clicked(1);
}void Widget::model2_Init()
{sx = ui->lineEdit_3->text().toUInt();t = ui->lineEdit_4->text().toUInt();div = (sx - ff)/(t*10);
}void Widget::on_pushButton_10_clicked()
{if(ui->lineEdit->text().isEmpty() == false && ui->lineEdit_2->text().isEmpty() == false ){std::uniform_real_distribution<float> dist(ui->lineEdit->text().toUInt(), ui->lineEdit_2->text().toUInt());ff = dist(*QRandomGenerator::global());ui->lineEdit_5->setText(QString::number(ff));QString str = ui->lineEdit_5->text();if(str.length() > 4)str = str.left(4);ff = str.toFloat();ui->lineEdit_5->setText(QString::number(ff));if(ui->lineEdit_3->text().isEmpty() == false && ui->lineEdit_4->text().isEmpty() == false){time->start(6000);}}}

在这里插入图片描述

二、通过蓝牙模块控制stm32f103c8t6驱动VFD

蓝牙模块选择BT08B蓝牙串口模块兼容HC-06,只需连接四个引脚 VCC 、GND、TX、RX即可

下面为VFD模块驱动程序,采用带驱动芯片的模块,直流5V供电即可,stm32可直接驱动模块引出引脚

1、VFD_Drive.h

#ifndef _VFD_DRIVE_H
#define _VFD_DRIVE_H#include "stm32f10x.h"void VFD_GPIOInit(void);//GPIO初始化void WriteCMD(u8 cmd);//写命令
void WriteDATA(u8 data);//写数据void Clear(void);//清屏
void Cursor_home(void);//光标归位
/*
该指令选择在每次DDRAM或CGRAM访问后AC(游标位置)是递增还是递减,并确定在每次DDRAM写入后显示信息的移动方向。
该指令还在每次DDRAM写入后启用或禁用显示移位。
*/
void IncCursor(void);//光标递增(向右)
void DecCursor(void);//光标递减(向左)void DisplayOFForON(u8 i,u8 j,u8 n);//光标显示还是不显示,i = 1显示i = 0不显示,并指定是否闪烁j = 1闪烁,j = 0闪烁,n=1开光标,n=0关光标
/*
该指令增加或减少AC(光标位置),并将显示信息向左或向右移动一个字符的位置
*/
void CharLeft(void);//字符和光标左移
void CharRight(void);//字符和光标右移
void CursorLeft(void);//光标左移
void CursorRight(void);//光标右移/*
设置并行口模式DL = 0为4位模式,DL = 1为8位模式
设置单行显示还是两行显示,N = 0,单行显示,N = 1两行显示
设置亮度BR = 0  100%亮度,BR = 1   75%亮度,BR = 2   50%亮度,BR = 3    25%亮度
*/
void FunSet(u8 DL,u8 N,u8 BR);//这里固定为两行显示,亮度100%,如需更改请查看手册重写函数/*该指令将DB5-DB0指定的6位CGRAM地址放入AC(光标位置)。后续的数据写入(读取)将会指向(从)CGRAM。*/
u8 CGRAM_addrSet(u8 addr);//返回传入addr后的命令/*该指令将DB6-DB0指定的7位DDRAM地址放入AC(光标位置)。后续的数据写入(读取)将从DDRAM写入(从DDRAM读取)。*/
u8 DDRAM_addrSet(u8 addr);//返回传入addr后的命令/*该指令将DB7-DB0上的8位数据字节写入AC寻址的DDRAM或CGRAM位置。
最近的DDRAM或CGRAM地址集指令决定是写入DDRAM还是CGRAM。
该指令还根据输入模式设置(Entry 

这篇关于Qt实现安卓手机蓝牙通信并控制stm32f103c8t6驱动VFD屏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/291287

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Python实现精确小数计算的完全指南

《Python实现精确小数计算的完全指南》在金融计算、科学实验和工程领域,浮点数精度问题一直是开发者面临的重大挑战,本文将深入解析Python精确小数计算技术体系,感兴趣的小伙伴可以了解一下... 目录引言:小数精度问题的核心挑战一、浮点数精度问题分析1.1 浮点数精度陷阱1.2 浮点数误差来源二、基础解决

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版