设计目标

本文实现uart发送多个数据给上位机,上位机显示,这里不对数据进行解析。
这次实现的是使用开发板每隔一秒向上位机发送“I love you”。下一篇博文实现当发送"I love you too",开发板进行相应处理(看时间安排)
开发板上电后打开串口助手即可看到接受的数据

实现思路

这里实现思路其实很简单,就是控制在什么时候发送什么数据。具体见代码,这里预留了一个状态为以后的数据解析。看有没有时间。
仿真也很简单,直接给一个时钟信号,同时将复位拉高即可。(说明:这里笔者对之前的发送模块进行了一点点小的修改,添加了一个发送结束信号,发送结束,将其拉高一个时钟周期)

代码

数据发送

`timescale 1ns / 1ps
module data_send(input          s_clk           ,input          s_rst_n         ,output             RS232_tx        );
reg     [7:0]   pi_data         ;       //要发送的数据
reg             tx_en           ;       //发送使能,与发送模块相连接
reg             tx_en_ctr       ;       //发送使能控制信号,控制发送使能的拉高与拉低
localparam  S0 = 3'b001,S1 = 3'b010,S2 = 3'b100;      //定义的三种状态,状态一等待计数结束进行数据的发送//状态二发送数据,结束后跳到状态一//状态三待补充
localparam cnt_done  = 49_999_999;
reg     [2:0]   curr_st;
reg     [2:0]   next_st;
reg [5:0] delay;            //延时的时钟周期数
wire send_done;             //发送数据结束标志
reg [4:0] k;            //要发送第几个字符
reg [7:0] store [19:0]; //存储发送字符
always @ (posedge s_clk)
begin //定义发送的字符store[0  ]   <=  8'd0       ;           //不能用来存储字符store[1   ]   <=  8'd73      ;           //存储字符 Istore[2 ]   <=  8'd32      ;           //存储字符空格    store[3 ]   <=  8'd76      ;           //存储字符 Lstore[4 ]   <=  8'd111     ;           //存储字符 ostore[5 ]   <=  8'd118     ;           //存储字符 vstore[6 ]   <=  8'd101     ;           //存储字符 e store[7    ]   <=  8'd32      ;           //存储字符空格    store[8 ]   <=  8'd89      ;           //存储字符 Ystore[9 ]   <=  8'd111     ;           //存储字符 ostore[10]   <=  8'd117     ;           //存储字符 ustore[11]   <=  8'd32      ;           //存储字符空格store[12]   <=  8'd94      ;           //存储字符^store[13]    <=  8'd95      ;           //存储字符_store[14]    <=  8'd94      ;           //存储字符^store[15]    <=  8'd32      ;           //存储字符空格store[16]   <=  8'd32      ;           //存储字符空格store[17]   <=  8'd32      ;           //存储字符空格store[18]   <=  8'd10      ;           //换行符store[19]  <=  8'd13      ;           //回车符
end
reg [27:0] cnt_1s;          //一秒计数寄存器
reg cnt_1s_done;            //一秒结束标志信号
//计数一秒,只有在状态S0的时候才进行计数
always @ (posedge s_clk or negedge s_rst_n)
begin  if(!s_rst_n)cnt_1s <= 'd0;else if(cnt_1s == cnt_done)//当cnt_1s为24_999_999的时候,重新计数并且将clk1反转cnt_1s <= 'd0;  elseif(curr_st == S0)cnt_1s <= cnt_1s + 1'b1;   else cnt_1s <= 0;
end
//当计数到一秒时候拉高一个时钟周期的一秒计数信号
always @ (posedge s_clk or negedge s_rst_n)
begin  if(!s_rst_n)cnt_1s_done <= 0;else  if(cnt_1s == cnt_done)//当cnt_1s为24_999_999的时候,重新计数并且将clk1反转cnt_1s_done <= 1; elsecnt_1s_done <= 0;
end//状态机,描述转态转移
always @ (posedge s_clk or negedge s_rst_n)
beginif(!s_rst_n)curr_st <= S0;else curr_st <= next_st;
end
//组合逻辑,判断转移条件
always @ (*)
begincase(curr_st)S0 : beginif(cnt_1s_done == 1'b1)next_st = S1;else next_st = S0;     end S1 :beginif(send_done == 1'b1)next_st = S0;else next_st = S1;  enddefault:next_st = S0;endcase
end
//时序逻辑进行输出,这里输出的是要发送的数据以及发送使能信号
always @ (posedge s_clk or negedge s_rst_n)
beginif(!s_rst_n)beginpi_data       <= 8'h00;tx_en         <= 1'b0 ;  endelse begincase(next_st)S0 : beginpi_data     <= 8'h00;tx_en         <= 1'b0 ;  endS1   :beginpi_data       <= store[k];tx_en       <= tx_en_ctr ;enddefault        :  ;endcase end
end
/
//以上完成了状态机的基本模块,下面对于里面的信号进行控制,什么时候发送,发送的数据是第几个等等
/
always @ (posedge s_clk or negedge s_rst_n)
beginif(!s_rst_n)tx_en_ctr <= 1'b0;else if((k == 0 && next_st == S1) || (delay[5] == 1'b1))tx_en_ctr <= 1'b1;else tx_en_ctr <= 1'b0;
end //assign OUT_delay = delay[5];
always @ (posedge s_clk or negedge s_rst_n)
beginif(!s_rst_n)delay <= 'd0;else delay <= {delay[4:0],tx_done};
end always @ (posedge s_clk or negedge s_rst_n)
beginif(!s_rst_n)k <= 'd0;else if(tx_en_ctr == 1'b1)k <= k + 1'b1;else if(k == 'd20)k <= 'd0;else k <= k;
end assign send_done = ((k == 'd19)  && (delay[5] == 1'b1)) ? 1'b1 : 1'b0;uart_tx uart_tx0 (.clk       (s_clk      ), .rst_n       (s_rst_n    ), .pi_data     (pi_data    ), .tx_en       (tx_en      ), .tx_data (RS232_tx   ), .tx_done (tx_done    ));
endmodule

串口模块

`timescale 1ns / 1ps
module uart_tx(//-----------input clk,rst_n,pi_data,tx_en,//-----------output tx_data,tx_done);
input clk;
input rst_n;
input [7:0] pi_data;
input tx_en;
output reg tx_data;
output reg tx_done;always @ (bit_cnt)
beginif(bit_cnt == 4'd11)tx_done = 1'b1;else tx_done = 1'b0;
endlocalparam baud_cnt_end = 'd434 - 'd1                         ;
// localparam baud_cnt_m    = (baud_cnt_end ) / 'd2               ;
// localparam baud_cnt_m    = (baud_cnt_end + 'd1) / 'd2 - 'd1  ;reg tx_en1;
reg tx_en2;
reg tx_flag;
reg [12:0] baud_cnt;
reg [3:0] bit_cnt;
always@(posedge clk )
begintx_en1 <= tx_en;tx_en2 <= tx_en1;
endalways @ (posedge clk or negedge rst_n)
beginif(!rst_n)tx_flag <= 1'b0;else if(tx_en2 && !tx_flag)tx_flag <= 1'b1;else if(bit_cnt == 'd10 && baud_cnt == baud_cnt_end)tx_flag <= 1'b0;
end
//reg [3:0] bit_cnt;
always@(posedge clk or negedge rst_n)
beginif(!rst_n)bit_cnt <= 4'd0;else if(!tx_flag)bit_cnt <= 4'd0;else if(baud_cnt == baud_cnt_end)bit_cnt <= bit_cnt + 1'b1;else   bit_cnt <= bit_cnt;
end
//reg [12:0] baud_cnt;
always@(posedge clk or negedge rst_n)
beginif(!rst_n)baud_cnt <= 13'd0;  else if(baud_cnt == baud_cnt_end)baud_cnt <= 13'd0;else if(tx_flag)baud_cnt <= baud_cnt + 1'b1;else baud_cnt <= 13'd0;
end
reg [7:0] pi_data_r;
always@(posedge clk or negedge rst_n)
beginif(!rst_n)pi_data_r <= 8'd0;else if(tx_en)pi_data_r <= pi_data;else pi_data_r <= pi_data_r;
end
//define tx_data
always@(posedge clk or negedge rst_n)
beginif(!rst_n)tx_data <= 1'b1;else if(tx_flag)case(bit_cnt)4'd0 : tx_data <= 1'b0           ;4'd1 : tx_data <= pi_data_r[0]    ;4'd2 : tx_data <= pi_data_r[1]    ;4'd3 : tx_data <= pi_data_r[2]    ;4'd4 : tx_data <= pi_data_r[3]    ;4'd5 : tx_data <= pi_data_r[4]    ;4'd6 : tx_data <= pi_data_r[5]    ;4'd7 : tx_data <= pi_data_r[6]    ;4'd8 : tx_data <= pi_data_r[7]    ;4'd9 : tx_data <= 1'b1           ;default:;endcaseelse tx_data <= 1'b1;
end
endmodule

需要工程的留邮箱即可,我看到会抽时间发!有问题欢迎提出,愿共勉!!!

基于FPGA实现uart串口模块——进阶版1相关推荐

  1. 基于FPGA实现uart串口模块(Verilog)--------发送模块及整合

    基于FPGA实现uart串口模块(Verilog)--------发送模块及整合 当接收模块接收到数据后,需要重新发送形成回环验证模块正确性.思路和结束模块有一点点的小差异.接收模块最终输出的是一个并 ...

  2. 基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结

    基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结 uart通信协议简单理解为串转并和并转串的两个模块.同时必须保证数据的正确性.且输入输出端为串行. 此次实现uar ...

  3. 基于FPGA的UART串口通信实验(VHDL语言实现)

    一.前言: 最近在做UART串口通信的相关实验时,在网上查了很多资料,发现网上的大部分文章只注重理论,不注重代码,很多代码有错误不说,而且难以理解.故在完成此实验后,起了写一篇博客的心思,以供有想做相 ...

  4. 基于FPGA的UART异步串行通信发送模块设计与实现

    欢迎关注微信公众号"FPGA科技室",更多内容请关注 下一篇文请点击下列链接(接收模块设计) [基于FPGA的UART异步串行通信接收模块设计与实现] 本文发送模块: 在电子系统中 ...

  5. 基于FPGA的UART接口协议设计

    一.PC终端概述 PC终端,Personal Computer 智能终端,通俗的讲,就是利用电脑GUI界面控制我们的外部硬件电路. 因此设计到了PC与外部硬件电路的通信接口.对于台式电脑.个人笔记本, ...

  6. 基于 FPGA 的 UART 控制器设计(VHDL)(下)

    今天给大侠带来基于FPGA的 UART 控制器设计(VHDL)(下),由于篇幅较长,分三篇.今天带来第三篇,下篇,使用 FPGA 实现 UART.话不多说,上货. 之前有关于 Veriliog HDL ...

  7. 2.3 基于FPGA的UART协议实现(一)串口信号定义和接线方法-5针串口-9针串口-全功能串口

      通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART.它将要传输的资料在串行通信与并行通信之间加以转换.作为把并行输入信号 ...

  8. 【FPGA】——UART串口通信

    UART串口简介   串行通信分为两种方式:同步串行通信和异步串行通信.同步串行通信要求通信双方使用同一时钟,异步则没有这个要求.UART是一种采用异步串行通信方式的通用异步收发传输器(univers ...

  9. FPGA实现uart串口协议

    reference:正点原子视频教程 具体代码请参考B站正点原子官方 UART串口通信原理 是一种采用异步串行通信方式的通用异步手法传输器. 因为是异步通信所以,使用的时候要进行同步到系统时钟下,不然 ...

最新文章

  1. Go 语言编程 — 逻辑控制语句
  2. cannot connect to vCenter Single Sign-on server...
  3. Python 日期时间函数
  4. REACT map dictionary
  5. 国家开放大学2021春1474临床医学概论(本)题目
  6. C++中的sort函数对二维数组排序是按照什么准则?
  7. java list分批_Java实用笔记——mybatis批量导入
  8. 类型与通用语言运行时:System.Object
  9. 资料下载地址和我加入的论坛
  10. 黑马vue实战项目-(五)参数列表组件的开发
  11. Python基础: python3书籍推荐
  12. 获取上周一及上周天日期
  13. DataV 你值得拥有的大屏展示工具
  14. @Adaptive注解
  15. NTFS文件系统文件删除对比
  16. Ubuntu鼠标移动中闪烁解决方法
  17. R语言 逻辑回归模型与混淆矩阵
  18. 微信小程序调试webview_微信小程序内嵌webview相关知识点整理
  19. 计算机应用领域的实践,计算机技术在通信技术领域的应用实践探微
  20. php文本输入框,html文本输入框代码是什么?如何创建html文本输入框

热门文章

  1. 安装DotNetCore.1.0.0-VS2015Tools.Preview2.exe 错误Error 0x81f40001 解决方法
  2. mysql中更改字符集为utf8mysql中文输入不了问题解决
  3. 在提交消息中链接到GitHub上的问题编号
  4. JavaScript中的“ new”关键字是什么?
  5. 循环报数java代码_循环报数 Java实现
  6. c 语言 循环判断语句,C值循环语句(七)
  7. 麦克纳姆轮速度分解再分析
  8. html语言汇总,第三讲HTML语言全面介绍汇总.ppt
  9. 洛谷——P1980 [NOIP2013 普及组] 计数问题
  10. 文字围绕浮动元素的妙用(HTML、CSS)