【单片机】12-串口通信和RS485

1.通信有关的常见概念

区分:串口,COM口,UART,USART_usart和串口区别-CSDN博客

串口、COM口、UART口, TTL、RS-232、RS-485区别详解-CSDN博客

1.什么是通信

(1)人和人之间的通信:说话,写信

(2)人和计算机之间的通信:按键,显示器,鼠标

(3)计算机和计算机之间的通信

2.通信的关键

(1)事先约定

(2)基本的信息单元

(3)有效信息的编码,传输和解码

3.通信的专业性概念

(1)同步和异步:同一个步调

(2)单工,半双工,全双工:数据传输方向

(3)并行和串口:并行(多根线),串行(单根线)

(4)电平信号【传输近,易受干扰】和差分信号【传输远,不易受干扰】:电平是通过高低电平进行区分,差分是相对的

2.串行通信

1.串口通信基础

(1)一种特定的通信协议【电平通信】

(2)串行通信,串口通信,UART,USART

(3)串口通信的特点:异步,串行,全双工

2.串行通信的主要用途

(1)早期:计算机之间短距离通信(1.5米内),完备通信机制

(2)现在:CPU之间近距离通信【CPU和周边芯片】,调试信息输入输出非完备通信

3.串行通信的工作方式

(1)3根线(GND,RxD【接收线】,TxD【发送线】---recive ,transmit)---不完备通信

或者9根线(DB9)-完备通信

(2)发送方有发送位移寄存器,接收方有接收移位寄存器

(3)数据在发送方和接收方的CPU中都以字节为单位整字节处理

(4)数据在通信线上以位为单位逐个bit的传输

4.串行通信的主要概念

传输都是一帧一帧的发

1.起始位

开始之前要发送一个起始位

2.数据位

比如我们传输“A”,转换为ASCII就是8位二进制,这8位就叫做8位数据位【有效数据】

数据位要双方沟通确定的

3.奇偶校验位

判断传输过程中是否出错

4.停止位(帧)

判断是否结束

5.波特率

串行通信的速度

一秒钟传输多少给bit位,发送方和接收方必须波特率设置为一样【波特率越小,传输速度慢,抗干扰能力越强】

6.流控

速率协商,现在一般要禁用掉

3.51单片机的串行通信

1.基础概念

SoC:把CPU以及其他功能集成到一个芯片上

(1)串行通信功能是SoC的一个(内部)外设提供的,与CPU无关【CPU=运算器+控制器】--CPU本身无法通信

(2)各种不同的SoC的串行通信大同小异【内部差不多,编程时候可能不同】

(3)串行通信经常作为主控SoC与其他外部芯片之间的通信接口【串行通信==SoC与外部其他芯片的通信】

2.STC51单片机的串行通信简介

4.STC51的串行通信相关寄存器

1.总体浏览

2.SCON:串行控制寄存器

3.SBUF:串行口缓存寄存器

4.PCON:电源控制寄存器

5.IE:中断允许寄存器

6.串口发送时的软硬件协作方式

(1)查询方式。硬盘在发送完一帧数据后会将一个标志位置位(标志位本来是0),软件需要不断读取这个标志位的值来判断硬件是否完成了发送(如果读出来的是0就表示硬件还在发还在发还没完还在忙,所以我们就不能认为硬件发完了,所以就不能给硬件安排下一帧数据的发送;如果读出来的是1则说明硬件已经发完了上一帧数据,这时候软件就应该给硬件在给一帧数据去发送)

(2)因为串口发送完这个事件对CPU来说是个异步事件(因为不知道什么时候发送消息),所以这里查询方式来处理和之前讲过的查询方式处理按键是非常类似的。

(3)常见情况下:串口发送会使用查询方式,串口接收会使用中断方式【因为不知道什么时候会接收到信息,使用中断才不会过度销毁CPU】

7.波特率加倍

PCON中的SMOD

所谓波特率加倍,就是正常计算出的波特率假设是2400,那么SMOD=1时则实际波特率就是4800;当SMOD=0时不加倍,也就是2400还是2400

5.STC51的串行通信实战

1.硬件接线分析

(1)目标:将PC机和51单片机通过串口连接起来

(2)PC机的串口情况:台式机串口,笔记本USB转串口

(3)开发板原理图分析

2.接线方案

1.使用板载CH340

