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

嵌入式之硬件学习(三)通信方式、串口通信

目录

一、通信种类

1、并行通信

2、串行通信

3、单工模式(Simplex Communication)

4、半双工通信(Half-Duplex Communication)

5、全双工通信(Full-Duplex Communication)

6、串行的异步通信与同步通信

(1)异步通信

(2)同步通信

二、串行口通信

(一)UART定义(串行通信协议)

(二)串口通信通信时序(底层逻辑)

1、空闲时

2、起始位

3、数据位

4、校验位

5、停止位

6、简述串口通信的通信逻辑(面问)

(三)波特率(bps)

三、三种串行通信方式在物理表现形式的不同

(一)TTL(Transistor-Transistor Logic)

(二)RS232标准

(三)RS485标准

四、串行口寄存器

(一)SBUF寄存器(串行口数据缓冲寄存器)

(二)串行口控制寄存器SCON

(三)电源控制寄存器PCON

五、USB下载电路模块

六、练习(实现51单片机与电脑之间的通信)

uart.c

main.c

xdata 的作用

计算定时器初值的计算公式

七、MODBUS通信协议

一、通信种类

1、并行通信

        并行通信是指多个比特同时通过并行线进行传输,这种方式的传输速率较高,但会占用大量的芯片资源;

2、串行通信

        串行通信是指将数据拆分成一个个比特,按照先后次序在一根总线上进行发送,串行通信有着系统占用资源少,结构简单等优点,是主机间通信的常用方式。

注:串口通信(Serial Port)是串行通信的一种,属于串行通信中的异步通信。我们经常听到的RS232、RS485、RS422都是串行通信。

3、单工模式(Simplex Communication)

        主机间通信时如果一方固定为发送端另外一方固定为接收端,通过一根总线实现数据通信。这种通信方式就像是你只能听别人说话,但无法回答他们一样,只能单向传递信息。

4、半双工通信(Half-Duplex Communication)

        半双工通信是一种通信方式,其中数据传输可以在两个方向之间交替进行,但不能同时进行。换句话说,通信双方可以既发送数据又接收数据,但不能同时进行这两种操作。比方说,就像你可以和别人交替说话和倾听对方说话一样。当你在说话时,对方在听你说;当对方在说话时,你在倾听对方。这种方式允许双方之间在发送和接收数据之间切换,但不能同时进行。半双工通信常用于对话式交流和一些简单的通信场景中。

5、全双工通信(Full-Duplex Communication)

        全双工通信是一种通信方式,其中数据传输可以同时在两个方向进行,允许通信双方同时发送和接收数据,实现双向通信。就像打电话一样,你可以同时说话也可以听对方说话,双方可以同时进行数据传输,实现双向沟通。

6、串行的异步通信与同步通信

(1)异步通信

        指通信中两个字符(8位)之间的时间间隔是不固定的,而在一个字符内各位的时间间隔是固定的;
        收发双方的波特率必须是事先约定好的;

(2)同步通信

        要求发收双方具有同频同相的同步;
        用专用时钟信号线来控制时钟的节奏,以为例:

  • SDA(数据线)
  • SCL(时钟线):用于同步双方时钟的节奏,一般由发送方决定;

      异步通信

        串口通信时,收发双方的波特率必须是事先约定好的,否则数据传输就会出现混乱。很明显,为保证每个比特占用数据线的时间,发送方和接收方需按照各自的系统计时且双方之间的误差不能太大。通常不能超过(6%)。这种双方各自“计时”的方式称为异步。就好比在打字一样,每次敲击键盘发送一个字母,速度快慢由打字者自己控制,没规定每敲击一个字母之间要等多久,只要保证接收端能够正确识别并解析即可。

同步通信

        同步通信设备之间除了有数据线(SDA)以为还有一条时钟线(SCL)。其中SCL就是时钟线(serial clock)。发送方负责控制时钟线的变化,每发送一个比特,都需要将时钟线按照规则进行改变。就好比在合唱团里,大家一起唱歌的节奏是由指挥员指挥的,每个人都按照指挥员的节奏唱歌,保证大家唱的是同一首歌且节奏一致。这种通信方式就称为同步通信。譬如IIC、SPI等。

注:同步串行通信方式与异步串行通信方式的区别:存在时钟线的为同步串行

通信方式通信,没有时钟线的为异步串行通信方式。

二、串行口通信(全双工串行通信,异步通信)

(一)UART定义(串行通信协议)

        UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一种广泛使用的串行通信协议。它用于在计算机或其他设备之间传输数据。UART通信协议通过两根线(通常称为TXD和RXD)实现数据的异步传输。

TXD(Transmit,发送)线:用于从设备发送数据到另一设备。

