⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart_my.txt

📁 自己设计的串口verilog代码
💻 TXT
字号:
/**********************************************************************
**
**-------------------------------------------文件信息----------------------------------------------------------
** 文件名称:           uart_test.v 
** 创建者:      
** 创建日期:           2008  
** 版本号:             V3.0 
** 功能描述:         串口通信顶层模块 
** 
**--------------------------------------修改文件的相关信息--------------------------------------------------
** 修改人:  
** 修改日期:  
** 版本号:  
** 修改内容:  
**
*******************************************************************************/
module uart_test(
    clock,      //系统时钟
    RXD,                        //uart接收引脚
    TXD         //uart发送引脚
    );
 input   clock;        //系统时钟(48MHz)
 input   RXD;       //uart接收引脚
 output  TXD;       //uart发送引脚

 reg     [7:0] senddata;     //发送一个字节的数据缓存区
 reg     WR_R1,WR_R2,WR_R3;    //控制产生一个发送的写信号

 wire    [7:0]recdata;     //接收缓存区
 wire    RI,TI,WR;      //接收、发送中断以及写控制信号    
 wire    clksend,clkrec;     //发送和接收的时钟频率
 wire    clk100M;
/********************************************************************************
** 模块名称:
** 功能描述:通过RI接收中断产生一个写信号,维持时间为1个Clk
********************************************************************************/
always@(posedge clksend)         
begin
 WR_R1 <= RI;
 WR_R2 <= WR_R1;
 WR_R3 <= WR_R2;
end

assign WR = (~WR_R3)&(WR_R2)&(WR_R1); //控制写信号
/********************************************************************************
** 模块名称:
** 功能描述:当接收了一个数据后,把数据加1后发回PC机
********************************************************************************/
always@(posedge RI)      
begin
    senddata <= recdata+8'd1;
end

rec   uartrec(       //实例化一个uart接收模块
            .clk(clock),
            .clkout(clkrec),
            .dataout(recdata),
            .RXD(RXD),
            .RI(RI)
            );

send   uartsend(      //实例化一个uart的发送模块
              .clk(clock),
              .clkout(clksend),
              .datain(senddata),
              .TXD(TXD),
              .TI(TI),
             . WR(WR)
              );

endmodule

发送模块:

/**********************************************************************
**
**-------------------------------------------文件信息----------------------------------------------------------
** 文件名称:       send.v 
** 创建者:      
** 创建日期:       2008  
** 版本号:         V3.0 
** 功能描述:     UART的发送模块 
** 
**--------------------------------------修改文件的相关信息--------------------------------------------------
** 修改人:    
** 修改日期:     2008 
** 版本号:         V3.0 
** 修改内容:     整理 
**
*******************************************************************************/
module send(
   clk,         //时钟
   clkout,         //输出
   datain,         //需要发送的一个字节数据
   TXD,         //uart发送引脚 
   TI,          //发送中断
   WR,          //写控制信号
            rst          //复位        
   );
 input           rst;
 input   clk;       //输入时钟
 input   WR;        //写信号
 input [7:0] datain;       //发送的一字节数据
 output   clkout;       //输出时钟
 output   TXD,TI;       //串行数据,发送中断

 reg  [9:0] datainbuf,datainbuf2;   //发送数据缓存
 reg    WR_ctr,TI,TXD_reg;    //写标志、中断标志、一位发送寄存器
 reg  [3:0] bincnt;       //发送数据计数器
 reg  [15:0] cnt;       //计数器

 wire   clk_equ;      //分频时钟

 parameter       cout = 5000;        //根据具体的时钟来设定分频系数
                //这里是48M时钟,波特率选择是9600,所以分频系数为48000000/9600= 5000;      
/********************************************************************************
** 模块名称:
** 功能描述:波特率发生进程
********************************************************************************/
always@(posedge clk)          
begin
    if(rst)
        cnt <= 16'd0;
    else
     if(clk_equ)
      cnt <= 16'd0;
     else 
      cnt<=cnt+1'b1;
end

assign clk_equ = (cnt == cout);
assign clkout = clk_equ;
/********************************************************************************
** 模块名称:
** 功能描述:读数据到缓存进程
********************************************************************************/

always@(posedge clk)
begin
    if(rst)
     begin
        datainbuf <= 10'd0;
        WR_ctr <= 1'b0;
     end
    else   
 if(WR) 
 begin
  datainbuf <= {1'b1,datain[7:0],1'b0};  //读入数据,并把缓存组成一帧数据,10位 datain[7:0]
  WR_ctr <= 1'b1;        //置开始标志位
 end
 else if(TI==0)
  WR_ctr <= 1'b0;
end
 

