精华内容
下载资源
问答
  • uart通讯协议

    2017-07-27 12:21:00
    实验目的:通过uart通讯协议的编写,了解FPGA的通讯协议编写的方法。 实验现象:FPAG可以通过USB转TTL工具向电脑收发数据。 相关知识点:1、uart通讯协议是什么及其内容。2、in system surce and probes...

    本次设计的源码在http://download.csdn.net/detail/noticeable/9912383 下载

    实验目的:通过uart通讯协议的编写,了解FPGA的通讯协议编写的方法。

     

    实验现象:FPAG可以通过USB转TTL工具向电脑收发数据。

     

    相关知识点:1、uart通讯协议是什么及其内容。2、in system surce and probes(editor)调试工具的使用。

      

     

    关于串行通讯:串口通讯协议是一种主机之间常用的通讯协议,通过模块按位发送和接收字节,可以达到通讯的目的,其通讯只需要三根根数据线(GND,RXD,TXD)即可完成。其中串口通讯最重要的参数是波特率,数据位,停止位和奇偶校验位,下面来一一讲解这                              些参数的作用。

            (1)波特率:波特率是串口的通讯速率,常见的比特率为1200bps、4800bps、9600bps、38400bps、115200bps、256000bps、500000bps,这里bps的意思是bit/s,因此可以知道,波特率实际上是每秒可以传输的bit的个数,由此可知波特率与时钟是直接挂钩的,比如波特率位9600bps,那么时钟就是9600hz,即每秒内产生9600个时钟,每个时钟周期发送1bit的数据。(这里注意:波特率越高,传输距离越短)

              波特率分频计数器的方法:

     

     

            (2)数据位:数据位可以在通讯过程中告知另一个主机,完成一次通讯过程中真正有效的数据是多少位,完成对传输数据的位数的校验。

            (3)起始位、停止位:起始位位于单个数据包的第一位,停止位位于单个包的最后一位,每个包都是一个字节, 另一台主机接收到停止位时就知道信号发送已经完成了。

             (4)奇偶校验位:奇偶校验是通讯协议中的一种简单的检错方法,其有时钟检错方式,:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。如果是奇校验,校验位为1,这样就有3个逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步。

     

     

    项目设计:

    本次设计发送模块的整体结构体如下                                       发送时序图

     

     

      首先按照系统框图编写tx项目源码:

     

          

    发生时序图

     

     源码程序如下

     

    module uart_tx(
                                    clk,
                                    rst_n,
                                   send_en,
                                    baud_set,
                                    tx_done,
                                    rs232_tx,
                                    data_byte,
                                    uart_state
                                );
            input clk;
            input rst_n;
            input [7:0]data_byte;//数据发送寄存器
            input send_en;
            input [2:0]baud_set;
            
            output reg rs232_tx;                    //输出引脚
            output reg tx_done;                    //传输完成的标志位
            output reg uart_state;                //uart_state传送状态
            
            reg [15:0]div_cnt;        //分频计数器
            reg bps_clk;                    //波特率时钟
            reg [15:0]bps_dr;            //分频计数最大值
            reg [3:0]bps_cnt;            //波特率计数时钟
            reg [7:0]r_data_byte;//发送缓存区
            
            localparam start_bit=1'b0;
          localparam stop_bit=1'b1;
            
            //具有优先级的信号控制,产生控制信号
            always@(posedge clk or negedge rst_n)
                        if(!rst_n)
                uart_state<=0;
                else if(send_en==1'b1)
                uart_state<=1;
                else if(bps_cnt == 4'd11)                //假设穿的是一组8位的数据+起始位+停止位
            uart_state <= 1'b0;
                else 
                uart_state<=uart_state;
                
                        //发送过程中需要保证数据是稳定的,选用一个寄存器将数据先缓存起来
                always@(posedge clk or negedge rst_n)
                        if(!rst_n)
                        r_data_byte<=8'd0;
                        else if(send_en)
                        r_data_byte<=data_byte;
            
                            //设计查找表DR_LUT,通过查找表设置波特率
                  //1/波特率/20ns
    always@(posedge clk or negedge rst_n) if(!rst_n) bps_dr<=16'd5207; else begin case (baud_set) 0:bps_dr<=16'd5207;//9600 1:bps_dr<=16'd2603;//19200 2:bps_dr<=16'd1301;//28400 3:bps_dr<=16'd867;//57600 4:bps_dr<=16'd433;//115200 // 5:bps_dr<=16'd5207; // 6:bps_dr<=16'd5207; // 7:bps_dr<=16'd5207; default bps_dr<=16'd5207;//9600 endcase end //分频计数器 always@(posedge clk or negedge rst_n) if(!rst_n) div_cnt<=16'd0; else if(uart_state)begin if(div_cnt==bps_dr)//到达计数最大值时清零 div_cnt<=16'd0; else div_cnt<=div_cnt+1'b1; end else div_cnt<=16'd0; //单周期的波特率时钟产生 always@(posedge clk or negedge rst_n) if(!rst_n) bps_clk<=1'b0; else if(div_cnt==16'd1) bps_clk<=1; else bps_clk<=0; //设计波特率计数器 always@(posedge clk or negedge rst_n) if(!rst_n) bps_cnt<=4'b0; else if (bps_cnt == 4'd11) bps_cnt<=4'b0; else if (bps_clk) bps_cnt<=bps_cnt+1'b1; else bps_cnt<=bps_cnt; //发送完成信号 always@(posedge clk or negedge rst_n) if(!rst_n) tx_done<=1'b0; else if(bps_cnt==4'd11) tx_done<=1'b1; else tx_done <=1'b0; //数据发送,即一个十选一的多路器 always@(posedge clk or negedge rst_n) if(!rst_n) rs232_tx<=1'b1; else begin case(bps_cnt) 0:rs232_tx<=1'b1; 1:rs232_tx<=start_bit;//起始位 2:rs232_tx<=r_data_byte[0]; 3:rs232_tx<=r_data_byte[1]; 4:rs232_tx<=r_data_byte[2]; 5:rs232_tx<=r_data_byte[3]; 6:rs232_tx<=r_data_byte[4]; 7:rs232_tx<=r_data_byte[5]; 8:rs232_tx<=r_data_byte[6]; 9:rs232_tx<=r_data_byte[7]; 10:rs232_tx<=stop_bit;//结束位,本次设计不设奇偶校验位 default rs232_tx<=1'b1; endcase end endmodule

     

     

     编写testbench文件

    `timescale 1ns/1ns
    `define clock_period 20
    
    module uart_tx_tb;
            reg clk;
            reg rst_n;
            reg [7:0]data_byte;
            reg send_en;
            reg [2:0]baud_set;
            
            wire rs232_tx;
            wire tx_done;
            wire uart_state;
            uart_tx            uart_tx0(
                                                                .clk(clk),
                                                                .rst_n(rst_n),
                                                                .send_en(send_en),
                                                               .baud_set(baud_set),
                                                                .tx_done(tx_done),
                                                                .rs232_tx(rs232_tx),
                                                                .data_byte(data_byte),
                                                                .uart_state(uart_state)
                                                            );
                                                            
                                    initial clk=1;
                                    always#(`clock_period/2)  clk=~clk;
                                    initial begin 
                                    rst_n<=1'b0;
                                    data_byte<=8'd0;
                                    send_en<=1'd0;
                                    baud_set=3'd4;
                                    #(`clock_period*20+1)
                                    rst_n<=1'b1;
                                        #(`clock_period*50+1)
                                        data_byte<=8'haa;
                                    send_en<=1'd1;
                                    #(`clock_period)
                                    send_en<=1'd0;
                                    @(posedge tx_done)//等待传输完成的上升沿
                                    #(`clock_period*500)//重新发送
                                    data_byte<=8'h55;
                                    send_en<=1'd1;
                                    #(`clock_period)
                                    send_en<=1'd0;
                                    #(`clock_period*500)
                                    $stop;
                                    
                                    end
                                    
                                    
                                    
                                    
                                
            endmodule 

     

    仿真结果如下,可以看到,每当有一个send_en 时,databyte都会将串口数据输出出来。

            

     

    将之前用到的key_filter文件添加进来,作为传输的控制信号。

     添加IP核以便使用in system sources and probe editor 工具

     

     将.v文件添加到file中,编写uart_top

    module uart_top(clk ,rst_n,rs232_tx,key_in,led);
    
                        input key_in;
                        input clk;
                        input rst_n;
                        output rs232_tx;
                        wire send_en;
                        wire [7:0]data_byte;
                        output led;
                        wire key_flag,key_state;
                        assign send_en=key_flag&!key_state;//按键检测成功且为低电平时,发生使能
                        
                    uart_tx            uart_tx1(
                                                                .clk(clk),
                                                                .rst_n(rst_n),
                                                                .send_en(send_en),
                                                               .baud_set(3'd0),
                                                                .tx_done(),
                                                                .rs232_tx(rs232_tx),
                                                                .data_byte(data_byte),
                                                                .uart_state(led)//将串口状态用LED显示出来
                                                            );
                                    key_filter key_filter0(
                                                                    .clk(clk),
                                                                    .rst_n(rst_n),
                                                                    .key_in(key_in),
                                                                    .key_flag(key_flag),
                                                                    .key_state(key_state)
                                                                    );
                             ISSP  ISSP0(
                                                            .probe(),
                                                            .source(data_byte)
                                                            );
    endmodule

     

     

     进行引脚分配,进行板级验证。

    由于DE1-SOC上并未板载USB转TTL模块,这里需要自备一个,然后将模块的RXD口连接到开发板上的GPIO_0D1口上,打开串口调试软件并通过USB转TTL模块连接到FPGA上(波特率设为9600),按下KEY1后,可以看到开发板上的LEDR0快速闪烁一下,串口调试助手接收到00两个数据

     

     

     

    打开in system sources and probes editor,

    修改格式为hex格式,然后输入任意数据,我这里输入66,

     然后再按一下key1,可以看到串口调试软件显示出来66,即我们给的source值,这里发送端的设计就完成了,下面继续按相同的方法设计接收端的协议。

     

     

     

     

     

    UART数据接收部分:

     之前已经讲过了uart 发送端的时序图,对应的,理论上接收端的时序图如下,一般采样在每一位数据的中点是最稳定的。

     

    但是在工业等复杂的环境中,电磁场的干扰是很强的,所以在这里需要进行抗干扰处理,需要多次采样求概率来进行接收,进行改进后的单bit数据接收方式示意图

     

     

    同样编写Verilog代码:

    module uart_rx(clk,
                                        rs232_rx,
                                        baud_set,
                                        rst_n,
                                        data_byte,
                                        rx_done
                                        );
                                        input clk;
                            input                rs232_rx;
                            input             [2:0]baud_set;
                            input             rst_n;
                            output    reg     [7:0]data_byte;
                            output     reg        rx_done;
                            reg s0_rs232_rx,s1_rs232_rx;//两个同步寄存器
                            reg tmp0_rs232_rx,tmp1_rs232_rx;//数据寄存器
                            wire nedege;
                            reg [15:0]bps_dr;//分频计数器计数最大值
                            reg [15:0]div_cnt;//分频计数器
                            reg uart_state;
                            reg bps_clk;
                            reg [7:0]bps_cnt;
                            reg [2:0]r_data_byte [7:0];//前面[2:0]是每一位数据的存储宽度,[7:0]指位宽
                                reg [2:0] start_bit,stop_bit;
                            
                            
                            //异步信号同步处理,消除亚稳态,有疑惑的看之前的按键消抖部分
                            always@(posedge clk or negedge rst_n)
                        if(!rst_n)
                        begin
                        s0_rs232_rx<=1'b0;
                            s1_rs232_rx<=1'b0;
                            end
                            else 
                            begin 
                                s0_rs232_rx<=rs232_rx;
                            s1_rs232_rx<=s0_rs232_rx;
                            end
                                    //数据寄存
                            always@(posedge clk or negedge rst_n)
                        if(!rst_n)
                        begin
                        tmp0_rs232_rx<=1'b0;
                            tmp1_rs232_rx<=1'b0;
                            end
                            else 
                            begin 
                                tmp0_rs232_rx<=s1_rs232_rx;
                                        tmp1_rs232_rx<=tmp0_rs232_rx;
                            end
                            assign nedege=tmp0_rs232_rx&tmp1_rs232_rx;//下降沿检测
                            
                            
                            
                        //波特率设置模块
                        //10^9/波特率/20ns/这里为了稳定1bit数据会采16次所以还要除16
                        
                        always@(posedge clk or negedge rst_n)
                        if(!rst_n)
                    bps_dr<=16'd324;
                        else begin 
                        case (baud_set)
                        0:bps_dr<=16'd324;//9600
                        1:bps_dr<=16'd162;//19200
                        2:bps_dr<=16'd80;//28400
                        3:bps_dr<=16'd53;//57600
                        4:bps_dr<=16'd26;//115200
                            default
                            bps_dr<=16'd324;//9600
                        endcase 
                        end
                        //分频计数器
            always@(posedge clk or negedge rst_n)
                        if(!rst_n)
                        div_cnt<=16'd0;
                        else if(uart_state)begin 
                        if(div_cnt==bps_dr)//到达计数最大值时清零
                                div_cnt<=16'd0;
                                else div_cnt<=div_cnt+1'b1;
                                                    end
                            else 
                            div_cnt<=16'd0;
        
                                    //单周期的波特率时钟产生
                        always@(posedge clk or negedge rst_n)
                        if(!rst_n)
                        bps_clk<=1'b0;
                        else if(div_cnt==16'd1)
                            bps_clk<=1;
                            else
                            bps_clk<=0;
                
                                        //设计波特率计数器
                    always@(posedge clk or negedge rst_n)
                        if(!rst_n)
                    bps_cnt<=8'b0;
                else if(bps_cnt == 8'd159 | (bps_cnt == 8'd12 && (start_bit > 2)))//到12位的时候,start_bit>2说明接收错误,起始位不对
                                bps_cnt <= 8'd0;//接收完成或者开始检测到错误信号,波特率时钟停止
                    else if (bps_clk)
                            bps_cnt<=bps_cnt+1'b1;
                    else 
                            bps_cnt<=bps_cnt;
                
                    //接收完成信号
                    always@(posedge clk or negedge rst_n)
                        if(!rst_n)
                        rx_done<=1'b0;
                        else if(bps_cnt==8'd159)
                        rx_done<=1'b1;
                        else 
                        rx_done <=1'b0;
                        
                    
                                //数据读取,对每次采样进行求和值 
                        always@(posedge clk or negedge rst_n)
                        if(!rst_n)begin 
                                start_bit=3'd0;
                                r_data_byte[0]<=3'd0;
                                r_data_byte[1]<=3'd0;
                                r_data_byte[2]<=3'd0;
                                r_data_byte[3]<=3'd0;
                                r_data_byte[4]<=3'd0;
                                r_data_byte[5]<=3'd0;
                                r_data_byte[6]<=3'd0;
                                r_data_byte[7]<=3'd0;
                                stop_bit<=3'd0;
                                end 
                                else if(bps_clk)begin
            case(bps_cnt)
                0:begin
                        start_bit = 3'd0;
                        r_data_byte[0] <= 3'd0;
                        r_data_byte[1] <= 3'd0;
                        r_data_byte[2] <= 3'd0;
                        r_data_byte[3] <= 3'd0;
                        r_data_byte[4] <= 3'd0;
                        r_data_byte[5] <= 3'd0;
                        r_data_byte[6] <= 3'd0;
                        r_data_byte[7] <= 3'd0;
                        stop_bit = 3'd0;            
                        end 
                            6,7,8,9,10,11:start_bit <= start_bit + s1_rs232_rx;
                            22,23,24,25,26,27:r_data_byte[0] <= r_data_byte[0] + s1_rs232_rx;
                            38,39,40,41,42,43:r_data_byte[1] <= r_data_byte[1] + s1_rs232_rx;
                            54,55,56,57,58,59:r_data_byte[2] <= r_data_byte[2] + s1_rs232_rx;
                            70,71,72,73,74,75:r_data_byte[3] <= r_data_byte[3] + s1_rs232_rx;
                            86,87,88,89,90,91:r_data_byte[4] <= r_data_byte[4] + s1_rs232_rx;
                            102,103,104,105,106,107:r_data_byte[5] <= r_data_byte[5] + s1_rs232_rx;
                            118,119,120,121,122,123:r_data_byte[6] <= r_data_byte[6] + s1_rs232_rx;
                            134,135,136,137,138,139:r_data_byte[7] <= r_data_byte[7] + s1_rs232_rx;
                            150,151,152,153,154,155:stop_bit <= stop_bit + s1_rs232_rx;
                        default:
                    begin                                    
                        start_bit = start_bit;
                        r_data_byte[0] <= r_data_byte[0];
                        r_data_byte[1] <= r_data_byte[1];
                        r_data_byte[2] <= r_data_byte[2];
                        r_data_byte[3] <= r_data_byte[3];
                        r_data_byte[4] <= r_data_byte[4];
                        r_data_byte[5] <= r_data_byte[5];
                        r_data_byte[6] <= r_data_byte[6];
                        r_data_byte[7] <= r_data_byte[7];
                        stop_bit = stop_bit;                        
                    end
            endcase
        end
                        
            
                                            always@(posedge clk or negedge rst_n)//数据提取
                                        if(!rst_n)
                                        data_byte <= 8'd0;
                                    else if(bps_cnt == 8'd159)begin
                                        data_byte[0] <= r_data_byte[0][2];
                                        data_byte[1] <= r_data_byte [1][2];
                                        data_byte[2] <= r_data_byte[2][2];
                                        data_byte[3] <= r_data_byte[3][2];
                                        data_byte[4] <= r_data_byte[4][2];
                                        data_byte[5] <= r_data_byte[5][2];
                                        data_byte[6] <= r_data_byte[6][2];
                                        data_byte[7] <= r_data_byte[7][2];
                                    end    
                                    
                                    //控制逻辑
                                    
                            always@(posedge clk or negedge rst_n)
                        if(!rst_n)
                            uart_state <= 1'b0;
                            else if(nedege)
                                uart_state <= 1'b1;
                                else if(rx_done || (bps_cnt == 8'd12 && (start_bit > 2)))    //接收完成或者到12位的时候,start_bit>2说明接收错误,起始位不对
                                uart_state <= 1'b0;//关闭传输状态位
                            else
                                uart_state <= uart_state;        
    
    endmodule
    
                        
                        
                        
                        

    编写testbench并添加路径,因为testbench中调用了uart_rx,所以在添加路径的时候需要将uart.v文件添加到路径中去

    `timescale 1ns/1ns
    `define clock_period 20
    module uart_rx_tb;
                            reg             rst_n;
                            reg             clk;
                            reg                rs232_rx;
                            wire            rs232_tx;
                            reg             [2:0]baud_set;
                            wire             rx_done;
                            wire             tx_done;
                            wire             [7:0]data_byte_r;
                            reg              [7:0]data_byte_t;
                            reg             send_en;
                          wire             uart_state;        
        
                            
                            
    
                    uart_rx        uart_rx1(.clk(clk),
                                                        .rs232_rx(rs232_tx),    //用输入值作为读取值
                                                        .baud_set(baud_set),
                                                        .rst_n(rst_n),
                                                        .data_byte(data_byte_r),
                                                        .rx_done(rx_done)
                                                        );
    
                                uart_tx            uart_tx2(
                                                                                    .clk(clk),
                                                                                    .rst_n(rst_n),
                                                                                    .send_en(send_en),
                                                                                    .baud_set(baud_set),
                                                                                    .tx_done(tx_done),
                                                                                    .rs232_tx(rs232_tx),
                                                                                    .data_byte(data_byte_t),
                                                                                    .uart_state(uart_state)//将串口状态用LED显示出来
                                                                                );
                                                initial clk=1;
                                                                    always#(`clock_period/2)  clk=~clk;
                                                                    initial begin 
                                                                            rst_n<=1'b0;
                                                                            data_byte_t<=8'd0;
                                                                            send_en<=1'd0;
                                                                            baud_set=3'd4;
                                                                            #(`clock_period*20+1)
                                                                            rst_n<=1'b1;
                                                                                #(`clock_period*50+1)
                                                                                data_byte_t<=8'haa;
                                                                            send_en<=1'd1;
                                                                            #(`clock_period)
                                                                            send_en<=1'd0;
                                                                            @(posedge tx_done)//等待传输完成的上升沿
                                                                            #(`clock_period*5000)//重新发送
                                                                            data_byte_t<=8'h55;
                                                                            send_en<=1'd1;
                                                                            #(`clock_period)
                                                                            send_en<=1'd0;
                                                                            #(`clock_period*500)
                                                                            $stop;
                                                                            end
    endmodule 

    将uart_rx设为顶层文件,编译后进行仿真,仿真图形如下:

    新建ISSP IP核,添加8个探针

     

    在uart_top中将rs_232_rx添加进来

    module uart_top(clk ,rst_n,rs232_rx,rs232_tx,key_in,led);
    
                        input key_in;
                        input clk;
                        input rst_n;
                        input  rs232_rx;
                        output rs232_tx;
                        wire send_en;
                        wire [7:0]data_byte_t;
                        reg [7:0]data_byte_r;
                        wire [7:0]data_rx;
                        output led;
                        wire key_flag,key_state;
                        wire rx_done;
                        assign send_en=key_flag&!key_state;//按键检测成功且为低电平时,发生使能
                        
                    uart_tx            uart_tx1(
                                                                .clk(clk),
                                                                .rst_n(rst_n),
                                                                .send_en(send_en),
                                                               .baud_set(3'd0),
                                                                .tx_done(),
                                                                .rs232_tx(rs232_tx),
                                                                .data_byte(data_byte_t),
                                                                .uart_state(led)//将串口状态用LED显示出来
                                                            );
                        uart_rx        uart_rx2(.clk(clk),
                                                        .rs232_rx(rs232_rx),    //用输入值作为读取值
                                                        .baud_set(3'd0),
                                                        .rst_n(rst_n),
                                                        .data_byte(data_rx),//接收到的数据传递给data_rx;
                                                        .rx_done(rx_done)
                                                        );
    
                                    key_filter key_filter0(
                                                                    .clk(clk),
                                                                    .rst_n(rst_n),
                                                                    .key_in(key_in),
                                                                    .key_flag(key_flag),
                                                                    .key_state(key_state)
                                                                    );
                        
                         ISSP     ISSP(
                                                                .probe(),//调用一个ISSP 发送数据
                                                                .source(data_byte_t)
                                                                );
                                     ISSP1  ISSP2(
                                                            .probe(data_byte_r),//调用一个ISSP 接收数据
                                                            .source()
                                                            );
                            
                                                //应为data_rx可能没有接收成功,为错误量,所以需要一个中间量来进行缓冲
                                            always@(posedge clk or negedge rst_n)
                                            if(!rst_n)
                                                data_byte_r <= 8'd0;
                                            else if(rx_done)
                                                data_byte_r<= data_rx;
                                            else
                                                data_byte_r<= data_byte_r;
    endmodule

     

     分配RX引脚给GPIO0_D0,然后将程序烧写到FPGA中,将GPIO0-D0与GPIO0_D1连着直接用杜邦线连接,打开ISSP工具,将两者都设置为hex显示,且将第二个ISSP工具设置为循环扫描,在第一个ISSP中输入数据,按下按键KEY1后,看到第二个ISSP 有相应的数据变化。

    此时说明整个协议编写完成 了可以完成通讯了

     

     

     

    转载于:https://www.cnblogs.com/noticeable/p/7233666.html

    展开全文
  • UART通讯协议规范 高清完整PDF版

    千次下载 热门讨论 2014-10-05 11:04:09
    本资源为UART标准协议规范,对于UART开发及应用具有很大帮助。
  • 1/ UART通讯协议

    2019-09-03 17:38:33
    每一种命令都有自己的指定的编码;如下面所示:: 运用在代码中如: 还没有写完 待续~~

    每一种命令都有自己的指定的编码;如下面所示::

    运用在代码中如:


    还没有写完  待续~~

     

    展开全文
  •   简单的UART通讯接收数据,通常的做法是接收一帧数据帧处理后,将接收缓冲区游标指针移到缓冲区最前面。这样等到下次接受时候,数据又从头开始放,这种做法可以保证每次缓冲区接收的数据帧都是从头开始完整的一帧...

    【随手记】

      简单的UART通讯接收数据,通常的做法是接收一帧数据帧处理后,将接收缓冲区游标指针移到缓冲区最前面。这样等到下次接受时候,数据又从头开始放,这种做法可以保证每次缓冲区接收的数据帧都是从头开始完整的一帧。
      然而这种做法必须要满足一个条件,循环查询接收的数据时间必须略小于对方发送数据间隔,否则会产生数据混乱现象。

    展开全文
  • IIC SPI ... UART 端口名称 SDA SCL CLK MISO MOSI CS RX TX PHILIPS 摩托罗拉...

     

     

    IIC

    SPI

    UART

    端口名称

    SDA

    SCL

    CLK

    MISO

    MOSI

    CS

    RX

    TX

     

    PHILIPS

    摩托罗拉

     

     

    串行

    串行

    串行

     

    有同步时钟信号

    有同步时钟信号

    无同步时钟,需约定好的波特率

    USART指具有同步方式的控制器

     

    半双工

    全双工

    全双工

     

    总线

    无片选信号,发送带地址信息和仲裁机制还需应答信号

    总线

    有片选信号

     

    点对点

    转RS485两线制半双工可以接成总线形式,经上层协议可多机通讯

     

    读、写同一个线,带读写位

     

     

    元素

     

    极性、相位、片选

    波特率、起始位、数据位、校验位、停止位

    关键图示

    IIC

    数据位发送:在I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。进行数据传送时,在SCL呈现高电平期间,SDA上的电平必须保持稳定,低电平为数据0,高电平为数据1。只有在SCL为低电平期间,才允许SDA上的电平改变状态。逻辑0的电平为低电压,而逻辑1则为高电平。

    启动信号:SCL为高电平的时候,SDA由高电平向低电平跳变。结束信号:SCL为高电平的时候,SDA由低电平向高电平跳变。

     

    应答信号

     

    SPI

     

    UART

    波特率

    展开全文
  • https://baijiahao.baidu.com/s?id=1665274898041730396&wfr=spider&for=pc http://www.elecfans.com/emb/jiekou/20171206595886_a.html
  • UART串口通讯协议解析

    千次阅读 2021-02-26 11:44:04
    UART串口通讯协议解析概述接口通信协议 概述 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART。它将要传输的资料在串行通信与并行通信之间加以转换。作为把并行输入信号转成串行...
  • UART串口通讯协议

    千次阅读 2018-12-26 16:30:00
    一、UART定义 UART 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种通用的串行异步全双工数据收发传输器(总线)。 二、UART作用 UART的作用是:把“要传输的数据”...
  • UART总线协议详解

    2020-07-04 11:41:08
    UART通讯协议中信号线上的状态位高电平代表’1’低电平代表’0’。当然两个设备使用UART串口通讯时,必须先约定好传输速率和一些数据位。 硬件连接 硬件连接比较简单,仅需要3条线,注意连接时两个设备UART电平,...
  • uart协议_详解UART串口

    2020-11-27 07:51:22
    通用异步收发传输器(Universal...在UART通讯协议中信号线上的状态位高电平代表’1’低电平代表’0’。当然两个设备使用UART串口通讯时,必须先约定好传输速率和一些数据位。硬件连接硬件连接比较简单,仅需要3条线,...
  • UART通信协议

    千次阅读 2018-10-18 11:30:39
    对很多接触过单片机的朋友们来说,UART一定不是一个陌生的东西,因为往往许多人将UART作为程序调试反馈的一个重要途径,而UART协议也成为了目前最通用...早期的电脑基本上都是通过RS232协议进行通讯,采用的接插件...
  • 起止式异步通讯协议: 特点与格式: 起止式异步协议的特点是一个字符一个字符传输,并且传送一个字符总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。其格式如图3 所示。每一个字符的前面都有...
  • UART协议

    2019-10-29 22:40:33
    作为把并行输入信号转成串行输出信号的芯片,UART通常被集成于其他通讯接口的连结上。 UART是一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收。 通信协议 UART作为异步串口通...
  • UART串口协议简单总结

    2021-03-18 20:42:53
    文章目录UART串口 ---通用异步收发传输器(串行/异步/全双工)UART的硬件链接---TTL直接连接 / 配合232电平转接芯片连接UART 通讯数据格式UART控制器举例介绍---s3c2440 uart控制器 UART串口 —通用异步收发传输器...
  • 通信协议——UART

    2020-07-16 09:17:29
    UART概述 通用异步收发传输器(Universal ...在UART通讯协议中信号线上的状态位高电平代表’1’低电平代表’0’。当然两个设备使用UART串口通讯时,必须先约定好传输速率和一些数据位。 UART硬件连接 硬件连接比较简
  • uart协议

    2020-01-04 23:39:55
    UART就是通用异步收发协议,异步就是通讯双方没有时钟信号,通过一根线把数据按照Bit位LSB格式传输; 因为是异步通信,所以传输的数据时,双方通信要有个“同步机制”,因此数据格式的开头为一个bit的“0”作为起始...
  • 1. 串行异步通信UART使用的是串行异步通信。(1)串行通信即利用一条传输线将数据一位位地顺序传送。(2)异步通信以一个字符为传输单位,通信中两个字符间的时间间隔多少是不固定的,然而在同一个字符中的两个相邻“位...
  • UART、RS232、RS485、Modbus通讯协议

    千次阅读 2019-05-23 09:23:34
    UART(通用异步收发器):作用:将数据通过串行发送出去,即将一个byte的数据一bit的发送出去。 RS232与RS485:规定了电气特性。电气特性即电平特性。 RS232的电平特性:逻辑“1”为...MODBUS通讯协议:规定数据帧...
  • 常见通讯协议介绍

    2019-10-11 11:15:35
    UART通讯协议介绍 UART是什么?UART是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种异步收发传输器,是设备间进行异步通信的关键模块。UART负责处理数据总线和串行口之间...
  • 海凌科语音模块通讯协议
  • 仪表串行通讯协议CD_UART_V1.6版 1、 通讯方式:串行通信(单片机UART接口),RS232 通讯方式。 2、 通讯电压:TTL电平,低电平为0V,高电平为5V。 3、 通讯波特率:9600bits/S。 4、 通讯参数:8bit数据位,1位...
  • ModBus通信协议一种串行...UART / 串口通用异步收发传输器UniversalAsynchronousReceiver/Transmitter早于ModBus的硬件通讯器,用于并行数据转为串行进行传输,实现增距减线的目的。同步收发,有时钟线,就像节拍...
  • 数据解析协议,针对蓝牙通讯的数据解析,每次发一包数据,不含数据以外的干扰数据;
  • 数据解析协议,针对蓝牙通讯的数据解析,支持多包数据同时发送,支持含有数据以外的干扰数据;
  • UART协议学习

    2020-07-25 16:04:09
    协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。 电平标准 根据通讯使用的电平标准不同,串口通信可分为TTL标准及RS-232标准,见如下表格: 通讯标准 电平标准(发送端) 5V TTL 逻辑1:2.4V...
  • UART详解

    万次阅读 多人点赞 2018-12-26 15:56:59
    UART 通用异步收发传输器(Universal ...在UART通讯协议中信号线上的状态位高电平代表’1’低电平代表’0’。当然两个设备使用UART串口通讯时,必须先约定好传输速率和一些数据位。 硬件连接 硬件连接比较简...
  • UART概述】 UART俗称串口,是Universal Asynchronous Receiver/Transmitter(通用异步收发器)...这俩协议之间实际上并无包含关系,只是通常使用的串口是指满足UART通信协议且物理连接满足RS232电气特性的一种通讯...
  • 一种MODBUS RTU扩展串口通讯协议

    千次阅读 2018-05-24 12:55:12
    一直以来,都希望有一个比较通用的串口UART通讯协议,看到当前modbus RTU的工业应用场景比较多,但是该协议,每次最多256个字节,而且必须是一问一答的通讯方式。而我想象中的通讯协议应该可以相对较长的数据,大约...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 396
精华内容 158
关键字:

uart通讯协议