精华内容
下载资源
问答
  • 异步通信还要设置波特率?_深入理解同步/异步通信   上一篇我们解释了串口通信中同步通信和异步通信的区别,详见上篇链接。其中我们分析同步/异步通信最重要的不同点就是是否同步时钟,可能就有很多小伙伴不理解,...

    异步通信还要设置波特率?_深入理解同步/异步通信

      上一篇我们解释了串口通信同步通信异步通信的区别,详见上篇链接。其中我们分析同步/异步通信最重要的不同点就是是否同步时钟,可能就有很多小伙伴不理解,异步通信不是一字节一个字节的发送嘛?既然不同步时钟,那为什么要设置比特率?其实这是一个误导性的问题。且听我细细道来,

      


      
    理论篇
      

    1. 首先我们再次强调一下,异步通信传输是以字节为单位的,但是同步通信传输是以数据块为单位的。这里我们把数据块称为帧。帧的数据量是远远大于字节的。所以同步通信对时钟同步的要求较高。
    2.   然后异步通信是在每个字符附加起始位和停止位(有时候还会加校验位),其目的是保证位同步,就是保证发送的单位字节传输成功。发收双方都拥有独立的时钟,任何一方都不像对方提供时钟信号, 所以异步通信里波特率相差不大即可 (比如你的波特率是115200,我的是115100应该也是可以的,但是我们要是使用别人写好的串口小助手波特率都是固定的几个)。这里接收端随时准备接受数据。
        同步通信是在数据块中前部后结尾处加一个特殊的字符或者比特序列,标记一个数据块的开始和结束(一般还会加上一个校验序列如CRC),同步传输是以同步的时钟节拍来发送数据信号的,因此在一个串行的数据流中,各信号码元之间的相对位置都是固定的(即同步的)。下面实战篇通过I2C来辅助理解。
      在这里插入图片描述

      图片来自水印
      这里博主部分参考了如下链接: https://blog.csdn.net/farsight2009/article/details/53639881

    1.    所以,到这大家可能已经理解了,异步通信其实也是有时序要求的。只是要求较低,保证位同步即可,而同步通信往往有一根专门的时钟线来协调通信。

    2.   所以异步通信一般也就用于低速设备,而同步传输常用于高速设备(IIC最高传输速率400Kbps)。

      那,为什么说问题本身是有误导性的呢?

      单片机串行通信波特率就是每发送两个数据的之间的间隔,或者是每秒钟发送的字节数,你在进行串行通信时,是两个单片机进行通信,那肯定是要进行同步的(波特率要相同),要不然通信没法建立。波特率就好比一首歌曲的节奏,有了这个节奏,串行通讯的各个数据位就会有条不紊地依次排队一个一个地传到对方,要正确收发,两个通讯的主体的节奏必须一致。(此句摘自百度回答,感觉很形象)

      
      所以,你懂了嘛?皮!

      


      

    实战篇
      

      这里我我们对比一下同步通信的IIC异步通信的单总线吧,这里你能体验到同样都是半双工(不能同时收发,见上篇),同步通信时控制两根线(数据线和时钟线)有严格的时序,而异步通信一根线解决一切。
      PS:  UART是我们平时用的比较多的,详细的见上篇实战篇噢!

    • 同步通信中I2C原理简介

      数据帧的第一部分包含一组同步字符(如:i2c的起始位),它是一个独特的比特组合,类似于前面提到的起始位,用于通知接收方一个帧已经到达,但它同时还能确保接收方的采样速度和比特的到达速度保持一致,使收发双方进入同步。帧的最后一部分是一个帧结束标记(如I2C的结束位)。与同步字符一样,它也是一个独特的比特串,类似于前面提到的停止位,用于表示在下一帧开始之前没有别的即将到达的数据了。
      下图为一张I2C同步通信协议的时序(图片来自水印)
    在这里插入图片描述

    //下为I2C的几个基本时序函数,分数据线时钟线,无论是启动、停止、应答、发送、接收,对时序的要求较高,自己编写一般要参照时序图编写,同学们应该练习看懂时序图的能力。个人认为较为重要。

    #include "reg52.h"
    #include "intrins.h"
    
    #define DELAY_TIME 5
    
    /** 定义I2C总线时钟线和数据线 */
    sbit scl = P2^0;
    sbit sda = P2^1;
    
    /**
    * @brief I2C总线中一些必要的延时
    * @param[in] i - 延时时间调整.
    * @return none
    */
    void i2c_delay(unsigned char i)
    {
        do
        {
            _nop_();
        }
        while(i--);        
    }
    
    /**
    * @brief 产生I2C总线启动条件.
    * @param[in] none
    * @param[out] none
    * @return none
    */
    void i2c_start(void)
    {
        sda = 1;
        scl = 1;
        i2c_delay(DELAY_TIME);
        sda = 0;
        i2c_delay(DELAY_TIME);
        scl = 0;    
    }
    
    /**
    * @brief 产生I2C总线停止条件
    * @param[in] none
    * @param[out] none.
    * @return none
    */
    void i2c_stop(void)
    {
        sda = 0;
        scl = 1;
        i2c_delay(DELAY_TIME);
        sda = 1;
        i2c_delay(DELAY_TIME);       
    }
    
    /**
    * @brief I2C发送一个字节的数据
    * @param[in] byt - 待发送的字节
    * @return none
    */
    void i2c_sendbyte(unsigned char byt)
    {
        unsigned char i;
    	EA = 0;
        for(i=0; i<8; i++){
            scl = 0;
            i2c_delay(DELAY_TIME);
            if(byt & 0x80){
                sda = 1;
            }
            else{
                sda = 0;
            }
            i2c_delay(DELAY_TIME);
            scl = 1;
            byt <<= 1;
            i2c_delay(DELAY_TIME);
        }
    	EA = 1;
        scl = 0;  
    }
    
    /**
    * @brief 等待应答
    * @param[in] none
    * @param[out] none
    * @return none
    */
    unsigned char i2c_waitack(void)
    {
    	unsigned char ackbit;	
        scl = 1;
        i2c_delay(DELAY_TIME);
        ackbit = sda; //while(sda);  //wait ack
        scl = 0;
        i2c_delay(DELAY_TIME);
    	
    	return ackbit;
    }
    
    /**
    * @brief I2C接收一个字节数据
    * @param[in] none
    * @param[out] da
    * @return da - 从I2C总线上接收到得数据
    */
    unsigned char i2c_receivebyte(void)
    {
    	unsigned char da;
    	unsigned char i;
    	EA = 0;	
    	for(i=0;i<8;i++){   
    		scl = 1;
    		i2c_delay(DELAY_TIME);
    		da <<= 1;
    		if(sda) 
    			da |= 0x01;
    		scl = 0;
    		i2c_delay(DELAY_TIME);
    	}
    	EA = 1;
    //
    	return da;    
    }
    
    /**
    * @brief 发送应答
    * @param[in] ackbit - 设定是否发送应答
    * @return - none
    */
    void i2c_sendack(unsigned char ackbit)
    {
        scl = 0;
        sda = ackbit;  //0:发送应答信号;1:发送非应答信号
        i2c_delay(DELAY_TIME);
        scl = 1;
        i2c_delay(DELAY_TIME);
        scl = 0; 
    	sda = 1;
        i2c_delay(DELAY_TIME);
    }
    
    /**
    * @brief 读写操作过程中一些必要的延时
    * @param[in] i - 指定延时时间
    * @return - none
    */
    void operate_delay(unsigned char t)
    {
    	unsigned char i;
    	
    	while(t--){
    		for(i=0; i<112; i++);
    	}
    }
    

    //这里是温度传感器DS18B20的驱动程序,注意这里只对DQ这一根总线控制哦。(要是只收发的话跟同步通信有种既当爹又当妈的感觉//手动滑稽)
    //此段代码可以直接读取温度数据。

    #include "reg52.h"
    sbit DQ = P1^4;
    //单总线延时函数
    #ifndef STC12  
    void Delay_OneWire(unsigned int t)  //STC89C52RC
    {
    	while(t--);
    }
    #else
    void Delay_OneWire(unsigned int t)  //STC12C5260S2
    {
    	unsigned char i;
    	while(t--){
    		for(i=0;i<12;i++);
    	}
    }
    #endif
    //通过单总线向DS18B20写一个字节
    void Write_DS18B20(unsigned char dat)
    {
    	unsigned char i;
    	for(i=0;i<8;i++)
    	{
    		DQ = 0;
    		DQ = dat&0x01;
    		Delay_OneWire(5);
    		DQ = 1;
    		dat >>= 1;
    	}
    	Delay_OneWire(5);
    }
    
    //从DS18B20读取一个字节
    unsigned char Read_DS18B20(void)
    {
    	unsigned char i;
    	unsigned char dat;
      
    	for(i=0;i<8;i++)
    	{
    		DQ = 0;
    		dat >>= 1;
    		DQ = 1;
    		if(DQ)
    		{
    			dat |= 0x80;
    		}	    
    		Delay_OneWire(5);
    	}
    	return dat;
    }
    //DS18B20初始化
    bit init_ds18b20(void)
    {
      	bit initflag = 0;
      	
      	DQ = 1;
      	Delay_OneWire(12);
      	DQ = 0;
      	Delay_OneWire(80); // 延时大于480us
      	DQ = 1;
      	Delay_OneWire(10);  // 14
      	initflag = DQ;     // initflag等于1初始化失败
      	Delay_OneWire(5);
      
      	return initflag;
    }
    
    //DS18B20温度采集程序:整数
    unsigned char rd_temperature(void)
    {
        unsigned char low,high;
      	char temp;
      
      	init_ds18b20();
      	Write_DS18B20(0xCC);
      	Write_DS18B20(0x44); //启动温度转换
      	Delay_OneWire(200);
    
      	init_ds18b20();
      	Write_DS18B20(0xCC);
      	Write_DS18B20(0xBE); //读取寄存器
    
      	low = Read_DS18B20(); //低字节
      	high = Read_DS18B20(); //高字节
      
      	temp = high<<4;
      	temp |= (low>>4);
      
      	return temp;
    }
    

    每篇必皮。欢迎交流!共同进步。

    摄自 华为P20
    在这里插入图片描述

    展开全文
  • 异步串行通信波特率的误差

    千次阅读 2009-12-22 11:59:00
    在编写异步串行通信时经常会遇到通信过程中数据错误,有时可能是波特率的误差造成。 实际上,在设计时,就应该考虑波特率与时钟频率的匹配问题。设计时注意波特率与时钟频率的匹配,如果匹配不好,产生的波特率误差...

        在编写异步串行通信时经常会遇到通信过程中数据错误,有时可能是波特率的误差造成。
        实际上,在设计时,就应该考虑波特率与时钟频率的匹配问题。设计时注意波特率与时钟频率的匹配,如果匹配不好,产生的波特率误差较大。通过公式
        (计数器载入值Baud)=((f÷(2^U2X×8×baud))-1)
    计算出装入计数器的值,再将Baud代入
        (实际波特率baud)=f÷(2^U2X×8×(Baud+1))
    中计算,与需要的波特率比对即可知道相差多少。在较大的波特率误差下进行通信,必须每个字节间增加一定的延时,否则连续的数据发送将由于误差的积累而导致数据错误。
        就我们常用的9600的波特率而言,要使误差最小,建议使用11.0592MHz(或它的整数倍)的晶体振荡器,因为它理论上的计算值正好是0误差。但是,由于器件自身的误差,或是环境如温度等原因产生的频率偏移,在较大数据包的传输中,还是会有影响的。
        说明:以上计数器载入值的计算公式是基于AVR内核。51内核的计算公式有所不同,但是道理也是一样。不过,Microchip生产的一些中高档PIC单片机具有波特率校正功能,能在一定程序上减小误差造成的影响。

    展开全文
  • 在使用mdk提供的 keil 工具 开发arm目标板,本体提供了 工程模版,但该模板的启动代码 startup.s 是默认的,也就是说,诸如 主器件的PLL配置---是固定的。但这个 默认配置在某些特殊的应用场景是不能使用的!...
  • 晶振4Mhz,我想设置波特率为38400bps,SPBRG=?
  • 摘要 对串行通信波特率自动识别的方法进行深入的研究和分析;创新性地提出在码元宽度捕捉的基础上,用求最大公约数的方法进行波特率的自动识别,实现了不对待测系统发送的数据进行特殊要求即实现其串行通信数据的...
  • 对于异步串行通信 ,只有在通信双方波特率相同时 , 才能实现数据的正确传输与接收 ;而一些系统总是希望能 实现对各种波特率的兼容。 通常的实现方法是 ,要求对方 首先发出规定的字符或数据 ,系统收到该字符或数据后 ,...
  • 自适应波特率

    随着科技的进步,机器处理的数据量也越来越大。
    2021年,由于对实时性要求比较高,而数据量又越来越大,当时工作的公司就有好几个私有协议,每个私有协议的波特率也越来越高。但是又需要兼容以前的设备,所以Boss让我设计一个自适应波特率模块。

    自适应波特率

    自适应波特率顾名思义,自动设置串口通信模块中波特率。
    自适应波特率其实有很多种设计思路,本文将采用固定波特率,来达到波特率的自动切换。同时本文采用串行通信为正逻辑
    其实是由于本人技术有限,后来公司重新换了方案,就没有在继续考虑。如果后面项目中还需要用到自适应波特率模块,将看看有无更好的方法进行设计,会继续在本文中更新)。
    优点:

    • 在有些协议(波特率不一致)切换中,无需另外编写逻辑,而实现自动切换。

    缺点:

    • 同样在协议解析的过程中,由于需要判断波特率,所以必定会在协议切换的时候丢失一些数据帧。

    异步时钟域数据处理

    由于串口接收数据信号相对于FPGA时钟而言,属于异步信号,如果不进行处理容易产生亚稳态现象。
    这里可以参考我的另外一篇blog同步电路与跨时钟域电路设计.
    所以将串口接收数据信号进行打拍。

    	...Code omission...
    	input i_rxd_bus;
    	...Code omission...
        reg [2:0] r_rxd_sync;
        always @(posedge i_clk or negedge i_rst_n) 
        begin
            if(!i_rst_n)
                r_rxd_sync <= 3'd0;
            else 
                r_rxd_sync <= {r_rxd_sync[1:0],i_rxd_bus};   
        end  
    

    未完待续

    本来想更新完这篇blog,虽然之前已经验证过这个模块,但是最近有点累,这个模块也没用到,所以暂时拖着把。
    时间:2021-9-3

    展开全文
  • 同步通信和异步通信

    2019-12-02 11:21:39
    1、同步使用在芯片控制里面,应用SPI、IIC通信,通过时钟信号CLK进行同步 2、异步比如串口通信;通信波特率一致才能通信通信

    1、同步使用在芯片控制里面,应用SPI、IIC通信,通过时钟信号CLK进行同步

    2、异步应用比如串口通信,通信双方的通信波特率一样才能通信通信

    展开全文
  • 1单片机异步通信口的特点及波特率的选定MSC51系列单片机有一个全双工的异步通信口,他利用其RXD和TXD与...
  • 异步通信与同步通信

    2019-10-02 23:42:47
    @论异步通信与同步通信的区别 在单片机的通信方式中,有同步通信和异步通信两种。下面,我用通俗的比喻来解释...就比如异步全双工收发器一样,需要事先统一好一样的波特率,才能保证通信信息的正确性。 同步通信:...
  • 波特率(Baud Rate) 单位 bps -- 每秒传送的字节数 Byte Per Second.。(BaudRate) 模拟线路信号的速率,也称调制速率,以波形每秒的振荡数来衡量。如果数据不压缩,波特率等于每秒钟传输的数据位数,如果数据进行了...
  • 异步通信uart

    2013-02-02 10:44:51
    之后两端以此波特率进行通信; d. 波特率自适应只在电路复位后进行一次,如欲再次自适应波特率应对电路再次复位; e. 波特率自适应过程中不能对UART的波特率作任何设置,自适应完成后可以对波特率作设置。
  • 同步通信和异步通信以及传输

    千次阅读 2013-06-18 23:19:26
    一、同步通信和异步通信 串行通信可以分为两种类型,一种叫同步通信,另一种叫异步通信。 同步通信方式,是把许多字符组成一个信息组,这样,字符可以一个接一个地传输,但是,在每组信息(通常称为信息帧)的开始要...
  • 异步通信和同步通信 串行通信波特率 串行通信的制式 串行通信的校验 串行口特殊功能寄存器 串行工作方式
  • 异步通信

    千次阅读 2012-09-14 19:51:00
    数据通信的基本方式可分为并行通信和串行通信两种: 并行通信:利用多条数据线将数据...异步通信以一个字符为传输单位,通信中两个字符间的时间间隔是不固定的,然而同一个字符中的两个相邻位之间的时间间隔是固定的。
  • 串行异步通信接口

    千次阅读 2014-10-14 21:31:20
    串行异步通信接口UART(通用异步收发器)
  • 串行通信可以分为两种类型:同步通信、异步通信。    1.异步通信的特点及信息帧格式:      以起止式异步协议为例,下图显示的是起止式一帧数据的格式:         图1 ...
  • 同步通信 VS 异步通信

    万次阅读 2013-08-29 11:51:59
    在描述同步通信与异步通信之前,我们先得搞清串行通信的内涵。串行通信是指计算机主机与外设之间,以及主机系统与主机系统之间数据的串行传输。使用串口进行数据传输时,发送和接收的每一个字符实际上都是一次一位的...
  • 8251 全双工异步通信

    2009-04-02 13:32:57
    8251 全双工异步通信 这是武汉理工大学的接口实验 仅供交流用!
  • 同步通信与异步通信区别

    千次阅读 2016-12-14 15:24:16
    UART总线是异步串口,一般由波特率产生器(产生的波特率等于传输波特率的16倍)、UART接收器、UART发送器组成,硬件上有两根线,一根用于发送,一根用于接收。 显然,如果用通用IO口模拟UART总线,则需一个输入口,一...
  • 通常,在linux下面,设置串口使用终端IO的相关函数设置,如tcsetattr等函数,linux内部有一个对常用波特率列表的索引,根据设置的波特率用底层驱动来设置异步通信芯片的寄存器对于非标准的任意波特率需要用ioctl(fd, ...
  • UART串口异步通信

    2019-09-29 09:42:43
    1.波特率通信设备之间需要约定好波特率(每秒钟传送的二进制位的个数,单位Baud),常见的波特率有4800,9600,115200。 2.通信的起始信号和停止信号:USART协议空闲位默认为高电平,起始信号拉低,停止位(0.5、1、...
  • 介绍了利用现场可编程门阵列(FPGA)设计一个I/O板可以实现串口异步通信,I/O板主要完成中转上位机指令和下位机数据及中间控制的功能。设计可实现下位机任意配置标准波特率、数据传输超时时间以及上位机工作状态等。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,370
精华内容 4,148
关键字:

异步通信的波特率