news 2026/8/7 5:07:27

串口通信实战:主机按键控制从机LED

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
串口通信实战:主机按键控制从机LED

1. 项目概述

本项目基于单片机学习板,实现两个单片机之间的串口通信。主机通过按键K1控制从机LED灯的亮灭,是一个典型的串口通信应用实例。

1.1 硬件平台

  • 主控芯片:STC89C52
  • 通信接口:串口(CH340 USB转串口芯片)
  • 按键:K1连接在P3.4
  • LED:连接在P1端口

1.2 实现功能

  • 主机检测K1按键状态
  • 主机通过串口发送控制命令
  • 从机接收并解析串口命令
  • 从机控制LED1的亮灭状态

2. 硬件连接

2.1 串口连接配置

主机(Master) 从机(Slave) P3.1 (TXD) ----------- P3.0 (RXD) P3.0 (RXD) ----------- P3.1 (TXD) GND ------------------- GND

2.2 按键和LED连接

  • 主机:K1按键 → P3.4
  • 从机:LED1 → P1.0(低电平点亮)

2.3 通信协议

采用简单的字符协议:

  • 主机发送'L''1':从机LED1亮
  • 主机发送'O''0':从机LED1灭
  • 主机发送'A''a':从机所有LED亮

3. 程序设计

3.1 主机程序(Master)

#include <reg52.h> #define FOSC 11059200L #define BAUD 9600 sbit KEY_K1 = P3^4; bit last_key_state = 1; /** * 串口初始化 * 波特率:9600 @ 11.0592MHz * 工作方式:方式1 */ void UART_Init(void) { SCON = 0x50; // 方式1,8位数据,允许接收 TMOD = 0x20; // 定时器1方式2 TH1 = 0xFD; // 9600波特率 TL1 = 0xFD; TR1 = 1; // 启动定时器1 ES = 0; // 不启用串口中断 } /** * 发送单个字节 * @param dat 要发送的数据 */ void UART_SendByte(unsigned char dat) { SBUF = dat; while(!TI); // 等待发送完成 TI = 0; // 清除发送标志 } /** * 发送字符串 * @param str 要发送的字符串 */ void UART_SendString(char *str) { while(*str != '\0') { UART_SendByte(*str++); } } /** * 毫秒级延时函数 * @param ms 延时毫秒数 */ void DelayMs(unsigned int ms) { unsigned int i, j; for(i = 0; i < ms; i++) for(j = 0; j < 114; j++); } /** * 发送启动信息 */ void SendWelcomeMessage(void) { UART_SendString("\r\n"); UART_SendString("=== HL-1 MASTER CONTROLLER ===\r\n"); UART_SendString("Function: K1 -> Slave LED Control\r\n"); UART_SendString("Press K1 to toggle slave LED1\r\n"); UART_SendString("================================\r\n"); UART_SendString("\r\n"); } /** * 主函数 */ void main(void) { // 初始化串口 UART_Init(); // 发送启动信息 SendWelcomeMessage(); while(1) { // 检测按键状态变化 if(KEY_K1 != last_key_state) { DelayMs(10); // 按键消抖 if(KEY_K1 != last_key_state) { last_key_state = KEY_K1; if(KEY_K1 == 0) // 按键按下 { UART_SendByte('L'); // 发送LED亮命令 UART_SendString(" - LED ON command sent\r\n"); } else // 按键释放 { UART_SendByte('O'); // 发送LED灭命令 UART_SendString(" - LED OFF command sent\r\n"); } } } DelayMs(1); // 降低CPU占用率 } }

3.2 从机程序(Slave)

#include <reg52.h> /** * 串口初始化 */ void UART_Init(void) { SCON = 0x50; // 串口方式1 TMOD = 0x20; // 定时器1方式2 TH1 = 0xFD; // 9600波特率 TL1 = 0xFD; TR1 = 1; // 启动定时器1 ES = 1; // 允许串口中断 EA = 1; // 允许总中断 } /** * 毫秒级延时函数 * @param ms 延时毫秒数 */ void DelayMs(unsigned int ms) { unsigned int i, j; for(i = 0; i < ms; i++) for(j = 0; j < 114; j++); } /** * 主函数 */ void main(void) { // 初始化串口 UART_Init(); P1 = 0xFF; // 初始化所有LED灭 // 启动指示灯 P1 = 0xFE; // LED1亮一下 DelayMs(300); P1 = 0xFD; // LED2亮一下 DelayMs(300); P1 = 0xFF; // 所有LED灭 while(1) { // 主循环为空,等待串口中断 // 可在此处添加其他任务 } } /** * 串口中断服务函数 * interrupt 4 表示串口中断 */ void UART_ISR(void) interrupt 4 { unsigned char received_char; if(RI) // 接收中断 { RI = 0; // 清除接收标志 received_char = SBUF; // 读取接收到的字符 // 根据命令控制LED switch(received_char) { case 'L': // LED亮命令 case '1': P1 &= 0xFE; // LED1亮 (P1.0 = 0) break; case 'O': // LED灭命令 case '0': P1 |= 0x01; // LED1灭 (P1.0 = 1) break; case 'A': // 所有LED亮 case 'a': P1 = 0x00; // 所有LED亮 break; default: // 无效命令,不做处理 break; } } if(TI) // 发送中断(本程序不使用) { TI = 0; } }

4. 编译与烧录

4.1 开发环境配置

  1. 编译器:Keil uVision 5
  2. 编译器设置:选择C51编译器
  3. 目标芯片:STC89C52

4.2 编译步骤

  1. 创建新工程,选择STC89C52芯片
  2. 添加源文件,编写代码
  3. 设置编译选项
  4. 编译生成HEX文件