RXD(Receive,接收)线:用于从另一设备接收数据到本设备。

(二)串口通信通信时序(底层逻辑)

作为常用的串行通信方式,以TTL为例,串口通信在不同主机之间的数据格式为:

1、空闲时

        空闲时数据线为高电平;

2、起始位

        发送放发送一个低电平表示起始位;

3、数据位

        依据低位先行原则(发送的第一个比特是最低位(最右边))发送;

4、校验位

        分为奇校验,偶校验和无校验;校验位可发可不发

                奇校验是指确保数据位加上校验位中"1",1的总数为奇数;

                偶校验是指确保数据位加上校验位中"1",1的总数为偶数;

5、停止位

        为保证下一个字节发送前的起始位能够表现出来(把两个数据二者之间分隔开),校验位之后发送一个停止位1。(停止位也可是1个、1.5个、2个)

6、简述串口通信的通信逻辑(面问)

        双方在空闲时数据线保持高电平;发送数据时发送方先要发送一个起始位,起始位为低电平;发送数据位(8个bit)以低位先行原则发送(从右往左发);发完后有一个可以选择的校验位,校验分三种,分别为奇校验、偶校验、无校验,奇校验是数据位加校验位中1的个数总数为奇数,偶校验数据位加校验位1的总数为偶数;校验位结束后还要发送一个停止位,停止位为高电平。    

(三)波特率(bps)

串口通信用波特率来描述数据的传输速率问题:

        很明显上图的纵坐标为电压值,横坐标就是时间了。无论起始位、数据为还是停止位、校验位,每个比特在数据线上的时间决定了数据传输的速率。

        串行通信用波特率(bit per second)来描述数据传输的速率,记作bps。

        常见的波特率有1200、2400,4800,9600,115200等,表示每秒钟传输的比特数。以9600为例,表明每秒能传输9600个比特。每个比特传输时所需的时间为1/9600秒=1.041*10-4秒。

三、三种串行通信方式在物理表现形式的不同

        主机间通信无论采用并行还是串行方式,都无法避免一个物理现象:导线内阻不为零造成的电压衰减。以之前讨论的TTL电平为例,主机之间的距离会造成高电平在接收端出现衰减现象和串扰(指不同信号之间相互干扰导致信号失真)影响。

(一)TTL(Transistor-Transistor Logic)

        TTL(Transistor-Transistor Logic)通常指的就是芯片引脚产生的电压,这个电压值跟选择的芯片有关,在51单片机系统下是5v;在2440下是3.3v等等。5vTTL通信距离通常被限制在10~20米之间。(使用TTL方式进行数据传输距离受到很大限制)

        逻辑0:0V低电压

        逻辑1:取决于芯片本身(供电电压)

(二)RS232标准

        5vTTL通信距离通常被限制在10~20米之间,如果需要更远的距离,怎么解决呢?为解决这个问题IEEE(Institute of Electrical and Electronics Engineers)颁布了RS232标准,其中规定了:

逻辑高电平(逻辑1):在-3V到-15V之间

逻辑低电平(逻辑0):在+3V到+15V之间

收发主机间有三根线,分别是收、发和地,因此RS232是全双工的。

理论上RS232能够传输20~30米。

(三)RS485标准

        同理RS485使用两根信号线(A和B)来传输数据,通过比较A和B之间的电压差来识别信息,电压范围分别为+7V到+12V和-7V到-12V。正电压表示高电平,负电压表示低电平。这种差分信号传输方式提高了抗干扰能力。RS485的传输距离可达1200米,适用于大范围的数据传输需求。由于采用的是压差,RS485在传输数据的某一时刻,两根线都要用到,所以它是半双工的。

比较A和B之间的电压差:

        逻辑1:+7V到+12V

        逻辑0:-7V到-12V

四、串行口寄存器

(一)SBUF寄存器(串行口数据缓冲寄存器)

(二)串行口控制寄存器SCON

(三)电源控制寄存器PCON

五、USB下载电路模块

六、练习(实现51单片机与电脑之间的通信)

uart.c

 void init_uart(void)
 {
 //串口接收
    SCON &= ~(3 << 6);
    SCON |= (1 << 6) | (1 << 4);

 //使参数生效
    PCON &= ~(1 << 6);
    PCON |= (1 << 7); 

 //设置波特率,51单片机使用定时器1
    TMOD &= ~(0x0F << 4);
    TMOD |= (2 << 4); //1<<5 与其效果是一样的,改变第四位和第五位,2为0000 0010
    TL1 = 232;//计算出的定时器初值
    TH1 = 232;

 //    打开定时器1
    TCON |= (1 << 6);

//打开中断控制位及串口控制位
    IE |= (1 << 7) | (1 << 4);
}
/*
//全局变量字符型数组
char rcv_buffer[32];
*/
//数组不放到内部RAM放到外部扩展RAM(扩展内存不清0,数组内都是随机数)
xdata char rcv_buffer[32];
unsigned int pos = 0;

