当前位置: 首页 > news >正文

零知开源——基于STM32F4的HC-12无线通信系统及ST7789显示应用

 ✔零知IDE 是一个真正属于国人自己的开源软件平台,在开发效率上超越了Arduino平台并且更加容易上手,大大降低了开发难度。零知开源在软件方面提供了完整的学习教程和丰富示例代码,让不懂程序的工程师也能非常轻而易举的搭建电路来创作产品,测试产品。快来动手试试吧!

✔访问零知实验室,获取更多实战项目和教程资源吧!

www.lingzhilab.com

目录

一、硬件系统设计

1.1 硬件清单

1.2 接线方案

1.3 连接硬件图

1.4 接线实物图

二、软件系统设计

2.1 HC-12模块模式切换机制

2.2 ST7789显示优化技术

2.3 无线数据处理状态机

2.4 信道切换处理核心

2.5 发送端完整代码

2.6 接收端完整代码

三、数据传输展示

3.1 发送端操作

3.2 无线传输

3.3 接收端处理

3.4 视频演示

四、关键技术详解

4.1 HC-12模块工作原理

4.2 软件串口实现

五、常见问题解答

Q1: 为什么HC-12模块无法通信?

Q2: 如何增加通信距离?

六、结论


(1)项目概述

        本项目构建了一个基于STM32F407VET6微控制器的无线通信系统,通过HC-12模块实现两个零知增强板之间的长距离无线通信。发送端通过物理按键切换信道,接收端使用ST7789显示屏实时显示当前信道状态。系统实现了HC-12模块的无线通信控制、AT指令的无线传输与解析、接收端可视化界面设计、状态信息的实时更新与显示

(2)项目亮点

        >提供清晰直观的UI界面
        >HC-12模块支持1公里以上通信距离(空旷环境)
        >功能模块分离,便于维护和扩展
        >优化了通信协议,减少能耗

一、硬件系统设计

1.1 硬件清单

组件数量说明
零知增强板(STM32F407VET6)2主控制器
HC-12无线模块2433MHz无线通信
ST7789 TFT显示屏1240×320分辨率,SPI接口
轻触按键2发送端信道切换
杜邦线若干模块连接

1.2 接线方案

(1)发送端接线

HC-12模块按键零知增强板1
VCC按键的一端3.3V
GND通过10k下拉电阻接到按键另一端GND
/按键14
/按键23
TX/10
RX/11
SET/6

(2)接收端接线

HC-12模块ST7789零知增强板2
VCCVCC3.3V
GNDGNDGND
/SCL52
/SDA51
/RES47
/DC49
/CS53
TX/10
RX/11
SET/6

1.3 连接硬件图

(1)发送端接线图

(2)接收端接线图

1.4 接线实物图

二、软件系统设计

2.1 HC-12模块模式切换机制

// 发送信道切换命令
void sendChannelCommand(String channel) {HC12.print("AT+C" + channel); // 发送指令到另一个模块delay(100);// 进入AT指令模式digitalWrite(setPin, LOW);    // 设置HC-12为AT指令模式delay(100);                   // 等待进入AT模式HC12.print("AT+C" + channel); // 发送AT指令到本地HC-12delay(200);// 读取并显示响应while (HC12.available()) {Serial.write(HC12.read());}Serial.println("信道切换成功");// 退出AT指令模式digitalWrite(setPin, HIGH);
}

双模切换机制:

        首先以透明模式发送指令到接收端(digitalWrite(setPin, HIGH))
        然后进入AT模式(digitalWrite(setPin, LOW))配置本地模块
        确保发送端和接收端同时切换到相同信道

2.2 ST7789显示优化技术

