FPGA小记

UART协议:

发送端:串\rightarrow并       接收端:并\rightarrow

接口:clk    rst_n    uart_en      tx_data  (发送二进制的数据)    

           txd 发送端               uart_state(状态)

1.clk:50Mhz

2.rst_n  默认低电平有效,数据复位,当处于高电平时,程序正常工作。

3.tx_data   输入信号

4.当使能信号uart_en上升沿到达后,开始低位传输

5.当没有uart_en时,开始位\rightarrow1

6.uart_state,开始运行时,拉高(表示传输数据开始),在停止信号达到之前,拉低(表示传输数据结束)

7.波特率:bps   每传输一位需要多少时钟:

8.clk_cnt:

 

9.tx_cnt:

uartspii2c
2根线4线工作(片选线cs、sck串行时钟、mosi模式、miso模式)2根线(SCL、SDA)实现双向通信,具有地址定向性和主从模式

优点:

1:适用性广泛;

2:长距离通信

缺点:

1:速度较低

2:

232全双工(单端传输);485半双工(差分传输),485相比于232拥有更强的抗干扰能力

3:不可靠由于uart是异步通信,可能会造成噪声和干扰的影响,导致数据传输不可靠

优点:

1:spi通信速度较快,适用于对速度要求较高的应用

2:全双工,支持全双工通信,可以同时进行数据接收和发送

3:通信协议相对简单,适用于快速开发和调试

缺点:

1:连线复杂,spi需要多根线进行连接,可能会增加硬件设计的复杂性,spi比i2c需要更多的引脚。

2:长距离传输受限,过长的线路可能会导致信号衰减或干扰

3:

spi通常采用主从模式,主设备数量受限制,不适用于多主设备场景

优点:

1:多设备支持:i2c设备支持多个设备连接在同一条总线上,每个设备都有唯一地址

2:简单,i2c协议相对简单,易于实现和调试

3:低功耗,在空闲状态时,i2c总线上的器件进入低功耗模式,节省能量

半双工

缺点:

1:通信速度较慢,用于低俗设备;

2:i2c的总线长度和设备数量收到限制,过长的总线会导致通信问题

3:当多个设备尝试同时发送数据时,可能会发生冲突,需要额外的冲突检测和处理机制

 

 

module uart_tx(
input wire clk, //系统时钟50Mhz
input wire  uart_rst_n,    //复位信号低有效
input uart_en,   //发送端使能信号
input wire [7:0] tx_data,
output reg txd ,  //发送的数据信号
output  reg  tx_state //发送端状态
wire en_flag ;//使能标志位
assign en_flag=(~uart_en_d1)&uart_en_d0;//检测到上升沿,使能信号拉高

);
//波特率定义模块
localparam clk_fre=50_000_000;  
localparam baud=115200;
localparam baud_N=clk/baud;//传输一位需要的时钟周期
//发送端使能信号的异步两拍同步
always @(posedge clk or negedge urat_rst_n)begin
        if(!uart_rst_n)begin
           uart_en_d0<=1'b0;
            uart_en_d1<=1'b0; 

end
        else begin
      
         uart_en_d0<=uart_en;
        uart_en_d1<=uart_en_d0;


end

end

module uart_tx.v(
input   ckl,
input   rst_n,
input [7:0] data,
input   send_en,
input [5:0] baud_set,
output uart_tx,
output tx_done,
uart_state
);
 reg [17:0]   bps_DR ;
always@(posedge clk or negedge rst_n)
  if(!rst_n)
     bps_DR<=16'd5207;
  else   begin
         case(baud_set)
            0:bps_DR<=17'd5207;
            1:bps_DR<=17'd2603;
            2:bps_DR<=17'd1301;
            4:bps_DR<=17'd867;
            5:bps_DR<=17'd433;
            default:bps_DR<=17'd5207;    //默认状态为9600bps
       endcase
    end

 reg [17:0]   div_cnt;     //波特率为300所对应的最大计数值