什么都不用动,默认就是使用这个,最简单最省事,最推荐

2.使用DB9接口USB转串口线

用DB9接口的USB转串口线

注意:跳线帽接到DB9一侧

3.使用TTL接口USB转串口线

只接三根线:TxD,RxD,GND

4.总结

3.使用板载CH340进行串口实践

1.接线+下载程序

2.查看设备管理器确定COM号

3.方法一:使用普中下载软件自带的串口助手监视

4.方法二:使用第三方串口助手软件监视

5.方法三:使用SecureCRT软件监视

4.使用DB9接口USB转串口线

1.接线+下载程序

2.注意对下载程序的影响

此时无法进行程序下载

3.使用各种方式进行监视

5.串口初始化

//串口初始化函数
//预设一个串口条件:8位数据位,1停止位,0校验位,波特率4800
//初始化的主要工作就是去设置相关的寄存器
void uart_init(void){SCON=0x50; //串口工作在模式1(8位串口),允许接收PCON=0x80;   //波特率加倍,意思是本来需要波特率4800,等一下计算时按照2400去计算就好}

6.波特率计算

SMOD---》判断是否进行波特率加倍【如果加倍则为1,不加倍则为0】

 查看数据手册中”串行通信中波特率的设置“

接着查看定时/计数器1的工作方式2的寄存器设置情况

TMOD=0x20;  //设置T1为模式2

TR1=1;        //开启T1让它开始工作

我们刚刚在上面计算出TH1=243;,所以进行设置

TH1=243;
TL1=243;   //8位自动重装,意思就是TH1用完了下一个周期TL1会自动重装到TH1中

 




7.串口发送字符【单个字符】

注意点:51单片机不一样,要先发送在检验有没有在发送

其他MCU都是先检验在发送

如果为【0】则表示在忙,如果为【1】则表示发送结束

//串口发送函数,发送一个字节
void uart_send_byte(unsigned char c){//【第一步】发送一个字节SBUF=c;//【第二步】先确认串口发送部分没有在忙while(!TI);//TI=0,表示在忙//【第三步】软件复位TI标志位---数据手册要求的TI=0;
}

8.测试一下

1.波特率不加倍

#include<reg51.h>//函数声明
void uart_init(void);
void uart_send_byte(unsigned char c);
void delay();void main(){//第一步:初始化好串口到正确的状态uart_init();while(1){//为了调试方便,让A循环发送,才好监视//第二步:通过串口发送信息出去uart_send_byte('A');delay();}}void delay(){unsigned char i,j;for(i=0;i<100;i++){for(j=0;j<200;j++);}
}//串口初始化函数
//预设一个串口条件:8位数据位,1停止位,0校验位,波特率4800
//初始化的主要工作就是去设置相关的寄存器
void uart_init(void){//波特率不加倍的例子SCON=0x50; //串口工作在模式1(8位串口),允许接收PCON=0x00;   //波特率不加倍//通信波特率相关的设置//此处我们使用【方式1】---对应数据手册TMOD=0x20;  //设置T1为模式2TR1=1;	//开启T1让它开始工作TH1=249;TL1=249;    //8位自动重装,意思就是TH1用完了下一个周期TL1会自动重装到TH1中//中断初始化ES=1;//串口中断初始化EA=1;//整个中断初始化}//串口发送函数,发送一个字节
void uart_send_byte(unsigned char c){//【第一步】发送一个字节SBUF=c;//【第二步】先确认串口发送部分没有在忙while(!TI);//TI=0,表示在忙//【第三步】软件复位TI标志位---数据手册要求的TI=0;
}

因为我们算出来的TH1和TL1=6.5,所以精确度可能会受到影响,我们将其设置为250 或者 249则结果都会输出乱码

2.换一个波特率:9600

我们前面算出TH1=6.5【这里我们的波特率为4800】,所以如果为9600则我们应该将【6.5/2=3.25】才是我们9600的结果


//波特率为9600SCON=0x50; //串口工作在模式1(8位串口),允许接收PCON=0x00;   //波特率不加倍//通信波特率相关的设置//此处我们使用【方式1】---对应数据手册TMOD=0x20;  //设置T1为模式2TR1=1;	//开启T1让它开始工作TH1=253;TL1=253;    //8位自动重装,意思就是TH1用完了下一个周期TL1会自动重装到TH1中//中断初始化ES=1;//串口中断初始化EA=1;//整个中断初始化

9.串口发送字符串【多个字符】

#include<reg51.h>//函数声明
void uart_init(void);
void uart_send_byte(unsigned char c);
void delay();
void uart_send_string(unsigned char *str);void main(){//第一步:初始化好串口到正确的状态uart_init();while(1){//发送字符串,也可以发送中文uart_send_string("abcdefg");delay();}}void delay(){unsigned char i,j;for(i=0;i<100;i++){for(j=0;j<200;j++);}
}//串口初始化函数
//预设一个串口条件:8位数据位,1停止位,0校验位,波特率4800
//初始化的主要工作就是去设置相关的寄存器
void uart_init(void){//波特率加倍的例子SCON=0x50; //串口工作在模式1(8位串口),允许接收PCON=0x80;   //波特率加倍,意思是本来需要波特率4800,等一下计算时按照2400去计算就好//通信波特率相关的设置//此处我们使用【方式1】---对应数据手册TMOD=0x20;  //设置T1为模式2TR1=1;	//开启T1让它开始工作TH1=243;TL1=243;    //8位自动重装,意思就是TH1用完了下一个周期TL1会自动重装到TH1中//中断初始化ES=1;//串口中断初始化EA=1;//整个中断初始化}//串口发送函数,发送一个字节【单个字节】
void uart_send_byte(unsigned char c){//【第一步】发送一个字节SBUF=c;//【第二步】先确认串口发送部分没有在忙while(!TI);//TI=0,表示在忙//【第三步】软件复位TI标志位---数据手册要求的TI=0;
}//发送字符串【多个字符】
void uart_send_string(unsigned char *str)
{while (*str != '\0'){uart_send_byte(*str);		// 发送1个字符str++;						// 指针指向下一个字符}
}

10.串口接收函数编写

因为我们在程序执行过程中如果要接收PC机传输过来的数据,则表示程序要进行中断,则要进行中断处理。

void uart_isr(void) interrupt 4 using 1{
}

#include<reg51.h>//函数声明
void uart_init(void);
void uart_send_byte(unsigned char c);
void delay();
void uart_send_string(unsigned char *str);void main(){//第一步:初始化好串口到正确的状态uart_init();uart_send_string("串口回环测试\n");while(1);
}void delay(){unsigned char i,j;for(i=0;i<100;i++){for(j=0;j<200;j++);}
}//串口初始化函数
//预设一个串口条件:8位数据位,1停止位,0校验位,波特率4800
//初始化的主要工作就是去设置相关的寄存器
void uart_init(void){//波特率加倍的例子SCON=0x50; //串口工作在模式1(8位串口),允许接收PCON=0x80;   //波特率加倍,意思是本来需要波特率4800,等一下计算时按照2400去计算就好//通信波特率相关的设置//此处我们使用【方式1】---对应数据手册TMOD=0x20;  //设置T1为模式2TR1=1;	//开启T1让它开始工作TH1=243;TL1=243;    //8位自动重装,意思就是TH1用完了下一个周期TL1会自动重装到TH1中//中断初始化ES=1;//串口中断初始化EA=1;//整个中断初始化}//串口发送函数,发送一个字节【单个字节】
void uart_send_byte(unsigned char c){//【第一步】发送一个字节SBUF=c;//【第二步】先确认串口发送部分没有在忙while(!TI);//TI=0,表示在忙//【第三步】软件复位TI标志位---数据手册要求的TI=0;
}//发送字符串【多个字符】
void uart_send_string(unsigned char *str)
{while (*str != '\0'){uart_send_byte(*str);		// 发送1个字符str++;						// 指针指向下一个字符}
}//中断处理程序
void uart_isr(void) interrupt 4 using 1
{unsigned char tmp;if(RI){tmp=SBUF;   //读取SBUF,其实就是读出串口接收到的1个字节//RI:串行口1接收中断标志RI=0;}//自此已经读到了PC发给单片机的一个字节,但是单片机没有显示器无法显示//我们用最简单的方法,就是直接回发uart_send_byte(tmp);
}

6.RS485

1.UART的缺点:传输距离受限

(1)理论上RS232不超过15米--电脑的COM端口【DB9】

(2)理论上TTL电平通信距离更短---TTL是在单片机上使用

(3)实际上几百米也有人宣称做到了,但是稳定性不能保证

(4)波特率越高通信距离越短【速度越快,通信距离越短】

2.远距离传输

(1)提高电压标准

(2)提高通信线抗干扰能力,降低阻抗

(3)使用差分信号--抗干扰能力强【RS485/RS422】

3.RS485(RS422)

(1)最大通信距离1200多米,最快通信速率10Mbps,距离和速度成反比(USB接口,网线)

(2)差分信号负逻辑【5V代表---0     -3V代表----1】

(3)更远距离可以加中继器【中继器---多个485的节点连接起来--放大】

(4)半双工【如果要实现全双工,则使用4根线】

(5)RS485只提高物理层通信能力,不提供数据层协议,需要用户自定义,或者使用标准协议如MODBUS协议。

4.MAX485

MAX485就是相当于UART与RS485之间的信号转换

(1)CPU本身只会提供URAT接口,而不会提供RS485接口。CPU根本不认识RS485

(2)RS485使用场景:CPUA-->UART转RS485------>远距离通信----->RS485转UART---->CPUB

(3)对RS485的理解:RS485是纯硬件实现的,硬件芯片如MAX485来管理的,根本不涉及软件编程。软件工程师只关注串口,只通过串口将数据发送出去或者接收回来即可。UART转485和485转UART对CPU来说是透明的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/146016.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

抓包习讯云院校数据通过PHP解析导入数据库

前言 最近&#xff0c;打卡APP需要这个数据&#xff0c;通过抓包后发现这个数据是固定的&#xff0c;获取很简单&#xff0c;但是数据太多&#xff0c;手动导入不显示&#xff0c;于是分析了json格式后果断通过脚本完成 【推荐】 《【MQTT】Esp32数据上传采集&#xff1a;最…

栈和队列的概念和实现

栈和队列的概念和实现 一.栈二.队列一些题目 一.栈 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作&#xff0c;进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底&#xff0c;栈中的数据元素遵守后进先出LIFO&#x…

UG\NX二次开发 用程序修改“用户默认设置”

文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 简介 可以用程序修改“用户默认设置”吗?下面是用代码修改“用户默认设置->基本环境->用户界面->操作记录->操作记录语言”的例子。 效果 代码 #include <uf_defs.h> #include <NXOpen/NXExcept…

angular 在vscode 下的hello world

Angulai 是google 公司开发的前端开发框架。Angular 使用 typescript 作为编程语言。typescript 是Javascript 的一个超集&#xff0c;提升了某些功能。本文介绍运行我的第一个angular 程序。 前面部分参考&#xff1a; Angular TypeScript Tutorial in Visual Studio Code 一…

Kafka-Kerberos票据刷新问题

线上kafka使用了 kerberos 认证&#xff0c;每隔24小时&#xff0c;票据过期&#xff0c;无法自动续期&#xff0c;出现消息发送失败问题。 从日志可以发现会有如下报错&#xff1a; 2023-09-14 17:48:47,144 [kafka-kerberos-refresh-thread-kafka/hdp-1HADOOP.COM] [] WARN …

gitee 远程仓库操作基础(二)

(1&#xff09;clone远端仓库,本地建立分支推送 (基于远程仓库版本库 本地建立分支开发新功能) git clone gitgitee.com:xxxxx/alsa_test.git git remote add origin gitgitee.com:xxxxx/alsa_test.git进入clone过后路径代码,查看本地分支,发现该项目远程仓库有很多分支 基于…

Spring Framework 学习笔记5:事务

Spring Framework 学习笔记5&#xff1a;事务 1.快速入门 1.1.准备工作 这里提供一个示例项目 transaction-demo&#xff0c;这个项目包含 Spring 框架、MyBatis 以及 JUnit。 对应的表结构见 bank.sql。 服务层有一个方法可以用于在不同的账户间进行转账&#xff1a; Se…

机器学习之单层神经网络的训练:增量规则(Delta Rule)

文章目录 权重的调整单层神经网络使用delta规则的训练过程 神经网络以权值的形式存储信息,根据给定的信息来修改权值的系统方法称为学习规则。由于训练是神经网络系统地存储信息的唯一途径&#xff0c;因此学习规则是神经网络研究中的一个重要组成部分 权重的调整 &#xff08…

【中秋国庆不断更】OpenHarmony多态样式stateStyles使用场景

Styles和Extend仅仅应用于静态页面的样式复用&#xff0c;stateStyles可以依据组件的内部状态的不同&#xff0c;快速设置不同样式。这就是我们本章要介绍的内容stateStyles&#xff08;又称为&#xff1a;多态样式&#xff09;。 概述 stateStyles是属性方法&#xff0c;可以根…

蓝桥等考Python组别十级003

第一部分&#xff1a;选择题 1、Python L10 &#xff08;15分&#xff09; 已知s Pencil&#xff0c;下列说法正确的是&#xff08; &#xff09;。 s[0]对应的字符是Ps[1]对应的字符是ns[-1]对应的字符是is[3]对应的字符是e 正确答案&#xff1a;A 2、Python L10 &am…

NLP 03(LSTM)

一、LSTM LSTM (Long Short-Term Memory) 也称长短时记忆结构,它是传统RNN的变体,与经典RNN相比&#xff1a; 能够有效捕捉长序列之间的语义关联缓解梯度消失或爆炸现象 LSTM的结构更复杂,它的核心结构可以分为四个部分去解析: 遗忘门、输入门、细胞状态、输出门 LSTM内部结构…

解决 react 项目启动端口冲突

报错信息&#xff1a; Emitted error event on Server instance at:at emitErrorNT (net.js:1358:8)at processTicksAndRejections (internal/process/task_queues.js:82:21) {code: EADDRINUSE,errno: -4091,syscall: listen,address: 0.0.0.0,port: 8070 }解决方法&#xff…

叶工好容6-自定义与扩展

本篇主要介绍扩展的本质以及CRD与Operator之间的区别&#xff0c;帮助大家理解相关的概念以及知道要进行扩展需要做哪些工作。 CRD&#xff08;CustomerResourceDefinition&#xff09; 自定义资源定义,代表某种自定义的配置或者独立运行的服务。 用户只定义了CRD没有任何意…

最新AI智能创作系统ChatGPT商业源码+详细图文搭建部署教程+AI绘画系统

一、AI系统介绍 SparkAi创作系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧&am…

liunx的攻击

1.场景和分析 2.病毒分析 3.解决步骤

MySQL在线修改表结构-PerconaTookit工具

在线修改表结构必须慎重 在业务系统 运行 过程中随意删改字段&#xff0c;会 造成重大事故。 常规的做法是&#xff1a;业务停机&#xff0c;再 维护表结构 比如&#xff1a;12306 凌晨 0 点到早上 7 点是停机维护 如果是不影响正常业务的表结构是允许在线修改的。 比如&…

Ubuntu部署运行ORB-SLAM2

ORB-SLAM2是特征点法的视觉SLAM集大成者&#xff0c;不夸张地说是必学代码。博主已经多次部署运行与ORB-SLAM2相关的代码&#xff0c;所以对环境和依赖很熟悉&#xff0c;对整个系统也是学习了几个月&#xff0c;一行行代码理解。本次在工控机上部署记录下完整的流程。 ORB-SLA…

Vuex状态管理

一、Vuex简介&安装 简介 vuex是使用vue中必不可少的一部分&#xff0c;基于父子、兄弟组件&#xff0c;我们传值可能会很方便&#xff0c;但是如果是没有关联的组件之间要使用同一组数据&#xff0c;就显得很无能为力&#xff0c;那么vuex就很好的解决了我们这种问题&…

【数据结构】外部排序、多路平衡归并与败者树、置换-选择排序(生成初始归并段)、最佳归并树算法

目录 1、外部排序 1.1 基本概念 1.2 方法 2、多路平衡归并与败者树 2.1 K路平衡归并 2.2 败者树 3、置换-选择排序&#xff08;生成初始归并段&#xff09;​编辑 4、最佳归并树 4.1 理论基础​编辑 4.2 构造方法 ​编辑 5、各种排序算法的性质 1、外部排序 1.1 基本概…

简易磁盘自动监控服务

本文旨在利用crontab定时任务(脚本请参考附件)来监控单个服务节点上所有磁盘使用情况&#xff0c;一旦超过既定阈值则会通过邮件形式告警相关利益人及时介入处理。 1. 开启SMTP服务 为了能够成功接收告警信息&#xff0c;需要邮件接收客户都安开启SMTP服务。简要流程请参考下…