// 更新信道显示
void updateChannel() {// 清除旧信道显示区域tft.fillRect(20, 130, 200, 30, ST77XX_BLACK);// 绘制新信道信息tft.setCursor(20, 130);tft.setTextColor(ST77XX_YELLOW);tft.setTextSize(3);tft.println(currentChannel);
}// 更新消息显示
void updateMessage() {// 清除旧消息显示区域tft.fillRect(20, 210, 200, 30, ST77XX_BLACK);// 绘制新消息tft.setCursor(20, 210);// 根据消息类型设置颜色if (lastMessage == "Success!") {tft.setTextColor(ST77XX_GREEN); // 成功消息为绿色} else {tft.setTextColor(ST77XX_WHITE); // 普通消息为白色}tft.setTextSize(3);tft.println(lastMessage);
}

局部刷新技术:

        使用fillRect()仅刷新特定区域,而非整个屏幕
        显著提高刷新效率(全屏刷新需300ms,局部刷新仅需20ms)
        避免屏幕闪烁现象

2.3 无线数据处理状态机

void loop() {// 接收HC-12数据并存储到缓冲区while (HC12.available()) {incomingByte = HC12.read();readBuffer += char(incomingByte);}delay(100);// 处理信道切换指令if (readBuffer == "AT+C001") {processChannelChange("01");}else if (readBuffer == "AT+C002") {processChannelChange("02");}// 检查并处理AT指令checkATCommand();// 消息超时处理if (millis() - messageTime > MESSAGE_TIMEOUT && lastMessage != "Waiting...") {lastMessage = "Waiting...";updateMessage();}readBuffer = ""; // 清空缓冲区
}

数据接收状态机:

        使用while (HC12.available())确保完整接收数据包
        delay(100)提供数据接收缓冲时间
        字符串比较readBuffer == "AT+C001"实现指令识别        

2.4 信道切换处理核心

void processChannelChange(String channel) {// 进入AT指令模式digitalWrite(setPin, LOW);    // 设置HC-12为AT指令模式delay(100);                   HC12.print("AT+C" + channel); // 发送完整AT指令delay(200);// 读取响应String response = "";while (HC12.available()) {response += char(HC12.read());}// 退出AT指令模式digitalWrite(setPin, HIGH);   // 更新显示信息currentChannel = "Channel: " + channel;lastMessage = "Success!";messageTime = millis();       // 重置消息计时器// 更新显示屏updateChannel();updateMessage();
}

信道切换协议:

严格遵循AT指令格式"AT+C" + channel
确保与发送端指令格式完全一致
支持扩展更多信道(如"003"、"004"等)

响应处理机制:

构建response字符串收集模块响应
可用于错误检测和调试(当前版本未使用)

显示更新联动:

同时更新currentChannel和lastMessage
调用updateChannel()和updateMessage()刷新界面
重置messageTime启动超时计时器

2.5 发送端完整代码