/********************************************************************************
** 模块名称:
** 功能描述:主程序进程
********************************************************************************/

always@(posedge clk)
begin
    if(rst)
    begin
        TXD_reg <= 1'b1;
        TI <= 1'b1;
        bincnt <= 4'd0;
    end
    else if(clk_equ)                               //发送条件判断,保证发送数据的完整性
     begin
      if(WR_ctr==1||TI==0) 
       if(bincnt<4'd10)
          begin
        TXD_reg <= datainbuf>>bincnt; //移位输出
        bincnt <= bincnt + 4'd1;        //发送数据位计数
        TI <= 1'b0;
       end
       else
                    begin
            bincnt <= 4'd0;
                        TI <= 1'b1;
                        TXD_reg <= 1'b1;
                    end

    end  
end
 
assign TXD = TXD_reg;        //TXD连续输出

endmodule 

接收模块:

/********************************
**                                     
**
**-------------------------------------------文件信息----------------------------------------------------------
** 文件名称:       rec.v 
** 创建者:      
** 创建日期:       2008  
** 版本号:         V3.0 
** 功能描述:     UART的接收模块 
** 
**--------------------------------------修改文件的相关信息--------------------------------------------------
** 修改人:    
** 修改日期:     2008 
** 版本号:         V3.0 
** 修改内容:     整理 
**
*******************************************************************************/
module rec(
           clk,
     clkout,
     dataout,
     RXD,
     RI,
     rst
     );

 input           rst;
 input    clk,RXD;         //时钟与数据输入
 output    clkout,RI;         //时钟输入、接收中断输出
 output [7:0] dataout;          //并行数据输出

 reg    StartF,RI;         //开始与接收中断标志
 reg  [9:0]  UartBuff;           //接收缓存区
 reg  [3:0] count,count_bit;       //位接收计数器
 reg    [15:0]  cnt;          //时钟节拍计数器
 reg  [2:0] bit_collect;        //采集数据缓存区

 wire    clk_equ,bit1,bit2,bit3,bit4;    //连线

 parameter      cout = 312;         //时钟是48M所以16*9600的分频数为312.5,这里取整数

/********************************************************************************
** 模块名称:
** 功能描述:波特率发生进程
********************************************************************************/

always@(posedge clk)            //时钟节拍计数器
begin
    if(rst)
        cnt <= 16'd0;
    else
    begin
     if(clk_equ)
      cnt <= 16'd0;
     else 
      cnt <= cnt + 1'b1;
    end 
end

assign clk_equ = (cnt == cout);        //采样时钟
assign clkout = clk_equ;

assign   bit1 = bit_collect[0]&bit_collect[1];    //对采样数据进行判断
assign   bit2 = bit_collect[1]&bit_collect[2];    //对采样数据进行判断
assign   bit3 = bit_collect[0]&bit_collect[2];    //对采样数据进行判断
assign   bit4 = bit1|bit2|bit3;        //对采样数据进行判断,只要有两次相同就可以
/********************************************************************************
** 模块名称:
** 功能描述:UART的接收模块,接收采样率为波特率的16倍
********************************************************************************/

always@(posedge clk)
begin
    if(rst)
    begin
        count <= 4'd0;
        RI <= 1'b1;
        StartF <= 1'b0;
        bit_collect <= 3'd0;
        UartBuff <= 10'd0;
    end
    else
begin
 if(clk_equ)
 begin
  if(!StartF)           //是否处于接收状态
  begin
   if(!RXD)
   begin 
    count <= 4'b0;        //复位计数器
    count_bit <= 4'b0;
    RI <= 1'b0; 
    StartF <= 1'b1; 
   end
   else  RI <= 1'b1;
  end
  else 
  begin
   count <= count+1'b1;       //位接收状态加1
   if(count==4'd6)
    bit_collect[0] <= RXD;      //数据采集
   if(count==4'd7)
    bit_collect[1] <= RXD;      //数据采集 
   if(count==4'd8)
   begin
    bit_collect[2] <= RXD;      //数据采集
    UartBuff[count_bit] <= bit4;
    count_bit <= count_bit+1'b1;    //位计数器加1
    if((count_bit==4'd1)&&(UartBuff[0]==1'b1)) //判断开始位是否为0
    begin
     StartF <= 1'b0;       //标志开始接收
    end
    RI <= 1'b0;         //中断标志位低
   end 
   if(count_bit>4'd9)        //检测是否接收结束
   begin 
    RI <= 1'b1;         //中断标志为高标志转换结束
    StartF <= 1'b0;
   end
  end
 end
end
end
 
assign  dataout = UartBuff[8:1];          //取出数据位 

endmodule 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -