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

51单片机串口通信

串口发送功能的实现:

一、配置SCON串行口控制寄存器

1.REN:允许/禁止串口接收控制位

2.SM0=0、SM1=1:选择通讯方式一

3.TI=0、RI=0:发送接收中断标志位,每次发送后必须手动清零

二、配置PCON电源控制寄存器

SMOD:波特率选择位,SMOD=1使方式一二三波特率加倍,默认为0

(波特率越低 = 越稳定、越抗干扰、越不容易出错,但速度越慢)

三、配置定时器

串口发送时中断不需要配置,只需要配置定时器1并选择波特率

串口需要八位自动重装,不再是十六位(65535),因为十六位要每次赋初值会占用时间导致误差,串口通信要双八位更精准,计数值变为0-255(256次计数,255后还要加一位才溢出)

1.在这里我们先对特殊功能寄存器TMOD高四位清零,低四位置默认:TMOD&=0x0F

再设置高四位GATE=0;C/~T=0;M1、M0=1,0(八位重装模式):TMOD|=0x20

2.然后再设置定时器初值和是否倍速波特率,这里选倍速也就是PCON |= 0x80,然后我们这里是八位自动重装模式,不需要每次溢出重新赋初值,只需要把高低位都设置成我们的初值就好:TL1=0xF4;TH1=0xF4;

波特率计算:我们这里初值为0xF4,换算为十进制就是244,256-244=12,也就是每次溢出经过12次计数,12个1.085us,每次溢出时间=12*1.085069444=13.020833328

溢出率=1/每次溢出时间=0.07680000003145728MHZ

注意,我们这里是波特率倍速,所以不用除2,直接除16就好

波特率=溢出率/16=4800.00000196608HZ≈4800HZ,是不是几乎没有误差?如果是12MHZ晶振就会算出是4807.69MHZ,而且波特率越高误差就会越大

3.ET1=0;禁止定时器中断,这里不需要

4.TR1=1:启动定时器1

void Uart1_Init(void) //4800bps@11.0592MHz { PCON |= 0x80; //使能波特率倍速位SMOD SCON = 0x50; //8位数据,可变波特率 AUXR &= 0xBF; //定时器时钟12T模式 AUXR &= 0xFE; //串口1选择定时器1为波特率发生器 TMOD &= 0x0F; //设置定时器模式 TMOD |= 0x20; //设置定时器模式 TL1 = 0xF4; //设置定时初始值 TH1 = 0xF4; //设置定时重载值 ET1 = 0; //禁止定时器中断 TR1 = 1; //定时器1开始计时 }

当然也可以使用STC-ISP的波特率计算器自动生成初始化代码,连配置都省了:

四、串口发送函数

我们直接将数据写入SBUF即可,在写入后加上whlie判断检测发送是否完成,防止一直发送卡住,在发送后手动将发送标志位TI清零

//串口发送一个字节数据范围0-255 void UART_SendByte(unsigned char Byte) { SBUF=Byte; //写入SBUF实现数据发送 while(TI==0); //发送结束检测,防卡死 TI=0; //发送检测位清零 }

五、主函数调用

当我们需要连续发送信息时,在while循环中调用的时候要每次发送后延时,否则会由于发送过快发送错误信息,比如从66变为99,要想控制信息发送速度也可以通过延时函数粗略控制