/* * 基于STM32F407VET6的HC-12无线通信发送端* 功能:通过按键切换信道并发送AT指令*/
#include <SoftwareSerial.h>// 引脚定义
#define setPin 6    // HC-12设置引脚(PD6)
#define button1 4   // 按钮1引脚(PD4)
#define button2 3   // 按钮2引脚(PD3)// 初始化软件串口 (RX, TX)
SoftwareSerial HC12(10, 11); // PA10(RX), PA9(TX)// 全局变量
byte incomingByte;
String readBuffer = "";
int button1State = 0;
int button1Pressed = 0;
int button2State = 0;
int button2Pressed = 0;void setup() {Serial.begin(9600);          // 初始化串口监视器HC12.begin(9600);            // 初始化HC-12通信pinMode(setPin, OUTPUT);     // 配置SET引脚为输出pinMode(button1, INPUT);     // 配置按键1为输入pinMode(button2, INPUT);     // 配置按键2为输入digitalWrite(setPin, HIGH);  // 设置HC-12为正常透明模式
}void loop() {// 接收HC-12数据并存储到缓冲区while (HC12.available()) {incomingByte = HC12.read();readBuffer += char(incomingByte);}delay(100);// 串口转发功能:将串口数据转发到HC-12while (Serial.available()) {HC12.write(Serial.read());}// 按钮1处理:切换到信道01button1State = digitalRead(button1);if (button1State == HIGH && button1Pressed == LOW) {button1Pressed = HIGH;delay(20); // 按键消抖}if (button1Pressed == HIGH) {sendChannelCommand("001"); // 发送信道切换指令button1Pressed = LOW;     // 重置按键状态}// 按钮2处理:切换到信道02button2State = digitalRead(button2);if (button2State == HIGH && button2Pressed == LOW) {button2Pressed = HIGH;delay(100); // 按键消抖}if (button2Pressed == HIGH) {sendChannelCommand("002"); // 发送信道切换指令button2Pressed = LOW;     // 重置按键状态}// 检查并处理AT指令checkATCommand();readBuffer = ""; // 清空缓冲区
}// 发送信道切换命令
void sendChannelCommand(String channel) {HC12.print("AT+C" + channel); // 发送指令到另一个模块delay(100);// 进入AT指令模式digitalWrite(setPin, LOW);    // 设置HC-12为AT指令模式delay(100);                   // 等待进入AT模式HC12.print("AT+C" + channel); // 发送AT指令到本地HC-12delay(200);// 读取并显示响应while (HC12.available()) {Serial.write(HC12.read());}Serial.println("信道切换成功");// 退出AT指令模式digitalWrite(setPin, HIGH);
}// 检查并处理串口接收的AT指令
void checkATCommand() {if (readBuffer.startsWith("AT")) {digitalWrite(setPin, LOW);  // 进入AT模式delay(200);HC12.print(readBuffer);     // 发送AT指令delay(200);// 读取并显示响应while (HC12.available()) {Serial.write(HC12.read());}digitalWrite(setPin, HIGH); // 退出AT模式}
}

2.6 接收端完整代码

/** 基于STM32F407VET6的HC-12无线通信接收端* 功能:接收信道切换指令并在ST7789显示屏上显示状态*/
#include <SoftwareSerial.h>
#include <Adafruit_GFX.h>       // 核心图形库
#include <Adafruit_ST7789.h>    // ST7789显示驱动// 引脚定义
#define setPin 6                // HC-12设置引脚(PD6)
#define TFT_CS   53             // 显示屏片选(PG9)
#define TFT_DC   49             // 数据/命令选择(PG8)
#define TFT_RST  47             // 显示屏复位(PG7)// 初始化软件串口和显示屏
SoftwareSerial HC12(10, 11);    // PA10(RX), PA9(TX)
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);// 全局变量
byte incomingByte;
String readBuffer = "";
String currentChannel = "Channel: --"; // 当前信道显示
String lastMessage = "Waiting...";     // 最后消息
unsigned long messageTime = 0;         // 消息时间戳
const unsigned long MESSAGE_TIMEOUT = 2000; // 消息显示超时(2秒)void setup() {Serial.begin(9600);          // 初始化串口监视器HC12.begin(9600);            // 初始化HC-12通信pinMode(setPin, OUTPUT);     // 配置SET引脚为输出digitalWrite(setPin, HIGH);  // 设置HC-12为正常模式// 初始化显示屏tft.init(240, 320);          // 初始化240x320显示屏tft.setRotation(3);           // 设置显示方向(0-3)tft.invertDisplay(false);     // 禁用显示反转tft.fillScreen(ST77XX_BLACK); // 清屏tft.setTextWrap(false);       // 禁用文本换行// 绘制静态UI元素drawUI();
}void loop() {// 接收HC-12数据并存储到缓冲区while (HC12.available()) {incomingByte = HC12.read();readBuffer += char(incomingByte);}delay(100);// 串口转发功能:将串口数据转发到HC-12while (Serial.available()) {HC12.write(Serial.read());}// 处理信道切换指令if (readBuffer == "AT+C001") {processChannelChange("01");}else if (readBuffer == "AT+C002") {processChannelChange("02");}// 检查并处理AT指令checkATCommand();// 消息超时处理if (millis() - messageTime > MESSAGE_TIMEOUT && lastMessage != "Waiting...") {lastMessage = "Waiting...";updateMessage();}readBuffer = ""; // 清空缓冲区
}// 处理信道切换
void processChannelChange(String channel) {// 进入AT指令模式digitalWrite(setPin, LOW);    // 设置HC-12为AT指令模式delay(100);                   HC12.print("AT+C" + channel); // 发送完整AT指令delay(200);// 读取响应String response = "";while (HC12.available()) {response += char(HC12.read());}// 退出AT指令模式digitalWrite(setPin, HIGH);   // 更新显示信息currentChannel = "Channel: " + channel;lastMessage = "Success!";messageTime = millis();       // 重置消息计时器// 串口输出Serial.print("Channel ");Serial.print(channel);Serial.println(" set successfully");// 更新显示屏updateChannel();updateMessage();
}// 检查并处理AT指令
void checkATCommand() {if (readBuffer.startsWith("AT")) {digitalWrite(setPin, LOW);  // 进入AT模式delay(100);                 HC12.print(readBuffer);     // 发送AT指令delay(200);// 读取并显示响应while (HC12.available()) {Serial.write(HC12.read());}digitalWrite(setPin, HIGH); // 退出AT模式}
}// 绘制静态UI元素
void drawUI() {// 绘制标题tft.setCursor(20, 20);tft.setTextColor(ST77XX_WHITE);tft.setTextSize(3);tft.println("HC-12 SYSTEM");// 绘制分隔线tft.drawFastHLine(10, 60, 220, ST77XX_BLUE);// 绘制信道标签tft.setCursor(20, 100);tft.setTextColor(ST77XX_CYAN);tft.setTextSize(2);tft.println("Current Channel:");// 绘制状态标签tft.setCursor(20, 180);tft.setTextColor(ST77XX_CYAN);tft.setTextSize(2);tft.println("Status:");// 绘制边框tft.drawRect(5, 5, 240, 235, ST77XX_WHITE);// 初始化动态内容updateChannel();updateMessage();
}// 更新信道显示
void updateChannel() {// 清除旧信道显示区域tft.fillRect(20, 130, 200, 30, ST77XX_BLACK);// 绘制新信道信息tft.setCursor(20, 130);tft.setTextColor(ST77XX_YELLOW);tft.setTextSize(3);tft.println(currentChannel);
}// 更新消息显示
void updateMessage() {// 清除旧消息显示区域tft.fillRect(20, 210, 200, 30, ST77XX_BLACK);// 绘制新消息tft.setCursor(20, 210);// 根据消息类型设置颜色if (lastMessage == "Success!") {tft.setTextColor(ST77XX_GREEN); // 成功消息为绿色} else {tft.setTextColor(ST77XX_WHITE); // 普通消息为白色}tft.setTextSize(3);tft.println(lastMessage);
}

错误预防机制:

        指令格式严格校验
        超时管理系统
        缓冲区定期清理

三、数据传输展示

系统工作时,数据传输流程如下:

3.1 发送端操作

        用户按下按键1或按键2
        发送端通过软件串口发送"AT+C001"或"AT+C002"指令
        同时设置本地HC-12模块的信道

3.2 无线传输

        两个HC-12模块通过433MHz无线频段传输数据
        传输距离可达1000米(开阔地带)

3.3 接收端处理

        接收端HC-12模块收到指令
        解析指令内容并设置本地信道
        更新ST7789显示屏上的信道信息
        显示"Success!"状态信息2秒后恢复等待状态

3.4 视频演示

基于零知增强板和HC-12传输无线指令

发送端(零知增强板1)按下按键同时将接收端(零知增强板2)的信道切换成信道01和信道02

四、关键技术详解

4.1 HC-12模块工作原理

HC-12是基于Si4463射频芯片的无线串口通信模块,特点包括:

        工作频率:433.4-473.0MHz
        传输距离:100-1000米(取决于环境和功率设置)
        支持多种波特率(1200bps-115200bps)
        提供4个通信频道

AT指令关键操作:

        >AT+C001:切换到信道001
        >AT+RPx:设置发射功率(x=0-8,8为最大功率20dBm)
        >AT+FBx:设置工作模式(x=0-2,0为FU1模式)

4.2 软件串口实现

在STM32F407VET6上使用软件串口的优势:

        不占用硬件串口资源
        可灵活配置任意GPIO作为TX/RX
        支持多串口并发通信

SoftwareSerial库注意事项:

        >波特率不宜过高(建议≤38400bps)
        >避免在中断服务程序中调用
        >接收缓冲区大小可调整以优化性能

五、常见问题解答

Q1: 为什么HC-12模块无法通信?

A:以下步骤进行检查:

        检查电源:确保3.3V稳定供电
        验证接线:TX-RX交叉连接
        检查波特率:双方必须使用相同波特率
        确认信道:双方必须处于相同信道

Q2: 如何增加通信距离?

A:发送端进行指令配置:

        设置更高发射功率:AT+RP8(最大功率)
        使用外置天线:替换模块上的弹簧天线
        调整工作模式:AT+FB2(FU2模式,低速率但更远距离)
        优化天线位置:避免金属屏蔽

六、结论

        项目充分展示了STM32F407VET6的强大性能和HC-12模块的通信能力,为物联网应用开发提供了实用参考。系统可进一步扩展为环境监测、远程控制等多种应用场景。通过本项目的开发,我们实现了:

        基于HC-12的可靠无线通信系统
        ST7789显示屏的GUI界面设计与实现
        硬件按键与无线指令的协同控制
        实时状态反馈与显示

项目资源:

(1)所需库

        ST7789显示屏: Adafruit ST7789 Library

        GFX图形库: Adafruit GFX Library

        软件串口库: SoftwareSerial Library

(2)技术文档

        HC-12无线通信模块: HC-12用户手册

        主控芯片数据手册: STM32F407VET6 Datasheet

本文详细介绍了基于STM32F407VET6零知增强板的HC-12无线通信系统设计与实现!点击了解更多零知开发教程:
https://www.lingzhilab.com/freesources.html

http://www.dtcms.com/a/330870.html

相关文章:

  • 【Linux】库制作与原理
  • mysql卸载了 服务内还显示如何解决
  • CVPR 2025丨时间序列:动态多尺度机制登场,即插即用,预测稳准狠刷新SOTA
  • Vivado GPIO详解
  • 量化因子RSI
  • 中小型泵站物联网智能控制系统解决方案:构建无人值守的自动化泵站体系
  • 基于STM32单片机智能手表GSM短信上报GPS定位温湿度检测记步设计
  • OS设备UDID查看方法
  • Mybatis学习笔记(一)
  • 「iOS」————设计架构
  • 在语音通信业务量下降时候该怎么做
  • PHP现代化全栈开发:微服务架构与云原生实践
  • 基于FPGA的8PSK+卷积编码Viterbi译码通信系统,包含帧同步,信道,误码统计,可设置SNR
  • 一台联想 ThinkCentre M7100z一体机开机黑屏无显示维修记录
  • 优化 SQL 查询:选出每个分组最大值的行并插入 10W 条测试数据
  • 云计算-Docker Compose 实战:从OwnCloud、WordPress、SkyWalking、Redis ,Rabbitmq等服务配置实例轻松搞定
  • 【代码随想录day 20】 力扣 108.将有序数组转换为二叉搜索树
  • 老生常谈之引用计数:《More Effective C++》条款29
  • 炎热的夏天
  • SQL181 第二快/慢用时之差大于试卷时长一半的试卷
  • 掌握MATLAB三维可视化:从基础到实战技巧
  • Redis 从入门到生产:数据结构、持久化、集群、工程实践与避坑(含 Node.js/Python 示例)
  • jenkins在windows配置sshpass
  • 构建Node.js单可执行应用(SEA)的方法
  • 【前端工具】使用 Node.js 脚本实现项目打包后自动压缩
  • Go语言defer机制详解与应用
  • 机器学习介绍
  • 预训练模型在机器翻译中的应用:迁移学习的优势详解
  • 华为实验WLAN 基础配置随练
  • dkms安装nvidia驱动和多内核支持