精华内容
下载资源
问答
  • EDA课设 FPGA开发板 VHDL实现串口通信
    千次阅读 多人点赞
    2021-07-20 21:28:14

    一、设计概述

    1. UART串口通信设计目的

    随着 FPGA/CPLD 器件在控制领域的广泛使用,开发嵌于 FPGA/CPLD 器件内部的通用异步收发器,以实现 FPGA/CPLD 开发系统与 PC 机之间的数据通信是很有实际意义的。FPGA/CPLD与单片机、ARM等器件不同,它内部并没有集成UART,因此要实现串行通信必须要独立开发UART模块。

    通用异步收发器(Universal Asynchronous Receiver/Transmitter, 简称为UART)由于具有数据通信时需要的连线少,具有相关工业标准提供的标准的接口电平规范等优点,在工业控制领域被广泛采用。近年来,FPGA器件逐渐开始广泛使用,开发基于 FPGA/CPLD 器件内部的通用异步收发器,以实现 FPGA/CPLD 开发系统与 PC 机或其它外设之间的数据通信引起了 FPGA/CPLD 领域研究人员的关注。为此,本设计基于 FPGA 器件设计了符合 RS232 标准的UART,实现开发板与计算机串口助手之间的收发,并能够自行调节波特率。

    2. UART串口通信设计目的

    通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART)是一种异步收发传输器,其在数据发送时将并行数据转换成串行数据来传输,在数据接收时将接收到的串行数据转换成并行数据,可以实现全双工传输和接收。它包括了 RS232、RS449、RS423、RS422 和 RS485 等接口标准规范和总线标准规范。换句话说,UART是异步串行通信的总称。而 RS232、RS449、RS423、RS422 和 RS485 等,是对应各种异步串行通信口的接口标准和总

    更多相关内容
  • 并行数据转换为串行数据的转换

    万次阅读 2017-07-24 12:04:16
    这篇文章写一下今天早上设计的并行数据到串行数据的转换器,也算是对并行总线和串行总线一个小小的应用,编码过程中也用到了task。 该转换器主要实现的功能是: 1、把并行地址存入寄存器 2、把并行数据存入寄存器 3...

    这篇文章写一下今天早上设计的并行数据到串行数据的转换器,也算是对并行总线和串行总线一个小小的应用,编码过程中也用到了task。

    该转换器主要实现的功能是:

    1、把并行地址存入寄存器

    2、把并行数据存入寄存器

    3、连接串行单总线

    4、地址的串行输出

    5、数据的串行输出

    6、挂起串行单总线

    7、给信号源应答

    8、让信号源给出下一个操作对象

    9、结束写操作

    该设计利用嵌套的状态机实现,主状态机分为四个状态:idle,addr_write,data_write,stop,主状态机中会涉及到任务shift8out的调用,该任务主要实现并行数据到串行数据的转换,也是由一个状态机实现。下面给出整个设计的代码:

    设计代码:

    ///并串转换器//
    module ps_convertor(clk,rst,data,addr,sda,ack);
    parameter idle=4'b0001,addr_write=4'b0010,data_write=4'b0100,stop=4'b1000;//独热编码
    parameter sh8_start=9'b00000_0001;
    parameter bit6     =9'b00000_0010;
    parameter bit5     =9'b00000_0100;
    parameter bit4     =9'b00000_1000;
    parameter bit3     =9'b00001_0000;
    parameter bit2     =9'b00010_0000;
    parameter bit1     =9'b00100_0000;
    parameter bit0     =9'b01000_0000;
    parameter sh8_stop =9'b10000_0000;
    
              
    input clk,rst;
    input [7:0]addr,data;
    inout sda;//串行总线
    output ack;//应答信号将输入测试模块
    
    reg ack;
    
    reg link_write;//写开关
    reg [7:0] sh8out_buf;//并行总线缓冲器
    
    reg [3:0] mstate;//主状态机的状态寄存器
    reg [8:0] sh8_state;//并串转换状态机状态寄存器
    
    reg FF;//标志寄存器,用来表示任务是否完成
    
    assign sda=(link_write)?sh8out_buf[7]:1'hz;//串行总线数据传输
    
    always@(posedge clk)
    begin
     if(!rst)//同步复位
     begin
      mstate<=idle;
      link_write<=0;
      FF<=0;
      sh8out_buf<=0;
      //sh8_state<=sh8_start;
      ack<=0;
     end
     else 
     begin
     case (mstate)
      idle: begin
             mstate<=addr_write;
    		 link_write<=0;
    		 FF<=0;
    		 sh8out_buf<=addr;
    		 sh8_state<=sh8_start;
    		 ack<=0;
            end
      addr_write: 
            begin
    		 if(FF==0)
    		  begin
    		   shift8out;
    		  end
    		 else 
    		  begin
    		   FF<=0;
    		   mstate<=data_write;
    		   sh8out_buf<=data;
    		   sh8_state<=sh8_start;
    		  end
    		end
      data_write:
            begin
    		 if(FF==0)
    		  begin
    		   shift8out;
    		  end
    		 else 
    		  begin
    		   FF<=0;
    		   mstate<=stop;
    		   ack<=1;
    		  end
    		end
      stop: begin
             ack<=0;
    		 mstate<=idle;
            end
      //default: mstate<=idle;       
     endcase
     end
    end
    //并串转换模块
    task shift8out;
     begin
      case(sh8_state)
       sh8_start: begin
                   link_write<=1;
    			   sh8_state<=bit6;
                  end
       bit6:      begin
                   //link_write<=1;
                   sh8_state<=bit5;
    			   sh8out_buf<=sh8out_buf<<1;
                  end
       bit5:      begin
                   sh8_state<=bit4;
    			   sh8out_buf<=sh8out_buf<<1;
                  end
       bit4:      begin
                   sh8_state<=bit3;
    			   sh8out_buf<=sh8out_buf<<1;
                  end
       bit3:      begin
                   sh8_state<=bit2;
    			   sh8out_buf<=sh8out_buf<<1;
                  end
       bit2:      begin
                   sh8_state<=bit1;
    			   sh8out_buf<=sh8out_buf<<1;
                  end
       bit1:      begin
                   sh8_state<=bit0;
    			   sh8out_buf<=sh8out_buf<<1;
                  end
       bit0:      begin
                   sh8_state<=sh8_stop;
    			   sh8out_buf<=sh8out_buf<<1;
                  end
       sh8_stop: begin 
                  FF<=1;
    			  sh8_state<=sh8_start;
    			  link_write<=0;
    			 end
    			  
      endcase
     end
    endtask
    
    endmodule
    

    测试模块:

    `timescale 1ns/1ns
    `define half_cycle 10
    module signal;
    reg clk,rst;
    reg [7:0]data,addr;
    wire sda,ack;
    always #(`half_cycle) clk=~clk;
    initial 
    begin
      rst=1;
      clk=0;
      data=8'b1010_1010;
      addr=0;
      #100 rst=0;
      #100 rst=1;
      #(200* `half_cycle)$stop;
    end
    
    always @(posedge ack)
    begin
     data=data+1;
     addr=addr+1;
    end
     ps_convertor m(clk,rst,data,addr,sda,ack);
    endmodule
    


    最终在modelsim中得到的仿真图如下:



    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    展开全文
  • 串行通信/并行通信和UART、SPI、I2C、USB以及TTL、RS-232、RS-485区别详细整理 串行通信/并行通信和UART口/USB口以及TTL、RS-232、RS-485这些和通信相关的名词我们做电子的每天都在接触,但是如果不认真整理,我想...

    串行通信/并行通信和UART、SPI、I2C、USB以及TTL、CMOS、RS-232、RS-485区别详细整理

    串行通信/并行通信和UART口/USB口以及TTL、CMOS、RS-232、RS-485这些和通信相关的名词我们做电子的每天都在接触,但是如果不认真整理,我想很多人都不知道这些名词的具体含义和区别,因为我项目中刚好需要用到UART传输数据,所以就打算用这篇文章好好的归纳一下这些磨人的“通信名词”

    关于串行通信/并行通信的解释

    串口通信

    串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节。
    串口:可以算是一个泛称,一般指代的是串口时序标准。UART、RS232、RS485、TTL都遵循着类似的通信时序协议,因此都被通称为串口。

    串行通信

    串行通信(serial communication)是指计算机主机与外设之间以及主机系统与主机系统之间数据的串行传送。使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机、计算机与外设之间的远距离通信。
    串行通信按照发送时钟源和接收时钟源是否需要保持一致,又可分为同步通信异步通信两种。
    具体可参考链接:https://blog.csdn.net/yangtalent1206/article/details/5822509
    在这里插入图片描述

    (补充串口的定义:串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口 (Serial Interface)是指数据一位一位地顺序传送。)

    并行通信

    并行通信(Parallel communication)就是指数据的每一位同时在多根数据线上发送或者接收。可以字或字节为单位并行进行。并行通信速度快,但用的通信线多、成本高,故不宜进行远距离通信。计算机或PLC各种内部总线就是以并行方式传送数据的。
    在这里插入图片描述

    串口通信和串行通信的的区别

    总结:串行通信是一种概念,是指一比特一比特的收发数据,相对于并行通信可一次性收发N比特而言。包括普通的串口通信,包括I2C,包括SPI等等。
    串口通信是一种通信手段/方式,是相对于以太网方式、红外方式、蓝牙方式、usb方式(usb广义也算串行通信)等而言,是一种比较低级的通信手段。
    再强调一遍,二者一个是一种概念,一个是一种实际的通信手段/方式,对咱们而言,几乎一样。

    关于UART、I2C、SPI、USB等详解

    参考链接:https://www.jianshu.com/p/df2ed057b4a0(非常详细)

    UART

    UART是一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收。在嵌入式设计中,UART用于主机与辅助设备通信,如汽车音响与外接AP之间的通信,与PC机通信包括与监控调试器和其它器件,如EEPROM通信。
    可以说UART不是接口,而是实现串口收发的逻辑电路,这部分可以独立成芯片,也可以作为模块嵌入到其他芯片里,单片机、SOC、PC里都会有UART模块。
    接口
    在单片机中UART可以说是一种最基本的配置,很多与电脑进行通信的设备都采用到它,按计算机最常规的说法就是串行通信。
    1.、TX - 数据发送接口
    2、RX - 数据接受接口
    两个设备间将TX与RX相连,RX与TX相连即可正常工作。最常用到的就是我们电脑上的USB那就是个最典型的UART接口。

    I2C

    I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
    主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。
    接口
    1、SCL - 串行时钟线
    2、SDA - 串行数据线接口
    SDA(串行数据线)和SCL(串行时钟线)都是双向I/O线,接口电路为开漏输出.需通过上拉电阻接电源VCC.当总线空闲时.两根线都是高电平,连接总线的外同器件都是CMOS器件,输出级也是开漏电路.在总线上消耗的电流很小,因此,总线上扩展的器件数量主要由电容负载来决定,因为每个器件的总线接口都有一定的等效电容.而线路中电容会影响总线传输速度.当电容过大时,有可能造成传输错误.所以,其负载能力为400pF,因此可以估算出总线允许长度和所接器件数量。

    主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。

    SPI

    SPI接口的全称是"Serial Peripheral Interface",意为串行外围接口,是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在EEPROM、FLASH、实时时钟、AD转换器,还有数字信号处理器和数字信号解码器之间。
    SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,在主器件的移位脉冲下,数据按位传输,高位在前,低位在后,为全双工通信,数据传输速度总体来说比I2C总线要快,速度可达到几Mbps。
    接口
    1、MOSI – 主器件数据输出,从器件数据输入
    2、MISO – 主器件数据输入,从器件数据输出
    3、SCLK –时钟信号,由主器件产生,最大为fPCLK/2,从模式频率最大为fCPU/2
    4、NSS – 从器件使能信号,由主器件控制,有的IC会标注为CS(Chip select)
    在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。在多个从器件的系统中,每个从器件需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。

    USB

    USB,是英文Universal Serial Bus(通用串行总线)的缩写,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯。是应用在PC领域的接口技术。USB接口支持设备的即插即用和热插拔功能。USB是在1994年底由英特尔、康柏、IBM、Microsoft等多家公司联合提出的。
    一条USB传输线分别由地线、电源线、D+和D-四条线构成,D+和D-是差分输入线,它使用的是3.3V的电压(与CMOS的5V电平不同),而电源线和地线可向设备提供5V电压,最大电流为500mA(可以在编程中设置)。
    USB设备可以直接和HOST通信,或者通过Hub和Host通信。一个USB系统中仅有一个USB 主机,设备包括USB功能设备和USB HUB,最多支持127个设备。物理连接指的是USB传输线。在USB 2.0系统中要求使用屏蔽双绞线。
    USB是普遍使用的一种接口,和串口完全是两个概念。虽然也是串行方式通信,但由于USB的通信时序和逻辑电平标准都和串口完全不同,因此和串口没有任何关系。USB是高速的通信接口,用于PC连接各种外设,U盘、键鼠、移动硬盘、当然也包括“USB转串口”的模块。

    USB总线包括:
    USB1.1:
    ——-低速模式(low speed):1.5Mbps
    ——-全速模式(full speed): 12Mbps
    USB2.0:向下兼容。增加了高速模式,最大速率480Mbps。
    ——-高速模式(high speed): 25~480Mbps
    USB3.0:向下兼容。
    ——-super speed :理论上最高达4.8Gbps,实际中,也就是high speed 的10倍左右。

    参考链接:https://blog.csdn.net/u010142953/article/details/82627591

    TTL电平

    通常我们采用二进制来表示数据,为了表示二进制,需要用高低电平表示这些二进制数。而且规定,+5V等价于逻辑“1”,0V等价于逻辑“0”。这样的数据通信及电平规定方式,被称做TTL(晶体管-晶体管逻辑电平)信号系统。这是计算机处理器控制的设备内部各部分之间通信的标准技术。

    UART特指单片机的UART端口,使用TTL电平:
    标准TTL输入高电平最小2V,输出高电平最小2.4V,典型值3.4V,输入低电平最大0.8V,输出低电平最大0.4V,典型值0.2V。
    TTL 电平是 TTL 电路输出的电平,其中"TTL"是英文 “Transistor-Transistor Logic” 的缩写,中文翻译为“晶体管-晶体管逻辑”,因此 TTL 电路就是“晶体管-晶体管逻辑电路”。
    由于电平是一个连续变化的电压范围,为了用这种模拟量的电压来表示数字量的逻辑1和逻辑0,TTL电平规定:

    –输出电路:电压大于等于(≥)2.4V为逻辑1;电压小于等于(≤)0.4V为逻辑0;
    –输入电路:电压大于等于(≥)2.0V为逻辑1;电压小于等于(≤)0.8V为逻辑0;

    CMOS电平

    在这里插入图片描述

    RS-232

    RS232 是美国电子工业协会于 1962 年发布的串行通信接口标准,其中 RS 为英文 “Recomend Standard” 的缩写,中文翻译为“推荐标准”,232为标识号。该标准对串行通信的物理接口及逻辑电平都做了规定。其输出的电平称为 RS232 电平。

    RS485采用差分方式传输,最简单的RS232通信由三条数据线组成,即 TxD、RxD 和GND。RS232采用负逻辑电平,即-15V ~ -3V代表逻辑"1",+3V ~ +15V代表逻辑"0"。这里的电平,是TxD线(或者RxD线)相对于 GND 的电压。

    RS-485

    RS485是一个定义平衡数字多点系统中的驱动器和接收器的电气特性的标准,该标准由电信行业协会和电子工业联盟定义。使用该标准的数字通信网络能在远距离条件下以及电子噪声大的环境下有效传输信号。RS-485使得廉价本地网络以及多支路通信链路的配置成为可能,而且增加了联网功能。

    逻辑"1”以两线间的电压差为+(2 ~ 6)V表示;逻辑"0"以两线间的电压差为-(2 ~ 6)V表示,使能端起作用和其他状态时为高阻态。

    在实际中由于需要,有时候会要讲TTL电平转化为RS232电平,有时候也会要将RS232电平转化为TTL电平

    在这里插入图片描述
    使用MAX232能实现在TTL和RS232之间的相互转化,参考电路图如上。

    小小总结(补充)

    串口通信不包括并行通信,并行通信曾经有一个通用接口叫并口,被后来的一系列串行协议打趴下了。TTL现在是是一种数字电路的电平标准, 另一个相似的概念是CMOS电平。UART是串行通信的一种,重点是异步,和同步相对应,意思是不需要同步的时钟,通信两端预先约定bit的传输速率(每秒传多少bit),而不是由时钟触发的。USB是一个完整的通过串行方式传输数据的协议。初学嵌入式可以把RS232,串口,UART当作一种东西的。
    补充1:
    usb与串口的关系,刚开始确实比较容易搞混。一般电脑是没有uart接口的(ttl电平),那么拥有uart接口的单片机如何和电脑通信呢?我们可以通过电脑的usb接口和单片机通信,只需一个usb转串口模块插到usb接口上,装上驱动,另一边接单片机即可。有很多可以usb协议转为串口协议的芯片,如ch340,cp2102,pl2303等。
    补充2:
    TTL、RS232、RS485应用点:
    TTL电平一般用于芯片与芯片之间的通信;RS232采用了正负逻辑电平,提高线路的抗干扰性最远可以达到15米左右;如果更远的距离会采样RS485,它使用两线制的差分信号传输,最远可至1200米;RS232全双工只支持点对点通讯(1:1),RS485半双工或单双工支持总线形式通讯(1:N)。
    补充3:
    摘自:https://www.zhihu.com/question/271616218/answer/365203637
    USB是一种高速通信接口,和串口无关。串口是泛指,指代所有采用串口通信时序的接口。
    TTL不是正规名称,只不过在某些情况下约定俗成的一种串口标准(电平标准,通信时序都是串口)
    RS232、RS485都是串口标准。不同的串口标准虽然电平标准不一定相同,但通信时序协议都是大致相同的。
    UART指的是实现UART通信的数字逻辑电路。
    补充4:
    UART是计算机中串行通信端口的关键部分。在计算机中,UART相连于产生兼容RS232规范信号的电路。RS232标准定义逻辑“1”信号相对于地为-3到-15伏,而逻辑“0”相对于地为+3到+15伏。所以,当一个微控制器中的UART相连于PC时,它需要一个RS232驱动器来转换电平。
    Uart这里指的是TTL电平的串口;RS232指的是RS232电平的串口。
    TTL电平是5V的,而RS232是负逻辑电平,它定义+5 ~ +12V为低电平,而-12 ~ -5V为高电平。
    Uart串口的RXD、TXD等一般直接与处理器芯片的引脚相连,而RS232串口的RXD、TXD等一般需要经过电平转换(通常由Max232等芯片进行电平转换)才能接到处理器芯片的引脚上,否则这么高的电压很可能会把芯片烧坏。
    我们平时所用的电脑的串口就是RS232的,当我们在做电路工作时,应该注意下外设的串口是Uart类型的还是RS232类型的,如果不匹配,应当找个转换线(通常这根转换线内有块类似于Max232的芯片做电平转换工作的),可不能盲目地将两串口相连。

    展开全文
  • 一文搞懂串口通信

    千次阅读 2021-05-19 15:22:13
    很久之前就听说“串口”这个词。一直没明白它是什么意思,应用在什么场景,有什么特点和优点。近来又在某个文档中看到“电脑上至少配置两个RS232...串行接口 是一种可以将接收来自CPU的并行数据字符转换为连续的串行

    很久之前就听说“串口”这个词。一直没明白它是什么意思,应用在什么场景,有什么特点和优点。近来又在某个文档中看到“电脑上至少配置两个RS232串口,一个RJ-45网口”,我实在拖不了了,今天一定要把它搞清楚。

    研究之前我先是在网上搜了一些Qt和串口通信开发相关的资料,大致看了一下大家的博文,稍微有一个简单的了解,然后我先去问一下实验室的好兄弟,
    在这里插入图片描述
    在这里插入图片描述
    简单沟通了一下,听听其他同学的想法,然后开干!

    百度百科上对于“串口"和"串口通信”的解释:

    串行接口 是一种可以将接收来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接收的串行数据流转换为并行的数据字符供给CPU的器件。一般完成这种功能的电路,我们称为串行接口电路。
    串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节的通信方式。串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低。

    尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。典型地,串口用于ASCII码字符的传输。通信使用3根线完成,分别是地线、发送、接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配。

    RS-232标准

    串口是计算机上一种非常通用的设备通信协议。大多数计算机(不包括笔记本电脑)包含两个基于RS-232的串口。串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。同时,串口通信协议也可以用于获取远程采集设备的数据。
    RS-232(ANSI/EIA-232标准)是IBM-PC及其兼容机上的串行连接标准。可用于许多用途,比如连接鼠标、打印机或者Modem,同时也可以接工业仪器仪表。

    上面了解到大多数台式机上是有串口的,经常用于连接一些工业设备或者远程采集数据。由于自己对这些概念还不太懂,所以先去写个程序测试一下我的笔记本有没有串口。新建一个Qt Application项目,pro文件中导入serialport模块,在main.cpp中写入:

    #include "mainwindow.h"
    #include <QApplication>
    #include <QSerialPort>
    #include <QSerialPortInfo>
    #include <QDebug>
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    //    MainWindow w;
    //    w.show();
        foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            qDebug() << "Name : " << info.portName();
            qDebug() << "Description : " << info.description();
            qDebug() << "Manufacturer: " << info.manufacturer();
            qDebug() << "Serial Number: " << info.serialNumber();
            qDebug() << "System Location: " << info.systemLocation();
        }
        qDebug() << "hello";
        return a.exec();
    }
    

    主要是使用QSerialPortInfo,它提供有关现有串行端口的信息。使用静态函数生成qserialPortInfo对象列表,列表中的每个qserialPortInfo对象表示单个串行端口,可以查询端口名、系统位置、说明和制造商。

    最后发现只输出了:hello。

    果然经过程序验证,我的普通华硕笔记本上是不具有串口这个东西的,那么什么设备上面有呢?

    了解到:

    带串口的笔记本电脑上有一个9针的插口,现在大部分电脑都没有这一插口了,可通过USB转串口软件和连接线替代。串口是为了通信用的,在当年,可以连接Modem,打印机,游戏机等外部设备,现在,这些设备都变成USB口了,所以现在的电脑上,再也看不到串口了。只有工控机上,串口还被保留。因为串口在工业控制方面,到现在还有很多应用。

    仿佛茅塞顿开啊,原来很久之前是有的,但是随着时代的发展被取代,除非一些特殊领域。

    再往下看:

    串行接口,简称串口,也就是COM接口,是采用串行通信协议的扩展接口。串口的出现是在1980年前后,数据传输率是115kbps~230kbps,串口一般用来连接鼠标和外置Modem以及老式摄像头和写字板等设备,目前部分新主板已开始取消该接口。

    看到这,我觉得串行接口应该就是一种采用串行通信协议的接口而已。接口有很多种,它是其中之一。

    于是我想尽快学习一下基本的API,其实不多,看下面这个代码应该就差不多了。

    QSerialPort 负责具体的串口操作。

    使用qserialPortInfo帮助程序类获取有关可用串行端口的信息,该类允许枚举系统中的所有串行端口。可以将helper类的对象作为参数传递给setport()或setportname()方法,以分配所需的串行设备。选定串口后,要先打开串口,才能设置波特率等参数。

    这些参数都设置好了就可以使用了。最基本的操作无非是read() 和 write()。需要注意的是这两个操作都是非阻塞的。

    还有一个重要的signal 也需要用到,那就是 void QIODevice::readyRead()。每次串口收到数据后都会发出这个signal。我们的程序中需要定义一个slot,并将其与这个signal 相连接。这样,每次新数据到来后,我们就可以在slot中读取数据了。这时一定要将串口缓冲区中的数据全部读出来,可以利用readAll() 来实现。

    看一下代码:

    #include "widget.h"
    #include "ui_widget.h"
    
    #include <QSerialPort>
    #include <QSerialPortInfo>
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        //查找现有串行端口的信息
        foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
        {
            QSerialPort serial;
            serial.setPort(info);
            if(serial.open(QIODevice::ReadWrite))
            {
                ui->PortBox->addItem(serial.portName());
                serial.close();
            }
        }
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::on_OpenSerialButton_clicked()
    {
        if(ui->OpenSerialButton->text() == "打开串口")
        {
            serial = new QSerialPort;
            //设置串口名
            serial->setPortName(ui->PortBox->currentText());
            //打卡串口
            serial->open(QIODevice::ReadWrite);
            //设置波特率
            serial->setBaudRate(ui->BaudBox->currentText().toInt());
            //设置数据位数
            switch (ui->BitBox->currentIndex())
            {
            case 8:
                serial->setDataBits(QSerialPort::Data8);
            case 7:
                serial->setDataBits(QSerialPort::Data7);
            case 6:
                serial->setDataBits(QSerialPort::Data6);
            case 5:
                serial->setDataBits(QSerialPort::Data5);
                break;
            default:
                break;
            }
            //设置校验位
            switch (ui->ParityBox->currentIndex())
            {
            case 0:
                serial->setParity(QSerialPort::NoParity);
                break;
            default:
                break;
            }
            //设置停止位
            switch (ui->BitBox->currentIndex())
            {
            case 1:
                serial->setStopBits(QSerialPort::OneStop);
                break;
            case 2:
                serial->setStopBits(QSerialPort::TwoStop);
            default:
                break;
            }
            //设置流控制
            serial->setFlowControl(QSerialPort::NoFlowControl);
    
            //关闭设置菜单使能
            ui->PortBox->setEnabled(false);
            ui->BaudBox->setEnabled(false);
            ui->BitBox->setEnabled(false);
            ui->ParityBox->setEnabled(false);
            ui->StopBox->setEnabled(false);
            ui->OpenSerialButton->setText(tr("关闭串口"));
    
            //连接信号槽
            connect(serial,SIGNAL(readyRead),this,SLOT(ReadData));
        }
        else
        {
            //关闭串口
            serial->clear();
            serial->close();
            serial->deleteLater();
    
            //恢复设置使能
            ui->PortBox->setEnabled(true);
            ui->BaudBox->setEnabled(true);
            ui->BitBox->setEnabled(true);
            ui->ParityBox->setEnabled(true);
            ui->StopBox->setEnabled(true);
            ui->OpenSerialButton->setText(tr("打开串口"));
        }
    }
    //读取接收到的信息
    void Widget::ReadData()
    {
        QByteArray buf;
        buf = serial->readAll();
        if(!buf.isEmpty())
        {
            QString str = ui->textEdit->toPlainText();
            str+=tr(buf);
            ui->textEdit->clear();
            ui->textEdit->append(str);
    
        }
        buf.clear();
    }
    
    //发送按钮槽函数
    void Widget::on_SendButton_clicked()
    {
        serial->write(ui->textEdit_2->toPlainText().toUtf8());
    }
    
    

    就这?看完之后总感觉少了点什么,没错,你还没上手跑一下呢。于是我先大概参考[4]的代码,先保证代码能运行起来。

    前面验证知道,我的笔记本上不具有串口,所以需要用虚拟串口工具模拟两个串口出来,然后进行通信,于是我去找了一个用的比较多的软件,VSPD,它可以增加串口数量,一次虚拟2个串口,一个读,一个发,那我们就可以虚拟2个串口然后连接起来实现自发自收调试。

    安装很简单,完成之后,打开时这样子的。标题乱码了,对于我感觉有点难受,但是凑合用吧。

    在这里插入图片描述
    点击右边的【添加端口】,就会在左边的【Virtual ports】下面多出来两个端口。

    在这里插入图片描述
    然后,,,然后就可以跑程序了!

    首先,再次运行上面提到的main.cpp中监测串口的那几行代码,再看现在运行后输出的结果:

    Name :  "COM2"
    Description :  "Virtual Serial Port (Eltima Softwate)"
    Manufacturer:  "ELTIMA Software"
    Serial Number:  ""
    System Location:  "\\\\.\\COM2"
    Name :  "COM1"
    Description :  "Virtual Serial Port (Eltima Softwate)"
    Manufacturer:  "ELTIMA Software"
    Serial Number:  ""
    System Location:  "\\\\.\\COM1"
    hello
    

    说明刚刚的端口添加成功了!

    稍微修改一下博文[4]中的程序代码。其实少了一个文件,但是不影响我们运行,删了那两行代码就行了,还有把QAction中的最后一个参数this删了,运行结果:

    在这里插入图片描述
    在这里插入图片描述
    为何要俩窗口呢,因为要看收和发的过程。但是遇到了问题,Qt Creator还不能同时运行两个相同的进程,聪明的我想了个办法,开两个Qt Creator。。。

    ok,大致测试完了,记得关闭VSPD之前,删除掉虚拟端口。

    又参考[5]的代码写了一个示例:

    缺失一个ui文件,我在这放出来吧:
    在这里插入图片描述
    ui文件代码,自己实现的时候有些地方参考了博客[5]中的下拉框选项。

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow2</class>
     <widget class="QMainWindow" name="MainWindow2">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>800</width>
        <height>600</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <layout class="QGridLayout" name="gridLayout">
        <item row="0" column="0">
         <layout class="QHBoxLayout" name="horizontalLayout_7">
          <item>
           <layout class="QVBoxLayout" name="verticalLayout">
            <item>
             <widget class="QLabel" name="label">
              <property name="text">
               <string>接收窗口</string>
              </property>
             </widget>
            </item>
            <item>
             <widget class="QTextEdit" name="recvTextEdit"/>
            </item>
            <item>
             <widget class="QLabel" name="label_2">
              <property name="text">
               <string>发送窗口</string>
              </property>
             </widget>
            </item>
            <item>
             <widget class="QTextEdit" name="sendTextEdit"/>
            </item>
            <item>
             <layout class="QHBoxLayout" name="horizontalLayout">
              <item>
               <widget class="QPushButton" name="pushButton">
                <property name="text">
                 <string>清空接收</string>
                </property>
               </widget>
              </item>
              <item>
               <widget class="QPushButton" name="sendButton">
                <property name="text">
                 <string>发送数据</string>
                </property>
               </widget>
              </item>
             </layout>
            </item>
           </layout>
          </item>
          <item>
           <layout class="QVBoxLayout" name="verticalLayout_2">
            <item>
             <layout class="QHBoxLayout" name="horizontalLayout_2">
              <item>
               <widget class="QLabel" name="label_3">
                <property name="text">
                 <string>串口号</string>
                </property>
               </widget>
              </item>
              <item>
               <widget class="QComboBox" name="portNameBox"/>
              </item>
             </layout>
            </item>
            <item>
             <layout class="QHBoxLayout" name="horizontalLayout_3">
              <item>
               <widget class="QLabel" name="label_4">
                <property name="text">
                 <string>波特率</string>
                </property>
               </widget>
              </item>
              <item>
               <widget class="QComboBox" name="baudrateBox">
                <property name="currentIndex">
                 <number>3</number>
                </property>
                <item>
                 <property name="text">
                  <string>1200</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>2400</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>4800</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>9600</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>14400</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>19200</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>38400</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>56000</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>57600</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>115200</string>
                 </property>
                </item>
               </widget>
              </item>
             </layout>
            </item>
            <item>
             <layout class="QHBoxLayout" name="horizontalLayout_4">
              <item>
               <widget class="QLabel" name="label_5">
                <property name="text">
                 <string>数据位</string>
                </property>
               </widget>
              </item>
              <item>
               <widget class="QComboBox" name="dataBitsBox">
                <property name="currentIndex">
                 <number>3</number>
                </property>
                <item>
                 <property name="text">
                  <string>5</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>6</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>7</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>8</string>
                 </property>
                </item>
               </widget>
              </item>
             </layout>
            </item>
            <item>
             <layout class="QHBoxLayout" name="horizontalLayout_5">
              <item>
               <widget class="QLabel" name="label_6">
                <property name="text">
                 <string>校验位</string>
                </property>
               </widget>
              </item>
              <item>
               <widget class="QComboBox" name="ParityBox">
                <item>
                 <property name="text">
                  <string></string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string></string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string></string>
                 </property>
                </item>
               </widget>
              </item>
             </layout>
            </item>
            <item>
             <layout class="QHBoxLayout" name="horizontalLayout_6">
              <item>
               <widget class="QLabel" name="label_7">
                <property name="text">
                 <string>停止位</string>
                </property>
               </widget>
              </item>
              <item>
               <widget class="QComboBox" name="stopBitsBox">
                <item>
                 <property name="text">
                  <string>1</string>
                 </property>
                </item>
                <item>
                 <property name="text">
                  <string>2</string>
                 </property>
                </item>
               </widget>
              </item>
             </layout>
            </item>
            <item>
             <widget class="QPushButton" name="pushButton_3">
              <property name="text">
               <string>检测串口</string>
              </property>
             </widget>
            </item>
            <item>
             <widget class="QPushButton" name="openButton">
              <property name="text">
               <string>打开串口</string>
              </property>
             </widget>
            </item>
           </layout>
          </item>
         </layout>
        </item>
       </layout>
      </widget>
      <widget class="QMenuBar" name="menubar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>800</width>
         <height>21</height>
        </rect>
       </property>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
     </widget>
     <resources/>
     <connections/>
    </ui>
    
    

    同样是开两个端口COM1和COM2,然后测试一下收发,注意运行之前先打开VSPD添加一个虚拟串口对,然后分别启动两个进程a,b,首先分别点击a,b窗口中的检测串口,然后分别点击打开串口,这样发送数据按钮就会启用,然后就在发送窗口中编辑内容,点击发送数据就OK啦!

    可以看到,两边收发都是可以的。

    在这里插入图片描述
    细心的同学可能又发现了,为啥截图的VSPD变了?本人这一丢丢的强迫症困扰的厉害,这个pro才好嘛!

    今天的学习暂时先到此,后面继续补充完善,大家如果想要代码也可以私信我提供,欢迎讨论交流。

    参考

    1. Qt5 串口数据读取
    2. 串口通信
    3. 带串口的笔记本是什么概念
    4. QT5实现串口收发数据(上位机与下位机通信)
    5. QT5串口编程——编写简单的上位机
    6. qt 串口收发(完整版)
    展开全文
  • 什么是串口通信协议

    千次阅读 2020-10-10 10:25:23
    2、它自己本身不会去协商通信参数,需要通信通信双方事先约定好通信参数来进行通信。 3、因此,若是收发方的任何一个关键参数设置错误,都会导致通信失败。譬如波特率调错了,发送方发送没问题,接收方也能接收,...
  • 并行总线(MIII总线)是某型火控...该方案利用FPGA(可编程逻辑器件)和VerilogHDL(硬件描述语言),并采用Top-D-own电子设计自动化技术来对各功能模块进行划分和设计开发,可实现并行MIII总线与RS422通信协议之间的转换
  • 串行接口 (Serial Interface) 是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。...
  • 通信协议篇——UART串口通信

    千次阅读 2019-11-12 20:48:15
    通信协议篇——UART串口通信
  • 串并行转换器相连的光电器件  在高速光纤通信系统中,传输的数据流需要进行格式转换,即在光纤传输时的串行格式及在电子处理时的并行格式之间转换化器-解器 (一般被称作串并行转换器) 就是用来实现...
  • 串口通信

    2020-07-15 10:13:20
    文章目录0 背景知识回顾0.1 总线0.2 总线通信分类按传输方向分类按通信方式分类1 串行通信1.1 串行同步通信优点缺点1.2 串行异步通信1.2.1 异步通信的数据格式1.2.3 通用异步收发器UART1.2.4 DB9 0 背景知识回顾 0.1...
  • 串行接口是一种可以将接收来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接收的串行数据流转换为并行的数据字符供给CPU的器件。一般完成这种功能的电路,我们称为串行接口电路。 串口通信(Serial ...
  • 串口通信usart之灯光亮度控 串口通信usart原理 USART是一个全双工通用同步/异步串行收发模块,首先来介绍一下数据的传输方式,数据的传输方式有单工,半双工,全双工。...那么串行通信和并行通信是指什么呢?
  • 尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配。 1. 波特...
  • 串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件。一般完成这种功能的电路,我们称为串行接口电路。串口通信结构串口...
  • 【STM32】5分钟了解STM32的串口通信

    万次阅读 多人点赞 2020-08-21 10:18:28
    串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节的通信方式。文章主要是串口通信简介和STM32的串口通信
  • 01、UART串口通信

    千次阅读 2021-04-02 16:05:40
    文章目录0、前言1、串行通信的初步认识2、RS232 通信接口3、USB 转通信4、IO 口模拟 UART 串口通信5、UART串口通信的基本应用5.1、通信的三种基本类型5.2、UART 模块介绍5.3、UART 串口程序6、ASCII 码 ...
  • 这一节主要介绍Arduino串口通信的基本原理、USART通信模式下的硬件串口(SoftwareSerial类库),软件模拟串口(SoftwareSerial类库)两种实现方式,同时通过两个常用的例子进行实验,让你进一步快速学会串口通讯。
  • 【嵌入式】STM32串口通信一、串口通信协议1.串口通信简介2.串口通信原理二、RS232通信协议1.RS232协议简介2.机械规约3.电气规约三、STM32的USART串口通信(查询方式)1.题目要求2.连接USB转TTL与C8T63.安装串口驱动...
  • 安卓串口通信

    千次阅读 2020-09-10 16:24:20
    串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件。   串口通信(Serial Communications)是指外设和计算机间,通过...
  • STM32常用协议之串口通信详解

    千次阅读 2022-04-06 22:40:45
    串行通信与并行通信示意图 串行通信 并行通信 定义 利用单一传输线,按数据位形式一位一位地传输数据 利用多条传输线,将数据的各位同时传送 传输方式 传输一个字节(8个位)的数据时,串口将这8个位进行排队,然后...
  • 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节,尽管比按位字节(byte)的并行通信慢,但是串口可以使用一根线发送数据的同时用另一根线接收数据。串口通信属于异步串行通信方式...
  • 4.3 51单片机-串口通信

    千次阅读 2021-10-29 11:19:34
    4.3 串口通信 4.3.1 通信的概念 ...如果单片机通信没处理好的话,它和外围器件的合作程度就受到限制,最终整个系统也无法完成强大的功能,由此可见单片机通信技术的重要性。 UART(Universal Asynchronous Rec.
  • 摘要:根据现代通信对模数转换的高速、高分辨率性能要求,在对现有的并行式模数转换电路研究和改进的基础上,提出了一种比特滑动流水并行式模数转换方法,从而简化了电路结构、节省了器件、降低了功耗,更有利于集成...
  • FPGA串口通信

    2021-07-20 19:07:50
    1、串口叫做串行通信接口,它是指数据一位一位的顺序传输,最少只需要一根传输线即可完成,成本低但传输速度慢。串行通讯的距离可以从几米到几千米;根据信息的传送方向,串行通信可以进一步分为单工、半双工和全...
  • STM32串口通信简介

    2021-10-23 22:27:52
    尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间...
  • 1.1、串行通信 和 并行通信 并行通讯通常可以一次传送8bit、16bit、32bit甚至更高的位数,相应地就需要8根、16根、32根信号线,同时需要加入更多的信号地线。传输速度快,距离近; 串行通讯的数据线比较少,这样一条...
  • STC89C52系列单片机的串行通信口,除用于数据通信外,还可方便地构成一个或多个并行I/O口,或作 — 并转换,或用于扩展串行外设等。 串行口相关寄存器 串行口控制寄存器SCON和PCON STC89C52系列单片机的串行口设...
  • 【嵌入式】串口通信及其案例

    千次阅读 多人点赞 2021-03-29 17:27:49
    使用场景 串行接口(COM口)是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件。 串口是计算机上一种非常通用的设备通信协议。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,163
精华内容 2,465
关键字:

串并行通信转换的器件