//中断服务函数(TI RI都会导致中断);接收需要使用中断
 void uart_handler(void) interrupt 4
 {
     if((SCON & (1 << 0)) == 1) 
    {
        if(pos < 32) //防止越界访问
        {
            rcv_buffer[pos++] = SBUF;//接收的数据依次存入到该数组
            rcv_buffer[pos] = 0; //接收的字符串后加/0标志
        }
        //P2 = SBUF;
        SCON &= ~(1 << 0);//软件复位RI(接收中断请求标志位)清0
    }
 }

 //发送(轮询)
 void send_char(char ch)
 {
    SBUF = ch;
    while((SCON & (1 << 1)) == 0);
    SCON &= ~(1 << 1);    //软件复位TI(发送中断请求标志位)清0
 }

void send_buffer(const char *p, unsigned int len)
{
    while(len--)
    {
        send_char(*p++);
    }
}

  // 发送字符串函数 
  void send_str(const char *str) 
  { 
      unsigned int len = 0;
    while (str[len] != '\0') // 计算字符串长度 
    { 
           len++; 
    } 
    send_buffer(str, len); // 调用send_buffer函数发送字符串
  }
 

main.c

int main(void)
{
    const char *s = "Hello World!"; //不常用
    //char buffer[] = {0xAA ,0xBB, 0x00, 0x1A};
    xdata char buffer[16]; //???
    init_uart();
    while(1)
    {
         if(pos != 0)//至少收到一个字节
         {
             delay(0xAFFF);//保证数据全部收完,有延迟
            if(strcmp(rcv_buffer,"Hello") == 0)
            {
                send_str("Hi");
            }
            else if(strcmp(rcv_buffer,"See You Later") == 0)
            {
                send_str("Bye");
            }
            /*
            send_buffer(rcv_buffer, pos);
            */
            pos = 0;//保证下一轮从头开始收    
         }
           //send_buffer(buffer, sizeof(buffer) / sizeof(*buffer));
           //send_buffer(s,strlen(s));
         //send_char('A');
         //delay(0xAFFF);
    }
}

xdata 的作用

        不将内容放在芯片内部的RAM中,放在扩展的RAM中 ;

计算定时器初值的计算公式

        2^8-2^smod * focs / 32 / bps / 12

其中smod表示PCON的B7,根据实际情况带入,不是0就是1(SMOD=1波特率翻倍);

focs晶振频率,我们这是11.0592M;

bps目标波特率我们这是2400

2^8 这里的8来自定时器的工作方式,因为我们使用的是8位自动重装方式,所以是8

按照我们的要求2400bps,smod=1时,该公式计算结果为:232。

七、MODBUS通信协议

modbus协议:

                unsigned char s[xx] = ......

        该协议对数组每个元素内容都做了定义

相关文章:

  • RK3568笔记八十四:rtmp转rtmp直播流测试
  • 亚矩阵云手机+Whatnot:直播电商的自动化增长引擎
  • iOS多端兼容性调试:一次iOS性能优化分工具协作排查过程
  • 上线iOSApp前抓包工具协作保障接口行为一致性(iOS抓包)
  • spring-webmvc @InitBinder 典型用法
  • 《前端面试题:数组操作》
  • PID控制电机
  • springboot入门之路(二)
  • 技术赋能教师专业发展:从理论到实践的深度剖析
  • createInnerAudioContext播放不完整?
  • 榕壹云外卖跑腿系统:基于Spring Boot的开源生活服务平台技术解析
  • STM32 GPIO 寄存器开发
  • OCCT基础类库介绍:Modeling Algorithm - Topological Tools
  • 今天我想清楚了
  • 无需公网IP:Termux+手机+内网穿透实现Minecraft远程多人联机
  • 基于大数据技术的在UGC数据分析与路线推荐的研究
  • ArcGIS中利用泰森多边形法分析站点与流域占比
  • VTK知识学习(54)- 交互与Widget(五)
  • ES 索引加载 vs BulkLoad
  • function ‘as_cholmod_sparse‘ not provided by package ‘Matrix‘
  • 美团网站怎么做/口碑营销的缺点
  • 用织梦做网站调用乱码/上海最新新闻事件今天国内
  • 政府网站建设参考书/四川seo平台
  • 做网站写代码好还是模板/百度电脑端入口
  • 周口做网站建设/开发网站的流程是
  • 西宁网络公司网站建设/seo优化关键词排名优化