4.3 烧录步骤

  1. 使用烧写器
  2. 选择正确的COM端口
  3. 载入生成的HEX文件
  4. 点击下载,然后给开发板上电

5. 测试与调试

5.1 硬件测试

  1. 确保USB线连接正常
  2. 确认CH340驱动已安装
  3. 检查杜邦线连接是否正确
  4. 验证电源指示灯正常

5.2 软件测试

  1. 使用串口调试助手监控通信
  2. 测试按键响应
  3. 观察LED状态变化
  4. 测试通信稳定性

5.3 串口调试助手设置

端口:COMx(根据实际选择) 波特率:9600 数据位:8 停止位:1 校验位:None 流控制:None

6. 常见问题与解决方案

6.1 通信失败

现象:按键按下后从机LED无反应
解决方法

  1. 检查TXD和RXD是否交叉连接
  2. 确认波特率设置一致(9600)
  3. 检查地线是否连接
  4. 验证串口线是否完好

6.2 按键响应不稳定

现象:需要多次按键才能触发
解决方法

  1. 增加消抖延时时间
  2. 优化按键扫描算法
  3. 检查按键硬件连接

6.3 LED不亮

现象:发送命令后LED不亮
解决方法

  1. 确认LED连接在P1.0
  2. 检查LED方向是否正确
  3. 验证LED限流电阻是否正常

7. 功能扩展

7.1 多按键控制

可以扩展为多个按键控制多个LED:

// 扩展为4个按键控制4个LED sbit KEY_K2 = P3^5; sbit KEY_K3 = P3^6; sbit KEY_K4 = P3^7;

7.2 协议升级

实现更复杂的通信协议:

// 帧格式:帧头 + 命令 + 数据 + 校验 // 0xAA 0x55 CMD LED_NUM CHECKSUM

7.3 状态反馈

从机向主机发送状态反馈:

// 从机收到命令后回复 void SendResponse(unsigned char status) { SBUF = status; while(!TI); TI = 0; }

8. 项目总结

本项目通过学习板实现了基本的串口通信功能,具有以下特点:

8.1 技术要点

  1. 串口通信:掌握了51单片机串口通信的基本原理
  2. 中断应用:学习了串口中断的使用方法
  3. 按键处理:掌握了按键消抖和状态检测技术
  4. 协议设计:了解了简单的通信协议设计

8.2 学习收获

  1. 理解主从机通信的基本概念
  2. 掌握串口通信的硬件连接方法
  3. 学会使用串口调试工具
  4. 能够独立完成简单的通信项目

8.3 应用前景

本项目为基础,可扩展为:

  • 智能家居控制系统
  • 工业监控系统
  • 机器人控制系统
  • 物联网终端设备


版权声明:本文为原创内容,转载请注明出处

关键词:HL-1学习板、STC89C52、串口通信、单片机、按键控制、LED控制、51单片机

技术标签#单片机#串口通信#STC89C52#HL-1#嵌入式开发

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/6 15:21:28

28、网络数据分类与回归分析技术详解

网络数据分类与回归分析技术详解 1. 引言 在网络数据分析领域,分类和回归是两种重要的技术手段。分类可用于确定网络参数所属的类别,而回归则能预测特定变量在未来某个时间点的值。本文将详细介绍基于KNN、多层感知器(MLP)的分类方法,以及基于滑动窗口的多元线性回归(M…

作者头像 李华
网站建设 2026/8/6 15:20:07

Unity反向遮罩技术深度解析与应用实践

Unity反向遮罩技术深度解析与应用实践 【免费下载链接】UIMask Reverse Mask of Unity "Mask" component 项目地址: https://gitcode.com/gh_mirrors/ui/UIMask 在Unity用户界面开发领域&#xff0c;遮罩技术作为视觉呈现的重要工具&#xff0c;其功能特性直接…

作者头像 李华
网站建设 2026/8/6 7:37:59

多模态大模型新突破:Janus-Pro-7B重构跨模态理解与生成范式

在人工智能多模态交互领域&#xff0c;DeepSeek团队于2025年1月28日正式发布的Janus-Pro-7B模型引发行业高度关注。这款基于70亿参数构建的多模态大模型&#xff0c;通过创新的自回归框架设计&#xff0c;成功实现了视觉理解与图像生成能力的深度融合&#xff0c;为下一代智能交…

作者头像 李华
网站建设 2026/8/6 8:36:05

13、系统管理:用户管理脚本实用指南

系统管理:用户管理脚本实用指南 在系统管理中,管理用户和磁盘空间是非常重要的任务。本文将介绍一些实用的脚本,帮助你更好地管理磁盘配额、查看磁盘使用情况以及实现安全的文件查找功能。 1. 磁盘配额管理脚本 1.1 fquota 脚本 fquota 脚本用于检查用户的磁盘使用情况…

作者头像 李华
网站建设 2026/8/7 0:57:37

PyQt-Fluent-Widgets 现代桌面应用开发终极指南

PyQt-Fluent-Widgets 现代桌面应用开发终极指南 【免费下载链接】PyQt-Fluent-Widgets A fluent design widgets library based on C Qt/PyQt/PySide. Make Qt Great Again. 项目地址: https://gitcode.com/gh_mirrors/py/PyQt-Fluent-Widgets 还在为传统PyQt界面设计繁…

作者头像 李华
网站建设 2026/8/5 3:36:25

Duplicity:高效《缺氧》存档编辑器助力玩家打造个性化殖民地

还在为《缺氧》游戏中复制人属性不理想而烦恼吗&#xff1f;想要调整资源分布却不知从何下手&#xff1f;Duplicity存档编辑器正是你需要的解决方案。这款基于Web的本地运行工具让《缺氧》存档编辑变得简单直观&#xff0c;为玩家提供个性化游戏体验的强大支持。 【免费下载链接…

作者头像 李华