always@(posedge clk or negedge rst_n)
    if(!rst_n)
          div_cnt<=0;
   else if(uart_state)begin
         if(div_cnt==bps_DR)

   
         end
       
            


 

end   
       

endmodule


奇偶分频

一、N分频(N为偶数)

注意时钟翻转条件为N/2 -1(从0开始计数)

以8分频为例:


module div_clk(
input clk,
input rst_n,
output   wire clk_8

    );
    reg  [1:0] cnt
//计数器   
 always@(posedge clk or negedge rst_n)
 if(!rst_n)
            cnt<=2'd0;
 else if(cnt_p==2'd3)   //以0开始计数,当计数到(N/2 -1)时,计数清0
            cnt<=2'd0;
        else 
            cnt<=cnt+2'd1;
                   
 always@(posedge clk or negedge rst_n)
        if(!rst_n)begin
                clk_8<=1'd0;
 end
 else if(cnt==2'd3)
         clk_8<=~clk_8;
  else    
         clk_8<=clk_8;
    end 
    
endmodule

以7分频为例:(占空比不是50%)

对时钟上升沿计数即可,设置两个计数的翻转点,分别为0到(N-1)/2和N-1

module div_clk(
input clk,
input rst_n,
output   reg clk_7
    );
    reg  [2:0] cnt;
  
 always@(posedge clk or negedge rst_n)
 if(!rst_n)
            cnt<=2'd0;
 else if(cnt==3'd6)
            cnt<=3'd0;
        else cnt<=cnt+3'd1;
 always@(posedge clk or negedge rst_n)
        if(!rst_n)begin
                clk_7<=1'd0;
 end
 else if(cnt<3'd4)//在0到N-1/2输出低电平,N-1/2 +1到N-1输出高电平(此时占空比不是百分之50)
         clk_7<=1'd0;
     else
        clk_7<=1'd1;
endmodule

以7分频为例:(占空比50%)

a     分别设计上升沿计数器cnt_p、下降沿计数器cnt_n、上升沿分频器clk_p、下降沿分频器clk_n

b:

//复位信号均是低电平有效

module div_clk(
input clk,
input rst_n,
output   wire clk_7    //占空比要求百分之50

    );
    reg  [2:0] cnt_p;
    reg  [2:0] cnt_n;
    reg clk_p;
    reg clk_n;
  //上升沿计数
 always@(posedge clk or negedge rst_n) //时钟上升沿有效,上升沿开始计数
 if(!rst_n)
            cnt_p<=3'd0;
 else if(cnt_p==3'd6)
            cnt_p<=3'd0;
        else 
            cnt_p<=cnt_p+3'd1;
   //上升沿分频                  
 always@(posedge clk or negedge rst_n)
        if(!rst_n)begin
                clk_p<=1'd0;
 end
 else if((cnt_p==3'd3)||(cnt_p==3'd6))begin    //(若计数器的上升沿计数到3或计数器计数到6,上升沿分频输出均取反操作)
         clk_p<=~clk_p;
    end 
  //下降沿计数
 always@(negedge clk or negedge rst_n)//    时钟下降沿开始计数,下降沿有效
        if(!rst_n)
            cnt_n<=2'd0;
 else if(cnt_n==3'd6)
            cnt_n<=3'd0;
        else 
            cnt_n<=cnt_n+3'd1; 
 //下降沿分频           
    always@(negedge clk or negedge rst_n)
        if(!rst_n)begin
                clk_n<=1'd0;
 end
 else if((cnt_n==3'd3)||(cnt_n==3'd6))begin//(若计数器的下降沿计数到3或计数器计数到6,下降沿分频输出取反操作))
         clk_n<=~clk_n;
 end    
    assign clk_7=(clk_p|clk_n)  ;//将上升沿和下降沿取或操作,得到7分频输出,且占空比为50%
endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值