精华内容
下载资源
问答
  • 4.串口通信以1位的低电平标志串行传输的开始,待8位数据传输完成之后,再以1位的高电平标志传输的结束。(Send en) 5.控制信号,控制并转串模块什么时候开始工作,什么时候一个数据发送完成?须有一个发

    基于FPGA的串口(UART)发送实验

    1.串口通信模块设计的目的是用来发送数据的,因此需要一个数据输入端口。
    2.串口通信,支持不同的波特率,所以需要有一个波特率设置端口。
    3.串口通信的本质就是将8位的并行数据通过一根信号线,在不同的时刻传输并行数据的不同位,通过多个时刻,最终将8位并行数据全部传出。
    4.串口通信以1位的低电平标志串行传输的开始,待8位数据传输完成之后,再以1位的高电平标志传输的结束。(Send en)
    5.控制信号,控制并转串模块什么时候开始工作,什么时候一个数据发送完成?须有一个发送开始信号,以及一个 发送完成信号。(Tx Done
    Bout set 是用来控制波特率,满足不停环境下的应用
    在这里插入图片描述
    在这里插入图片描述
    ##最初版本
    源代码:

    module uart_byte_tx(
       Clk,
       Reset_n,
       Send_en,
       uart_tx,
       Baud_set,
       Data,
       Tx_done
        );
       input  Clk;
       input Reset_n;
       input Send_en;
       input [7:0] Data;
       input [2:0] Baud_set;  // 8钟不同的波特率
       output reg uart_tx;
       output  reg Tx_done;
       //Baud_set = 0 让波特率 = 9600;
        //Baud_set = 1 让波特率 = 19200;
        //Baud_set = 2 让波特率 = 38400;
         //Baud_set =3 让波特率 = 57600;
          //Baud_set = 4 让波特率 = 115200;
       reg [17:0] bps_DR ; 
       always@(*)
          case(Baud_set)
          0 :   bps_DR = 1000000000/9600/20;          
            1 :   bps_DR = 1000000000/19200/20;  
            2 :   bps_DR = 1000000000/38400/20;  
            3 :   bps_DR = 1000000000/57600/20;  
            4 :   bps_DR = 1000000000/115200/20;  
          default : bps_DR = 1000000000/9600/20;
       endcase
       
        reg [17:0] div_cnt;   //分频得到基本时钟。 因为波特率范围为 300~115200 最高为1000000000/300/20 18位 
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n) 
          div_cnt <= 0;
         else if(Send_en)     //控制信号为高电平时才计数。
          if (div_cnt == bps_DR - 1) //取决于波特率不同,计数值应该也不同,需要一个寄存器来管理
          div_cnt <= 0 ;
         else 
         div_cnt <= div_cnt + 1'b1;  
        else 
          div_cnt <= 0 ;
       
       reg [3:0] bps_cnt;  // 考虑到有 8位Bit流位 和 开始 结束 共十段 ,需要有一个计数器 计数11次
       always@(posedge Clk or negedge Reset_n)
        if(!Reset_n) 
           bps_cnt <= 0;
          else if (bps_cnt == bps_DR - 1)begin
           if(bps_cnt == 11)
             bps_cnt <= 0 ;
       else
             bps_cnt <= bps_cnt + 1'b1;
        end     
       
     always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)  begin
            uart_tx <= 1'b0;  
            Tx_done <= 0;
       end
    else begin
         case(bps_cnt)
         0: begin uart_tx <=  0; Tx_done <=1'b1; end
         1: uart_tx <= Data[0];
         2: uart_tx <=  Data[1];
         3: uart_tx <=  Data[2];
         4: uart_tx <= Data[3];
         5: uart_tx <=  Data[4];
         6: uart_tx <=  Data[5];
         7: uart_tx <=   Data[6];
         8: uart_tx <=   Data[7];
         9: uart_tx <=  Data[8];
         10: uart_tx <=   1;   //此时的结束信号 需要保持一个位的时间,即在11的时候 才是真正的结束。
         11:begin uart_tx <= 1;   Tx_done <=1'b1;  end   //判定在此时才为发送完。 Tx_Done为0时再给拉低。
           default : uart_tx <=  1;
       endcase   
       end
    endmodule
    

    TB文件:

    `timescale 1ns / 1ns
    module uart_byte_tx_tb();
       reg Clk;
       reg Reset_n;
       reg Send_en;
       reg [7:0] Data;
       reg [2:0] Baud_set;  
       wire  Tx_done;
       wire  uart_tx;
    uart_byte_tx uart_byte_tx(
        .Clk(Clk),
            .Reset_n(Reset_n),
            .Data(Data),
            .Send_en(Send_en),
            .Baud_set(Baud_set),
            .uart_tx(uart_tx),
            .Tx_done(Tx_done)
    );
    initial Clk = 1;
    always #10 Clk = !Clk;
    initial begin
     Reset_n = 0;
     Data = 0;
     Send_en =0;
     Baud_set = 4;  //设置一个速度快的,便于仿真
     # 201;
     #100;
     Data = 8'h57;
    Send_en = 1;
    #20;
    @(posedge Tx_done); //  阻塞语句,意思是: 一直在这里等待Tx_done信号到来才执行下面的语句,否则一直循环。
    Send_en =0; 
    #20000;
    Data = 8'h75;
    Send_en = 1;
    #20;
    @(posedge Tx_done);
    #20000;
    Send_en =0;
    $stop;
    end 
    endmodule
    

    仿真结果出现问题:
    在这里插入图片描述
    Reset_n 一直没有拉高,所有修改TB文件:
    在这里插入图片描述
    修改成这样后 再仿真

    在这里插入图片描述
    Send_en拉高之后,要过一位 tx才为0;

    检查代码逻辑发现
    在这里插入图片描述
    本来dps_cnt应该为0的时候却不是0,没有及时清零。

    bps_cnt也应该受到 Send_en的控制。

    修改后再次运行发现。

    在这里插入图片描述
    按照前面的图,tx信号在空闲时应该为高电平 此时却为低电平了。
    在这里插入图片描述
    发现是在此时 bps_cnt变为0时,把tx拉低了。
    思考后发现:在空闲时长时间保持为零,而在dps_cnt为0时又刚好命中代码中case语句中的 0
    在这里插入图片描述
    修改 使得dps_cnt从1开始,

    再次仿真发现:在这里插入图片描述
    还是tx信号还是滞后一个周期。
    分析发现
    在这里插入图片描述
    在Send en 为1开始后,
    必须要等 div_cnt记满之后 dps_cnt才能加1.
    修改为从 div_cnt=1 开始计数。
    最终代码:

    module uart_byte_tx(
        Clk,
        Reset_n,
        Data,
        Send_en,
        Baud_set,
        uart_tx,
        Tx_done
    );
        input Clk;
        input Reset_n;
        input [7:0]Data;
        input Send_en;
        input [2:0]Baud_set;
        output reg uart_tx;
        output reg Tx_done;
        
        //Baud_set = 0   就让波特率 = 9600;
        //Baud_set = 1   就让波特率 = 19200
        //Baud_set = 2   就让波特率 = 38400;
        //Baud_set = 3   就让波特率 = 57600;   
        //Baud_set = 4   就让波特率 = 115200; 
    
        reg [17:0]bps_DR;
        always@(*)
            case(Baud_set)
                0:bps_DR = 1000000000/9600/20;
                1:bps_DR = 1000000000/19200/20;
                2:bps_DR = 1000000000/38400/20;
                3:bps_DR = 1000000000/57600/20;
                4:bps_DR = 1000000000/115200/20;
                default:bps_DR = 1000000000/9600/20;
             endcase
    
        wire bps_clk;
        assign bps_clk = (div_cnt == 1);
        
        reg [17:0]div_cnt;
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            div_cnt <= 0;
        else if(Send_en)begin
            if(div_cnt == bps_DR - 1)
                div_cnt <= 0;
            else 
                div_cnt <= div_cnt + 1'b1;
        end
        else
            div_cnt <= 0;
    
        reg [3:0]bps_cnt;
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            bps_cnt <= 0;
        else if(Send_en)begin
            if(bps_clk)begin
                if(bps_cnt == 11)
                    bps_cnt <= 0;
                else
                    bps_cnt <= bps_cnt + 1'b1;
            end
        end
        else
            bps_cnt <= 0;
        
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n) begin
            uart_tx <= 1'b1;
            Tx_done <= 0;
        end
        else begin
            case(bps_cnt)
                1:begin uart_tx <= 0;Tx_done <= 1'b0;end
                2:uart_tx <= Data[0];
                3:uart_tx <= Data[1];
                4:uart_tx <= Data[2];
                5:uart_tx <= Data[3];
                6:uart_tx <= Data[4];
                7:uart_tx <= Data[5];
                8:uart_tx <= Data[6];
                9:uart_tx <= Data[7]; 
                10:uart_tx <= 1;
                11:begin uart_tx <= 1;Tx_done <= 1'b1;end
                default:uart_tx <= 1;
            endcase
         end     
    
    endmodule
    

    ##串口发送数据任务
    使用上面设计的串口发送模块,设计一个数据发送器,每10ms以115200的波特率发送一个数据,每次发送的数据比前一个数据大一(计数器)。

    在这里插入图片描述
    直接例化上面的模块,
    创建一个test文件:

    module uart_tx_test(
        Clk,
        Reset_n,
        uart_tx,
    );
        input Clk;
        input Reset_n;
        output uart_tx;
        
        reg Send_Go;
        reg [7:0]Data;
        
        uart_byte_tx uart_byte_tx(
            .Clk(Clk),
            .Reset_n(Reset_n),
            .Data(Data),
            .Send_Go(Send_Go),
            .Baud_set(3'd4),
            .uart_tx(uart_tx),
            .Tx_done(Tx_done)
        );
        
        reg [24:0]counter;
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            counter <= 0;
        else if(counter == 4999999)
            counter <= 0;
        else
            counter <= counter + 1;
            
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)       
            Send_Go <= 0;
        else if(counter == 1)
            Send_Go <= 1;
        else
            Send_Go <= 0;
    
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)        
            Data <= 0;
        else if(Tx_done)
            Data <= Data + 1'b1;   
        
    endmodule
    

    在这里插入图片描述
    发现问题:Send_en只有一个高电平
    分析代码发现,由于TX_done一直都是高电平,使得Send_en后续一直被拉低。
    先修改成:
    在这里插入图片描述
    再次仿真:
    在这里插入图片描述
    Data在此时连续加了三次 直接变成03
    因为Tx_done信号持续时间太长,这是因为bps_cnt11 这个信号保持了三个时钟周期,要想办法让他只有一个时钟周期。
    在这里插入图片描述
    分析代码逻辑:
    1.当div_cnt
    1时,产生bps_clk1的脉冲
    2.当bps_cnt
    1时,产生bps_cnt11
    3.当bps_cnt
    11时,产生Tx_done1的高电平信号
    4.当Tx_done
    1时,Send_en被拉低,要等下一个时钟周期才生效。此时Data 为01;
    5.而div_cnt往前加1,bps_cnt还是保持在11,则Tx_done也还是保持在高电平。
    6.直到下一个时钟周期,检测到Send_en=0;,则把bps_cnt清零,此时Tx_done变为0在这里插入图片描述
    修改为:
    在这里插入图片描述
    思考:优化设计
    在这里插入图片描述
    要点 :在DATA——done信号为高出发期间,DATA信号要保持不变。

    最终设计:

    uart_tx_test:

    module uart_tx_test(
        Clk,
        Reset_n,
        uart_tx,
    );
        input Clk;
        input Reset_n;
        output uart_tx;
        
        reg Send_Go;
        reg [7:0]Data;
        
        uart_byte_tx uart_byte_tx(
            .Clk(Clk),
            .Reset_n(Reset_n),
            .Data(Data),
            .Send_Go(Send_Go),
            .Baud_set(3'd4),
            .uart_tx(uart_tx),
            .Tx_done(Tx_done)
        );
        
        reg [24:0]counter;
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            counter <= 0;
        else if(counter == 4999999)
            counter <= 0;
        else
            counter <= counter + 1;
            
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)       
            Send_Go <= 0;
        else if(counter == 1)
            Send_Go <= 1;
        else
            Send_Go <= 0;
    
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)        
            Data <= 0;
        else if(Tx_done)
            Data <= Data + 1'b1;   
        
    endmodule
    

    uart_byte_tx:

    module uart_byte_tx(
        Clk,
        Reset_n,
        Data,
        Send_Go,
        Baud_set,
        uart_tx,
        Tx_done
    );
        input Clk;
        input Reset_n;
        input [7:0]Data;
        input Send_Go;
        input [2:0]Baud_set;
        output reg uart_tx;
        output reg Tx_done;
        
        //Baud_set = 0   就让波特率 = 9600;
        //Baud_set = 1   就让波特率 = 19200
        //Baud_set = 2   就让波特率 = 38400;
        //Baud_set = 3   就让波特率 = 57600;   
        //Baud_set = 4   就让波特率 = 115200; 
    
        reg [17:0]bps_DR;
        always@(*)
            case(Baud_set)
                0:bps_DR = 1000000000/9600/20;
                1:bps_DR = 1000000000/19200/20;
                2:bps_DR = 1000000000/38400/20;
                3:bps_DR = 1000000000/57600/20;
                4:bps_DR = 1000000000/115200/20;
                default:bps_DR = 1000000000/9600/20;
             endcase
    
        reg Send_en;
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)       
            Send_en <= 0;
        else if(Send_Go)
            Send_en <= 1;
        else if(Tx_done)
            Send_en <= 0;
            
        reg [7:0]r_Data;
        always@(posedge Clk)
        if(Send_Go)
            r_Data <= Data;
        else
            r_Data <= r_Data;     
    
        wire bps_clk;
        assign bps_clk = (div_cnt == 1);
        
        reg [17:0]div_cnt;
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            div_cnt <= 0;
        else if(Send_en)begin
            if(div_cnt == bps_DR - 1)
                div_cnt <= 0;
            else 
                div_cnt <= div_cnt + 1'b1;
        end
        else
            div_cnt <= 0;
    
        reg [3:0]bps_cnt;
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            bps_cnt <= 0;
        else if(Send_en)begin
            if(bps_clk)begin
                if(bps_cnt == 11)
                    bps_cnt <= 0;
                else
                    bps_cnt <= bps_cnt + 1'b1;
            end
        end
        else
            bps_cnt <= 0;
        
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n) 
            uart_tx <= 1'b1;
        else begin
            case(bps_cnt)
                1:uart_tx <= 0;
                2:uart_tx <= r_Data[0];
                3:uart_tx <= r_Data[1];
                4:uart_tx <= r_Data[2];
                5:uart_tx <= r_Data[3];
                6:uart_tx <= r_Data[4];
                7:uart_tx <= r_Data[5];
                8:uart_tx <= r_Data[6];
                9:uart_tx <= r_Data[7]; 
                10:uart_tx <= 1;
                11:begin uart_tx <= 1;end
                default:uart_tx <= 1;
            endcase
         end
         
        always@(posedge Clk or negedge Reset_n)
        if(!Reset_n) 
            Tx_done <= 0;
        else if((bps_clk == 1)  && (bps_cnt == 10))
            Tx_done <= 1;
        else
            Tx_done <= 0;
    
    endmodule
    

    TB:

    `timescale 1ns / 1ps
    
    module uart_tx_test_tb();
        reg Clk;
        reg Reset_n;
        wire uart_tx;
        
         uart_tx_test uart_tx_test(
            .Clk(Clk),
            .Reset_n(Reset_n),
            .uart_tx(uart_tx)
        );
        
        initial Clk = 1;
        always#10 Clk = ~Clk;
        
        initial begin
            Reset_n = 0;
            #201;
            Reset_n = 1;
            #50000000;    
        end
    
    endmodule
    
    展开全文
  • 什么是串行通信串行通信是指使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机、计算机与外设之间的远距离通信。...

    什么是串行通信

    串行通信是指使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机、计算机与外设之间的远距离通信。

    什么是并行通信

    在计算机和终端之间的数据传输通常是靠电缆或信道上的电流或电压变化实现的。如果一组数据的各数据位在多条线上同时被传输,这种传输方式称为并行通信。

    串行通信和并行通信的区别分析

    4d87c5d4d963c73aed0a46cba7c8b15c.png

    串行通信和并行通信的区别分析

    一、并行通信。

    并行通信端口,即LPT1,俗称打印口,因为它常接打印机,它是同时传送八路信号,一次并行传送完整的一个字节信息。

    二、串行通信。

    串行通信端口,即COM1、COM2,一般接鼠标,外置Modem或其他串口设备。它在一个方向上只能传送一路信号,一次只能传送一个二进制位,传送一个字节信息时,只能一位一位地依次传送。

    通讯

    两个设备之间的交流

    通信:并行通信和串行通信

    并行通信在同一时刻发送多位数据

    串行通信用一根线在不同的时刻发送8位数据

    并行通信

    优点发送速度快

    缺点传输距离短资源占用多

    串行通信

    优点传输距离远占用资源少

    缺点发送速度慢

    通信的方式

    1.单工通信只能接受或者发送收音机遥控器

    2.半双工通信在同一时刻只能发送或者接收对讲机

    3.全双工通信在同一时刻既能接收又能发送电话

    4.协议

    数据发送的格式

    Rs232协议:

    例如:发送8位数据0x12;

    发送数据之前先发送一个开始位

    开始位+数据位+奇偶校验位+停止位

    开始位1位低电平

    数据位5~8位用的最多的是8位

    奇偶校验位1位

    停止位1~2位1位1.5位2位

    奇偶校验奇校验通过查看数据中1的个数

    例如选择奇校验

    发送的数据为01011110

    1的个数为基数那么奇偶校验位为0

    如果发送的数据位10101010

    1的个数为偶数那么奇偶校验位为1

    发送方通过发送数据中1的个数,如果为奇数,那么奇偶校验位位0否则为1

    接收方当接收到数据,通过查看数据中1的个数+奇偶校验位1的个数

    如果为奇数,代表数据发送成功,否则失败

    停止位1位2位1.5位

    数字芯片时间通过时钟脉冲

    1位=1个脉冲

    2位=2个脉冲

    1.5位=1.5个脉冲

    3.串口的硬件连接

    4.51单片机中的硬件连接图

    1.ttl电平

    00v~1.5v

    12.5~5v

    展开全文
  • 串行通信(一)

    2021-01-06 13:59:07
    前言 人类生存于世,少不了沟通。沟通使人类互相认知,传递信息,提升生活品质。...通信方式有两种,分别是并行通信和串行通信。并行通信:并行是指多比特数据同时通过并行线进行传送,这样数据传送

    前言

    人类生存于世,少不了沟通。沟通使人类互相认知,传递信息,提升生活品质。但然单片机也需要,不然单单一个机器,无法构成一个系统,发挥更大的力量。只有单片机与外围设备传递信息,互相反馈才会有一个完美的系统。串行口通信就被发明出来,下面来了解串行口通信(uart)。

    几个概念

    为了能更好理解串行口通信,在介绍它之前,先来看看几个概念,补充知识,方便深入明白uart工作原理。

    通信方式

    通信方式通信方式
    通信方式有两种,分别是并行通信串行通信
    并行通信:并行是指多比特数据同时通过并行线进行传送,这样数据传送速度大大提高,但并行传送的线路长度受到限制,因为长度增加,干扰就会增加,数据也就容易出错。
    串行通信:串行通信是指 使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机、计算机与外设之间的远距离通信。
    拿汽车通道来说,并行通信就是多车道,多辆车一起行驶,而串行通信就是单车道,只能一辆一辆车通过。

     

    串行通信制式

    串行通信制式串行通信制式
    串行通信制式有单工通信,半双工通信,双工通信三种。
    单工通信:单工通信信道是单向信道,发送端和接收端的身份是固定的,发送端只能发送信息,不能接收信息;接收端只能接收信息,不能发送信息,数据信号仅从一端传送到另一端,即信息流是单方向的。
    半双工通信:半双工数据传输指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。例如,在一个局域网上使用具有半双工传输的技术,一个工作站可以在线上发送数据,然后立即在线上接收数据,这些数据来自数据刚刚传输的方向。像全双工传输一样,半双工包含一个双向线路(线路可以在两个方向上传递数据)。
    双工通信:双工通信是指在同一时刻信息可以进行双向传输,和打电话一样,说的同时也能听,边说边听。这种发射机和接收机分别在两个不同的频率上(两个频率差有一定要求)能同时进行工作的双工机也称为异频双工机。
    三种通信制式很容易理解,对照上图看,单工通信不就是单方面通信,只能发出指令或接收指令。半双工通信就是能接收又能发送,但是不能同时进行。双工就最厉害,可以同时发送和接收指令。

     

    串行通信分类

    串行通信有两种,一位异步串行通信,二为同步串行通信。
    异步串行通信:异步串行通信是指通信双方以一个字符(包括特定附加位)作为数据传输单位且发送方传送字符的间隔时间不一定,具有不规则数据段传送特性的串行数据传输。
    同步串行通信:所谓同步通信是指在约定的通信速率下,发送端和接收端的时钟信号频率和相位始终保持一致(同步),这就保证了通信双方在发送和接收数据时具有完全一致的定时关系。
    两种串行通信不同就只有时间,在发送字符时,异步可以是不同时间间隔发送,但同步只能以固定的时间间隔发送。

    波特率

    波特率:波特率表示每秒钟传送的二进制位数,是衡量数据传送速率的指标,它用单位时间内载波调制状态改变的次数来表示。
    相互通信的甲乙双方必须具有相同的波特率,不然无法成功完成串行通信。

    概述

    52单片机具有一个全双工串行通信口。一个全双工UART(通用异步接收发送器)的串行I/O口,用于实现单片机之间或单片机与微机之间的串行通信;片内振荡器和时钟产生电路,石英晶体和微调电容需要外接。最佳振荡频率为6M—12M。管脚RXD( P3.0),TXD(P3.1)与串口通信有关。波特率可以设置。

    内部结构

    串行口内部结构逻辑图串行口内部结构逻辑图
    串行口通信与三个寄存器有关,分别是:

     

     1. PCON寄存器
     2. SCON寄存器
     3. SBUF特殊功能寄存器
    

    寄存器

    PCON电源管理寄存器

    电源管理寄存器电源管理寄存器
    SMOD:该位与串口通信有关。
    SMOD=0; 串口方式1,2,3时,波特率正常。
    SMOD=1; 串口方式1,2,3时,波特率加倍
    LVDF:低电压检测标志位,同时也是低电压检测中断请求标志位
    GF1,GF0:两个通用工作标志位,用户可以自由使用。
    PD:掉电模式设定位。
    PD=0 单片机处于正常工作状态。
    PD=1 单片机进入掉电(Power Down)模式 ,可由外部中断或硬件复位模式唤醒,进入掉电模式后,外部晶振停振,CPU、定时器、串行口全部停止工作,只有外部中断工作。在该模式下,只有硬件复位和上电能够唤醒单片机。
    IDL:空闲模式设定位。
    IDL=0 单片机处于正常工作状态。
    IDL=1 单片机进入空闲(Idle)模式,除CPU不工作外,其余仍继续工作,在空闲模式下可由任一个中断或硬件复位唤醒。

     

    这个寄存器只有SMOD位与串行口通信有关。系统复位默认为SMOD=0。当为用52单片机的定时器2产生波特率时,波特率不受SMOD影响。用定时器1产生波特率时,不去设置,就默认为0,波特率正常,设置为1时,波特率加倍。

    SCON串行口控制寄存器

    串行口控制寄存器串行口控制寄存器
    SM0,SM1:共同决定串行口工作模式。
    SM2:多机通信控制位。在方式0中,SM2一定要等于0。在方式1中,当SM2为1时则只有接收到有效停止位时,RI才置1。在方式2或3中,当SM2为1且接收到的第9位数据RB8为0时,RI才置1。
    REN:接收允许控制位。由 软件置位以允许接收,又由 软件清零来禁止接收。
    TB8:要发送数据的第9位。在方式2或3中,要发送的第9位数据,根据需要由软件置1或清零软件置1或清零。例如,可约定作为奇偶校验位,或在多机通信中作为区别地址帧或数据帧的标志位。(很少用)
    RB8:接收到的数据的第9位。在方式0中不使用RB8。在方式1中,若SM2为0,RB8为接收到的停止位。在方式2或3中,RB8为到的第9位数据。(很少用)
    TI:发送中断标志。在方式0中,第8位发送结束时,由 硬件置位。在其它方式的发送停止位前,由 硬件置位。TI置位既表示一帧信息发送结束,同时也向CPU申请中断。可根据需要,用软件查询的方法获得数据已发送完毕的信息,或用中断的方式来发送下一个数据。TI必须用 软件清零
    RI:接收中断标志位。在方式0中,当接收完第8位数据后,由 硬件置位。在其它方式中,在接收到停止位的中间时刻由硬件置位(例外情况见对SM2的说明)。RI表示一帧数据接收完毕,可用查询的方法获知或者用中断的方法获知。RI也必须用 软件清零
    串行口工作模式串行口工作模式
    由于52单片机内部有一个硬件模块,让它自动接收数据,接收完了,通知我们一下就可以了,就不需要再手动配置TB8,RB8。只要配置好SCON,内部就自动帮弄好了。

     

    SBUF特殊功能寄存器

    特殊功能寄存器特殊功能寄存器
    SBUF是指串行口中的两个缓冲寄存器,一个是发送寄存器,一个是接收寄存器,在物理结构上是完全独立的,但地址是重叠的。它们都是字节寻址的寄存器,字节地址均为99H。只要在编写程序时,用不同指令即可操作两个寄存器。
    比如,SBUF=A;这个是指将A的数据移入发送寄存器,然后发送寄存器再把数据发送出去。A=SBUF;则是指将接受寄存器中的数据赋值给A。

     

    串行口方式1

    方式1逻辑图方式1逻辑图
    串行口为10位通用异步接口。发送或接收一帧数据信息为10位,包括1位起始位“0”、8位数据位、1位停止位“1”。发送数据:数据从TXD端口输出,当数据写入发送缓冲器SBUF时,就启动发送器发送。发送完一帧数据后,置中断标志TI=1,申请中断,通知CPU可以发送下一个数据了。接收数据:首先使REN=1(允许接收数据),串行口从RXD接收数据,当采样到1至0跳变时,确认是起始位“0”,就开始接收一帧数据,当接收完一帧数据时,置中断标志RI=1,申请中断,通知CPU从SBUF取走接收到的数据 。

     

    计算波特率

    方式1波特率计算方式1波特率计算
    溢出速率即溢出频率,只要算出定时器每溢出一次所需要的时间T,那溢出率就是1/T。计算在没有波特率加倍(SMOD=0)的情况下,波特率为9600bps时怎样赋值计数器。这里说明一下,由于波特率是需要很精确的,不然通信会出错。如果采用定时器工作模式1,采用人工重载,会有较大误差,因为进入中断函数也需要时间,累积时间就会出错。所以这里运用工作模式2,8位自动重装。计数器自动重装不需人工干预,减少误差。
    对照上面公式,波特率不加倍,SMOD=0,工作模式2,那n=8,波特率=9600,就可以算出x=253,十六进制为fd。

     

    编写步骤

    1. 设置串行口方式
    2. 设置定时器工作模式
    3. 计数器寄存器赋值
    4. 中断寄存器控制
    5. 启动定时器中断
    6. 发送函数
    7. 接收函数

    范例1

    #include<reg52.h>
    unsigned char date;    //定义变量数据中断
    bit flag;  //定义变量标志
    void send (); //声明发送函数
    void receive (); //声明接收函数
    void initialize ();    //声明初始化函数
    main()
    {        
        initialize();  //调用初始化函数
        while(1)
        {
            send();    //调用发送函数
            receive(); //调用接收函数
        }
    }
    void initialize()  //初始化函数
    {
        SCON=0X50;     //0011 0000 串行口工作模式1
        TMOD = 0X20;    //定时器1工作模式2,8为自动重装
        TH1 = 0xFD;     //设定定时初值        波特率为9600
        TL1 = 0xFD;     //设定定时器重装值
        TR1 = 1;        //启动定时器1
        IE=0;
    }
    void send()         //发送函数
    {
        if(flag==1)    //证明已经接收数据
        {   
            SBUF=date;    //将接收的数据发送出去
            while(!TI);   //等待发送中断
            TI=0;         //软件置0
            flag=0;       //清零
        }
    
    }
    void receive()       //接收函数
    {
        while(!RI);   //等待接收中断
        date=SBUF;    //将收到的数据存进接收缓冲寄存器
        RI=0;        //软件置0
        flag=1;      //将标志位置1
    }
    

    范例1是将接受的数据原封不动发送出去。采用查询法,故不需要打开串口中断,不用中断函数。只需不断查询TI,RI的值,就知道数据接收发送情况。

    范例2

    #include<reg52.h>
    unsigned char date;
    bit flag;
    main ()
    {
        SCON=0X50;      //初始化
        TMOD=0X20;
        TH1=0XFD;                                   
        TL1=0XFD;
        IE=0X90;
        TR1=1;
        while(1);
    }
    void interrupt_uart() interrupt 4     //中断函数
    {
        if(RI==1)        //判断有无数据接收
        {
            date=SBUF;     //将寄存器的值赋给变量
            RI=0;          //置0
            flag=1;        //标志位置1
        }
        if(flag==1)             //已接收数据
        {
            SBUF=date;        //将数据发出
            while(!TI);
            TI=0;
            flag=0;
        }
    }
    

    与范例1如出一撤,就不详细注释。

    总结

    在串口通信中,方式1是最常用的,要认真理解方式1。串行数据一位一位的已经不用处理了,52单片机已经有一个模块处理完了。只要知道接收一个数据,产生一次接收中断,要软件置0.,发送一个数据会产生一次发送中断,也要软件置0。自行置0,处理好数据就OK。

    展开全文
  • 51单片机——串行通信

    千次阅读 2021-08-28 23:03:37
    本文首先介绍了并行通信和串行通信的概念,然后对串行通信进行详细的介绍。然后介绍了51单片机的串行通信口的结构与原理,最后介绍了串行通信的四种方式,并介绍了如何计算波特率。

    目录

    1 概述

    1.1 并行通信和串行通信

    1.2 串行通信的两种方式

    1.2.1 异步通信

    1.2.2 同步通信

    1.3 串行通信的数据传送方向

    2 串行通信口的结构与原理

    2.1 串行通信口的结构

    2.2 串行通信口的工作原理

    2.2.1 接收数据过程

     2.2.2 发送数据过程

    3 串行通信口的控制寄存器

    3.1 串行控制寄存器(SCON)

    3.2 电源控制寄存器(PCON)

    4 四种工作方式与波特率的设置

    4.1 方式0

    4.1.1 方式0-发送数据

    4.1.2 方式0-接收数据

    4.2 方式1

    4.2.1 方式1-发送数据

    4.2.2 方式1-接收数据

    4.3 方式2

    4.3.1 方式2-发送数据

    4.3.2 方式2-接收数据

    4.4 方式3

    4.5 波特率的设置

    4.5.1 方式0的波特率

    4.5.2 方式2的波特率

    4.5.3 方式1和方式3的波特率


    1 概述

            通信的概念比较广泛,在单片机技术中,单片机与单片机单片机与其他设备之间的数据传输称为通信。

    1.1 并行通信和串行通信

            根据数据传输方式的不同,可将通信分并行通信串行通信两种。同时传输多位数据的方式称为并行通信。同时传输一位数据的方式称为串行通信

            如图1(a)所示,在并行通信方式下,单片机中的8位数据10011101通过8条数据线同时送到外部设备中。并行通信的特点是数据传输速度快,但由于需要的传输线多,故成本高,只适合近距离的数据通信。逐位传输数据的方式称为串行通信。

            如图1(b)所示,在串行通信方式下,单片机中的8位数据10011101通过一条数据线逐位传送到外部设备中。串行通信的特点是数据传输速度慢,但由于只需要一条传输线,故成本低,适合远距离的数据通信。

    图1 通信方式 

    1.2 串行通信的两种方式

            串行通信又可分为异步通信同步通信两种。51系列单片机采用异步通信方式。

    1.2.1 异步通信

            在异步通信中,数据是一帧一帧传送的。异步通信如图2 所示,这种通信是以帧为单位进行数据传输,一帧数据传送完成后,可以接着传送下一帧数据,也可以等待,等待期间为空闲位(高电平)。

    图2 异步通信

            (1)帧数据格式

            在串行异步通信时,数据是以帧为单位传送的。异步通信的帧数据格式如图3所示。从图中可以看出,一帧数据由起始位、数据位、奇偶校验位和停止位组成。 

     图3 异步通信的帧数据格式

            ① 起始位。

            表示一帧数据的开始,起始位一定为低电平。当单片机要发送数据时,先送一个低电平(起始位)到外部设备,外部设备接收到起始信号后,马上开始接收数据。

            ② 数据位。

            它是要传送的数据,紧跟在起始位后面。数据位的数据可以是5~8位,传送数据时是从低位到高位逐位进行的。

            ③ 奇偶校验位。

            该位用于检验传送的数据有无错误。奇偶校验是检查数据传送过程中是否发生错误的一种校验方式,分为奇校验和偶校验。奇校验是指数据位和校验位中“1”的总个数为奇数,偶校验是指数据位和校验位中“1”的总个数为偶数。以奇校验为例,若单片机传送的数据位中有偶数个“1”,为保证数据和校验位中“1”的总个数为奇数,奇偶校验位应为“1”,如果在传送过程中数据位中有数据产生错误,其中一个“1”变为“0”,那么传送到外部设备的数据位和校验位中“1”的总个数为偶数,外部设备就知道传送过来的数据发生错误,会要求重新传送数据。数据传送采用奇校验或偶校验均可,但要求发送端和接收端的校验方式一致。在帧数据中,奇偶校验位也可以不用。

            ④ 停止位。

            它表示一帧数据的结束停止位可以是1位、1.5位或2位,但一定为高电平。一帧数据传送结束后,可以接着传送第二帧数据,也可以等待,等待期间数据线为高电平(空闲位)。如果要传送下一帧,只要让数据线由高电平变为低电平(下一帧起始位开始),接收器就开始接收下一帧数据。

            (2)51系列单片机的几种帧数据方式

            51 系列单片机在串行通信时,根据设置的不同,其传送的帧数据有以下四种方式:

            ① 方式0。

            称为同步移位寄存器输入/输出方式,它是单片机通信中较特殊的一种方式,通常用于并行I/O接口的扩展,这种方式中的一帧数据只有8位(无起始位、停止位)。

            ② 方式1。

            在这种方式中,一帧数据中有1位起始位、8位数据位和1位停止位,共10位

            ③ 方式2。

            在这种方式中,一帧数据中有1位起始位、8位数据位、1位可编程位和1位停止位,共11位。

            ④ 方式3。

            这种方式与方式2相同,一帧数据中有1位起始位、8位数据位、1位可编程位和1位停止位它与方式2的区别仅在于波特率(数据传送速率)设置不同

    1.2.2 同步通信

            在异步通信中,每一帧数据发送前要用起始位,结束时要用停止位,这样会占用一定的时间,导致数据传输速度较慢。为了提高数据传输速度,在计算机与一些高速设备进行数据通信时,常采用同步通信。同步通信的帧数据格式如图4所示。

     图4 同步通信的帧数据格式

            从图中可以看出,同步通信的数据后面取消了停止位,前面的起始位用同步信号代替,在同步信号后面可以跟很多数据,所以同步通信传输速度快。但由于在通信时要求发送端和接收端严格保持同步,这需要用复杂的电路来保证,所以单片机很少采用这种通信方式。

    1.3 串行通信的数据传送方向

            串行通信根据数据的传送方向可分为三种方式:单工方式半双工方式全双工方式。这三种传送方式如图5所示。

    图5 数据传送方式 

            ① 单工方式。在这种方式下,数据只能向一个方向传送。单工方式如图5(a)所示,数据只能由发送端传输给接收端。

            ② 半双工方式。在这种方式下,数据可以双向传送,但同一时间内,只能向一个方向传送,只有一个方向的数据传送完成后,才能往另一个方向传送数据。半双工方式如图5(b)所示,通信的双方都有发送器和接收器,一方发送时,另一方接收,由于只有一条数据线,所以双方不能在发送的同时进行接收。

            ③ 全双工方式。在这种方式下,数据可以双向传送,通信的双方都有发送器和接收器,由于有两条数据线,所以双方在发送数据的同时可以接收数据。全双工方式如图5(c)所示。

    2 串行通信口的结构与原理

            单片机通过串行通信口可以与其他设备进行数据通信,将数据传送给外部设备或接受外部设备传送来的数据,从而实现更强大的功能。

    2.1 串行通信口的结构

            51单片机的串行通信口的结构如图6所示。

     图6 串行通信口的结构

            与串行通信口有关的部件主要有:

            ① 两个数据缓冲器SBUF。

            SBUF是可以直接寻址的特殊功能寄存器(SFR),它包括发送SBUF和接收SBUF发送SBUF用来发送串行数据,接收SBUF用来接收数据,两者共用一个地址(99H)。在发送数据时,该地址指向发送SBUF;而在接收数据时,该地址指向接收SBUF。

            ② 输入移位寄存器。

            在接收控制器的控制下,将输入的数据逐位移入接收SBUF

            ③ 串行控制寄存器 SCON。

            SCON 的功能是控制串行通信口的工作方式,并反映串行通信口的工作状态

            ④ 定时器T1。

            T1用作波特率发生器,用来产生接收和发送数据所需的移位脉冲,移位脉冲的频率越高,接收和传送数据的速率越快

    2.2 串行通信口的工作原理

            串行通信口有接收数据和发送数据两个工作过程,下面以图6所示的串行通信口结构为例来说明这两个工作过程。

    2.2.1 接收数据过程

            在接收数据时,若RXD端(与P3.2引脚共用)接收到一帧数据的起始信号(低电平),SCON寄存器马上向接收控制器发出允许接收信号,接收控制器在定时器/计数器T1产生的移位脉冲信号控制下,控制输入移位寄存器,将 RXD 端输入的数据由低到高逐位移入输入移位寄存器中,数据全部移入输入移位寄存器后,移位寄存器再将全部数据送入接收 SBUF中,同时接收控制器通过或门向CPU发出中断请求,CPU马上响应中断,将接收SBUF中的数据全部取走,从而完成了一帧数据的接收。后面各帧的数据接收过程与上述相同。

     2.2.2 发送数据过程

            相对于接收过程来说,串行通信口发送数据的过程较简单。当CPU要发送数据时,只要将数据直接写入发送SBUF中,就启动了发送过程。在发送控制器的控制下,发送门打开,先发送一位起始信号(低电平),然后依次由低到高逐位发送数据,数据发送完毕,最后发送一位停止位(高电平),从而结束一帧数据的发送。一帧数据发送完成后,发送控制器通过或门向CPU发出中断请求,CPU响应中断,将下一帧数据送入SBUF,开始发送下一帧数据

    3 串行通信口的控制寄存器

            串行通信口的工作受串行控制寄存器SCON电源控制寄存器PCON的控制。

    3.1 串行控制寄存器(SCON)

            SCON 寄存器用来控制串行通信的工作方式及反映串行通信口的一些工作状态。SCON寄存器是一个8位寄存器,它的地址为98H,其中每位都可以位寻址。SCON寄存器各位的名称和地址如下。

            ① SM0、SM1位:串行通信口工作方式设置位

            通过设置这两位的值,可以让串行通信口工作在四种不同的方式,具体见表1,这几种工作方式在后面将会详细介绍。

    表1 串行通信口工作方式设置位及其功能

            ② SM2位:用来设置主-从式多机通信

            当一个单片机(主机)要与其他几个单片机(从机)通信时,就要对这些位进行设置。当SM2=1时,允许多机通信;当SM2=0时,不允许多机通信。

            ③ REN位:允许/禁止数据接收的控制位

            当REN=1时,允许串行通信口接收数据;当REN=0时,禁止串行通信口接收数据。

            ④ TB8位:方式2、3中发送数据的第9位

            该位可以用软件规定其作用,可用作奇偶校验位,或在多机通信时,用作地址帧或数据帧的标志位,在方式0和方式1中,该位不用。

            ⑤ RB8位:方式2、3中接收数据的第9位

            该位可以用软件规定其作用,可用作奇偶校验位,或在多机通信时,用作地址帧或数据帧的标志位,在方式1中,若SM2=0,则RB8是接收到的停止位。

            ⑥ TI位:发送中断标志位

            当串行通信口工作在方式0时,发送完8位数据后,该位自动置“1”(即硬件置“1”),向CPU发出中断请求,在CPU响应中断后,必须用软件清0在其他几种工作方式中,该位在停止位开始发送前自动置“1”,向CPU发出中断请求,在CPU响应中断后,也必须用软件清0,以准备开始发送下一帧数据

            ⑦ RI位:接收中断标志位

            当串行通信口工作在方式0时,接收完8位数据后,该位自动置“1”,向CPU发出接收中断请求,在CPU响应中断后,必须用软件清0在其他几种工作方式中,该位在接收到停止位期间自动置“1”,向CPU发出中断请求,在CPU响应中断取走数据后,必须用软件对该位清0,以准备开始接收下一帧数据。在上电复位时,SCON各位均为“0”。

    3.2 电源控制寄存器(PCON)

            PCON寄存器是一个8位寄存器,它的字节地址为87H,不可位寻址并且只有最高位SMOD与串行通信口控制有关。PCON寄存器各位的名称和字节地址如下。

            SMOD位:波特率设置位。

            在串行通信口工作在方式1~3时起作用。若SMOD=0,波特率不变;当SMOD=1时,波特率加倍。在上电复位时,SMOD=0。

    4 四种工作方式与波特率的设置

            串行通信口有四种工作方式工作在何种方式受SCON寄存器的控制。在串行通信时,要改变数据传送速率(波特率),可对波特率进行设置

    4.1 方式0

            当SCON寄存器中的SM0=0、SM1=0时,串行通信口工作在方式0

            方式0称为同步移位寄存器输入/输出方式,常用于扩展I/O端口。在单片机发送或接收串行数据时,通过RXD端发送数据或接收数据,而通过TXD端送出数据传输所需的移位脉冲

            在方式0时,串行通信口又分两种工作情况:发送数据和接收数据。

    4.1.1 方式0-发送数据

            当串行通信口工作在方式0时,若要发送数据,通常在外部接8位串/并转换移位寄存器74LS164,具体连接电路如图7所示。其中RXD端用来输出串行数据,TXD端用来输出移位脉冲,P1.0端用来对74LS164进行清0

     图7 串行通信在方式0时的数据发送电路

            在单片机发送数据前,先从P1.0引脚发出一个清0信号(低电平)到74LS164的CLR引脚,对其进行清0,让D7~D0全部为“0”然后单片机在内部执行写SBUF指令,开始从RXD端(P3.0引脚)送出8位数据,与此同时,单片机的TXD端输出移位脉冲到74LS164的CLK引脚,在移位脉冲的控制下,74LS164接收单片机RXD端送到的8位数据(先低位后高位),数据发送完毕,在74LS164的D7~D0端输出8位数据。另外,在数据发送结束后SCON寄存器的发送中断标志位TI自动置“1”

    4.1.2 方式0-接收数据

            当串行通信口工作在方式0时,若要接收数据,一般在外部接8位并/串转换移位寄存器74LS165,具体连接电路如图8 所示。在这种方式时,RXD端用来接收输入的串行数据,TXD端用来输出移位脉冲,P1.0端用来对74LS165的数据进行锁存

     图8 串行通信口在方式0时的数据接收电路

            在单片机接收数据前,先从 P1.0 引脚发出一个低电平信号到74LS165 的S/\overline{L}\引脚,让74LS165锁存由D7~D0端输入的8位数据,然后单片机内部执行读SBUF指令,与此同时,单片机的TXD端送移位脉冲到74LS165的CLK1引脚,在移位脉冲的控制下,74LS165中的数据逐位从RXD端送入单片机,单片机接收数据完毕,SCON寄存器的接收中断标志位RI自动置“1”。

            在方式0中,串行通信口发送和接收数据的波特率都是fosc/12

    4.2 方式1

            当SCON寄存器中的SM0=0、SM1=1时,串行通信口工作在方式1

            在方式1时,串行通信口可以发送和接收每帧10位的串行数据其中TXD端用来发送数据,RXD端用来接收数据。

            在方式1中,一帧数据中有10位,包括1位起始位(低电平)、8位数据位(低位在前)和1位停止位(高电平)。在方式1时,串行通信口又分两种工作情况:发送数据和接收数据。

    4.2.1 方式1-发送数据

            在发送数据时,若执行写SBUF指令,发送控制器在移位脉冲(由定时器/计数器T1产生的信号再经16或32分频而得到)的控制下,先从TXD端送出一个起始位(低电平),然后再逐位将8位数据从 TXD 端送出,当最后一位数据发送完成,发送控制器马上将SCON的TI位置“1”,向CPU发出中断请求,同时从TXD端输出停止位(高电平)

    4.2.2 方式1-接收数据

            在方式1时,需要设置SCON中的REN=1,串行通信口才允许接收数据。由于不知道外部设备何时会发送数据,所以串行通信口会不断检测RXD端,当检测到RXD端有负跳变(由“1”变为“0”)时,说明外部设备发来了数据的起始位,于是启动RXD端接收,将输入的8位数据逐位移入内部的输入移位寄存器。8位数据全部进入输入移位寄存器后,如果满足RI位为“0”、SM2位为“0”(若SM2不为“0”,但接收到的数据停止位为“1”也可以)的条件,输入移位寄存器中的8位数据才可以放入SBUF,停止位的“1”才能送入SCON的RB8位中,RI位就会被置“1”,向CPU发出中断请求,让CPU取走SBUF中的数据,如果条件不满足,输入移位寄存器中的数据将无法送入SBUF而丢弃,重新等待接收新的数据

    4.3 方式2

            当SCON寄存器中的SM0=1、SM1=0时,串行通信口工作在方式2

            在方式2时,串行通信口可以发送和接收每帧11位的串行数据,其中1位起始位、8位数据位、1位可编程位和1位停止位。TXD端用来发送数据,RXD端用来接收数据

            在方式2时,串行通信口又分两种工作情况:发送数据和接收数据。

    4.3.1 方式2-发送数据

            在方式2时,发送的一帧数据有11位,其中有9位数据,第9位数据取自SCON中的TB8位。在发送数据前,先用软件设置TB8位的值,然后执行写SBUF指令(如MOV SBUF,A),发送控制器在内部移位脉冲的控制下,从TXD端送出一个起始位(低电平),然后逐位送出8位数据,再从TB8位中取出第9位并送出,当最后一位数据发送完成,发送控制器马上将SCON的TI位置“1”,向CPU发出中断请求,同时从TXD端输出停止位(高电平)

    4.3.2 方式2-接收数据

            在方式2时,同样需设置SCON的REN=1,串行通信口才允许接收数据,然后不断检测RXD端是否有负跳变(由“1”变为“0”),若有,说明外部设备发来了数据的起始位,于是启动RXD端接收数据。当8位数据全部进入输入移位寄存器后,如果RI位为“0”、SM2位为“0”(若SM2不为“0”,但接收到的第9位数据为“1”也可以),输入移位寄存器中的8位数据才可以送入SBUF,第9位会放进SCON的RB8位,同时RI位置“1”,向CPU发出中断请求,让CPU取走SBUF中的数据,否则输入移位寄存器中的数据将无法送入SBUF而丢弃

    4.4 方式3

            当SCON中的SM0=1、SM1=1时,串行通信口工作在方式3方式3与方式2一样,传送的一帧数据都为11位,工作原理也相同,两者的区别仅在于波特率不同,方式2的波特率固定为fosc/64或fosc/32,而方式3的波特率则可以设置

    4.5 波特率的设置

            在串行通信中,为了保证数据的发送和接收成功,要求发送方发送数据的速率与接收方接收数据的速率相同,而将双方的波特率设置相同就可以达到这个要求。在串行通信的四种方式中,方式0的波特率是固定的,而方式1~方式3的波特率则是可变的波特率是数据传送的速率,它用每秒传送的二进制数的位数来表示,单位符号是bit/s

    4.5.1 方式0的波特率

            方式0的波特率固定为时钟振荡频率的1/12,即方式0的波特率 = fosc/12

    4.5.2 方式2的波特率

            方式2的波特率由PCON寄存器中的SMOD位决定

            当SMOD = 0时,方式2的波特率为时钟振荡频率的1/64;

            当SMOD = 1时,方式2的波特率加倍,为时钟振荡频率的1/32,即

    方式2的波特率 = fosc*2^{SMOD}/64

    4.5.3 方式1和方式3的波特率

            方式1和方式3的波特率除了与SMOD位有关,还与定时器/计数器T1的溢出率有关。方式1和方式3的波特率可用下式计算:

    方式1、3的波特率 = T1的溢出率·2^{SMOD}/32

            T1的溢出率是指定时器/计数器T1在单位时间内计数产生的溢出次数,也即溢出脉冲的频率

            在将定时器/计数器T0设作工作方式3时,T1可以工作在方式0、方式1或方式2三种方式下。

            当T1工作于方式0时,它对脉冲信号(由时钟信号fosc经12分频得到)进行计数,计到2^{13}时会产生一个溢出脉冲到串行通信口作为移位脉冲;

            当T1工作于方式1和2时,则分别要计到2^{16}2^{8}−X(X为T1的初值,可以设定)才产生溢出脉冲。

            如果要提高串行通信口的波特率,可让T1工作在方式2,因为该方式计数时间短,溢出脉冲频率高,并且能通过设置T1的初值来调节计数时间,从而改变T1产生的溢出脉冲的频率(又称T1的溢出率)。

            当T1工作在方式2时,T1两次溢出的时间间隔,也即T1的溢出周期为

    T1的溢出周期 = (2^{8}− X)·12/ fosc

            T1的溢出率为溢出周期的倒数,即

    T1的溢出率 = fosc/[12·(2^{8}− X)]

            故当T1工作在方式2时,串行通信口工作方式1、3的波特率为

            方式1、3的波特率 = (2^{SMOD}/32)·fosc/[12·(2^{8}− X)] 

            由上式可推导出T1在方式2时,其初值X为

    X = 2^{8}− (2^{SMOD}·fosc)/(384·波特率)

            举例:单片机的时钟频率fosc=11.0592MHz,现要让串行通信的波特率为2400bit/s,可将串行通信口的工作方式设为1、T1的方式设为2,并求出T1应设的初值。

            求T1初值的过程如下。

            先进行寄存器设置:为了让波特率不倍增,将 PCON 寄存器中的数据设为00H,这样SMOD位就为“0”;设置TMOD寄存器中的数据为20H,这样T1就工作在方式2。再计算并设置T1的初值:

    X = 2^{8}2^{SMOD}·fosc/384·波特率 = 256 −(2^{0}× 11.0592 × 10^{6})/(384 × 2400)= 244

            十进制数244转换成十六进制数为F4H,将T1的初值设为F4H。

            由于设置波特率和初值需要计算,比较麻烦,一般情况下可查表来进行设置。常见的波特率设置见表2。

    表2 常用的波特率设置

    展开全文
  • 串行通讯一条信息的各位数据被逐位按顺序传送的通讯方式称为串行通讯。串行通讯的特点是:数据位传送,传按位顺序进行,最少只需一根传输线即可完成,成本低但送速度慢。串行通讯的距离可以从几米到几千米。 根据...
  • 而按照串行数据的时钟控制方式,串行通信又可分为同步通信和异步通信两种方式。1、异步串行方式的特点所谓异步通信,是指数据传送以字符为单位,字符与字符间的传送是完全异步的,位与位之间的传送基本上是同步的。...
  • 本文主要给出一个实用的java 串口通信程序,供大家讨论学习./******************************************* 程序文件名称:SendComm.java* 功能:从串行口COM1中发送数据****************************************...
  • 什么是计算机通信计算机通信基本原理并行与串行通信方式异步通信和同步通信 什么是计算机通信 计算机通信是指计算机个计算机之间或计算机与终端之间进行信息传递的方式。 通信中有并行和串行两种方式。在单片机系统...
  • 尽管比按字节(byte)传输的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。 串口通信中比较重要的参数包括波特率、数据位、停止位及校验位,通讯双方需要约定一致的数据格式才能正常收发...
  • 串行通信结构及工作原理 51系列单片机的串行口主要有两个数据缓冲器SBUF,一个输入移位寄存器(9位),一个穿行控制寄存器SCON和一个波特率发生器T1等组成。 图2 串行口结构框图(图片来自网络)系统总体设计 图2 ...
  • 数据通信的基本方式根据数据的传输方式可以分为串行通信与并行通信两种。 串行通信又根据数据的同步方式,分为异步传送和同步传送两种方式。或者根据数据的传输方向与时间关系,分为单工通信、半双工通信及全双工...
  • TXD发送端、RXD接收端 异步传输(ascall) 传输单位:字符 起始位0 数据位的倒序 校验位 停止位:1 比特率:b/s每秒传输2进制的位数 同步传输 单位:数据块 速率高 短距离(开发板、存储器中) 半双工(RXD数据...
  • 串行通信原理

    2021-02-19 23:39:52
    一、通信接口的背景知识 ...1、常见的串行通信接口 二、STM32串口通信接口 1、UART异步通信方式引脚 2、UART异步通信方式特点 3、串口通信过程: 4、STM32串口异步通信需要定义的参数: ...
  • 综合实验报告实验题目: 双机串行通信的设计与实现学生班级: 电子学生姓名:学生学号:指导教师:实验时间: 2016.9.12-2016.9.170题目:双机串行通信的设计与实现班级:电子 14-2 姓名:陈俊臣摘要串行通信是单片机的...
  • 综 合 实验 报告实验题目 :双机串行通信的设计与实现学生班级 :电子学生姓名 :学生学号 :指导教师 :实验时间 :.9.12- .9.17题目 :双机串行通信的设计与实现资料内容仅供您学习参考,如有不当或者侵权,请联系改正...
  • 发送设备将这些数据位通过对应的数据线传送给接收设备,还可附加一位数据校验位。接收设备可同时接收到这些数据,不需要做任何变换就可直接使用。并行方式主要用于近距离通信。计算机内部的总线结构就是并行通信的...
  • 串行通信时是指设备之间通过少量数据信号线(一般是8根以下)、地线及控制信号线,按数据位形式一位一位地传输数据的通信方式。 并行通信 一般是指使用8、16、32及64根或更多的数据线进行传输的通信方式。并行通信...
  • 并行通信是指数据同时进行传送,串行通信是指数据一位一位地依次传输,两种通信方式各有优缺点。 #include<reg51.h> #define uchar unsigned char; code uchar tab_cc[]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d...
  • 串行通信有单工通信、半双工通信和全双工通信3种方式。 单工通信:数据只能单方向地从一端向另一端传送。例如,目前的有线电视节目,只能单方向传送。 半双工通信:数据可以双向传送,但任一时刻只能向一个方向...
  • 串行通信串行通信是指使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机、计算机与外设之间的远距离通信。 拿...
  • http://www.51hei.com 出品汇编语言串口通信程序mov p1,#0ffhmov p3,#0ffh;mov p3,#00hmov p1,#00hMOV SCON,#50H;设置成串口1方式MOV TMOD,#20H;波特率发生器T1工作在模式2上MOV PCON,#80H;波特率翻倍为2400x2=4800...
  • 串行通信数据传输方式比较 单工 半双工 全双工 数据传输方向 A→B A↔B A↔B A、B之间的导线数量 1条 1条 2条 传输时间 同时 分时 同时 ...
  • 串口流控提供了由于某种原因不能进行通讯时...3. TXD→ Transmit Data 发送数据 4.DTR→ Data Terminal Ready数据终端就绪 5. GND— System Ground 系统接地 6. DSR← Data Set Ready 数据设备就绪 7. RTS→ R...
  • ORG 00HSJMP INITORG 0023HLJMP LOOPORG 0030HINIT: MOV SP,#5FHMOV SCON,#50H ;串行口工作方式1,允许接收MOV TMOD,#20H ;定时器1工作方式2MOV PCON,#0H ;波特率不加倍MOV TH1,#0FDH ...
  • 通过实验,发现在简单的三线连接电路中,INT14H不能用来通信,无法发送和接收。下面详细给出笔者采用的能实现通信的方法,供参考。一、计算机串口编程PC/XT计算机串口的核心是通用异步接收/发送器8250。附表是计算机...
  • MSP432的串行通信

    千次阅读 2021-07-23 15:43:53
    目录数字通信基本知识组成串行通信和并行通信同步通信和异步通信异步串行通信的通用基础知识异步串行通信的格式串行通信的波特率奇偶校验串行通信传输方式术语1.全双工(Full-duplex)2.半双工(Half-duplex)3.单工...
  • 用C51实现带奇偶校验的串行通信MCS-51系列单片机的串行口有4种工作方式。方式0为移位寄存器方式,用于外接同步I/O设备或扩展I/O口,不算起始位和停止位。方式1为8位异步串行通讯,方式2和方式3...
  • 串行通信中,数据是二进制脉冲的形式。换句话说,我们可以说二进制1表示逻辑高电平或5伏特,零表示逻辑低电平或0伏特。串行通信可以采用多种形式...串行通信是一种使用双线即发送器(发送器)和接收器逐位发送数据的...
  • 读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇...
  • 串行传输中,使用一根数据线传输数据,一次传输1个比特,多个比特需要一个接一个依次传输。 一根数据线,将数据一位一位的传输。双方按照一定规则对数据进行解析。 串行传输可分为异步传输、同步传输和等时传输。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 111,858
精华内容 44,743
关键字:

串行通信,是如何发送数据的?