void main() { Uartl Init (); //初始化 while(1) { UART_SendByte (0x66); //串口发送函数 Delay(100); //延时防止连续发送过快产生发送乱码 } }

程序编译烧录后打开串口,选择HEX模式,可以看到

如果我们选择文本模式,那么显示的就会是数字编码后,也就是字符原本的样子

六、串口发送模块化

串口发送可以模块化为.c.h文件方便以后调用(记得养成注释的好习惯),但是接下来讲的接收中断依赖于串口中断,和主函数耦合性较强,就没法模块化了

串口接收功能的实现:

一、串口初始化

其他都和发送一样,只需要改动几个点:

1.确保串口接收使能位为打开状态:SCON的第四位置1,也就是让SCON=0x50

(其实我们在发送时也是打开的,这里就不用改了)

2.打开串口中断:EA=1(启动中断总开关),ES=1(打开串口中断)

void Uart1_Init(void) //4800bps@11.0592MHz { PCON |= 0x80; //使能波特率倍速位SMOD SCON = 0x50; //8位数据,可变波特率 AUXR &= 0xBF; //定时器时钟12T模式 AUXR &= 0xFE; //串口1选择定时器1为波特率发生器 TMOD &= 0x0F; //设置定时器模式 TMOD |= 0x20; //设置定时器模式 TL1 = 0xF4; //设置定时初始值 TH1 = 0xF4; //设置定时重载值 ET1 = 0; //禁止定时器中断 TR1 = 1; //定时器1开始计时 EA=1; ES=1; //接收数据需要开启中断 }

二、中断函数

我们在技术手册查询到中断号小尾巴为interrupt 4,那中断函数我们命名为void UART_Routine()interrupt 4(函数名可以随便起,只要带上空格+中断号小尾巴就是中断函数啦),主函数空循环即可,这样我们就实现了电脑命令控制LED了

void UART_Routine() interrupt 4 //中断函数头 { if(RI==1) //发送完成进入后续 { P2=SBUF; //使用串口写入SBUF的数据控制LED(发送需要手动写入SBUF,接收时电脑会直接写入,不需要我们操作) UART_SendByte(SBUF); //在中断里将串口收到的数据发出 RI=0; //将接收检测位手动置零(发送位我们在函数中置零就好啦) } }
http://www.jsqmd.com/news/1237495/

相关文章:

  • 异构联盟链跨链互通的工程实现:从中继架构到接入连接器
  • 企业知识库RAG实战:用向量数据库构建精准语义检索系统
  • XXL-JOB分布式任务调度平台核心原理与实践指南
  • MCP Server:AI Agent安全高效调用业务API的标准化方案
  • Java面试突击:从八股文背诵到构建最小知识体系与问题拆解框架
  • 跨系统查数据要2天?企业AI落地的核心病根,藏在看不见的语义
  • 广州电商公司税务合规怎么做?2026电商行业合规管理与机构选型攻略 - 米諾
  • Qt的概述
  • YOLOv13涨点改进| CVPR 2026 | 独家Conv与频域改进篇| 引入SSFModule选择性空间频率模块,助力无人机航拍、遥感影像、小目标检测、语义分割、实例分割、目标跟踪任务,有效涨点
  • 郴州甲醛检测公司怎么选:只做检测不除醛的专业CMA资质实验室——国慷测研CMA甲醛检测及公共卫生检测 - CMA甲醛检测中心
  • 2026山西企业获客复盘:为什么传统SEO失效,GEO优化成主流? - 米諾
  • ElevenLabs语音合成API实战踩坑与优化指南
  • SpringBoot进阶实战:从原理到生产级应用与面试突破
  • SlowHTTPTest终极指南:如何用免费工具发现并防御慢速HTTP攻击漏洞
  • Claude Code与DeepSeek API一键安装配置指南
  • 石家庄平山县亨得利官方名表服务中心电话公示(2026年7月最新) - 亨得利官方
  • AI伦理三脚架:原则、流程与工具的落地断层解析
  • 双轴晶体的圆锥折射
  • 宁波GEO找哪家比较好?2026本地靠谱推荐与服务商分级选型指南 - 小随科技
  • Kimi K3大模型集成实战:从API接入到生产环境部署
  • LED显示屏驱动技术解析与工程实践
  • 宣城GEO找哪家比较好?2026本地靠谱推荐与服务商分级选型实战指南 - 企业新闻快传
  • 2026仲夏桐梓黄金回收全维度拆解|老牌三十年连锁盘价结算全县乡镇免费上门卖金防坑实操手册 - 华金汇黄金回收
  • 2026苏州房屋漏水维修靠谱机构TOP4:精准治漏长效保障 专业防水公司排名推荐(2026年7月防水补漏最新TOP权威排名) - 鼎万建筑修缮
  • AI 电动加热围巾智能温控功率 MOSFET 完整选型方案
  • GESP四级C++客观题实战解析:从指针内存到STL容器的解题思维
  • 3个简单步骤,用Qwerty Learner打造你的英语打字肌肉记忆训练系统
  • HarmonyOS 6.1 实战:Swiper 轮播图与页面滑动详解
  • HarmonyOS API 23 ArkTS 实战:实现一个轻量级滤镜图片预览工具
  • 仅限前500名开发者获取:2024最全AI模型RTT Benchmark数据集(含vLLM/TGI/Ollama三框架实测+硬件配置清单)