基于FPGA实现uart串口模块——进阶版1
设计目标
本文实现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相关推荐
- 基于FPGA实现uart串口模块(Verilog)--------发送模块及整合
基于FPGA实现uart串口模块(Verilog)--------发送模块及整合 当接收模块接收到数据后,需要重新发送形成回环验证模块正确性.思路和结束模块有一点点的小差异.接收模块最终输出的是一个并 ...
- 基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结
基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结 uart通信协议简单理解为串转并和并转串的两个模块.同时必须保证数据的正确性.且输入输出端为串行. 此次实现uar ...
- 基于FPGA的UART串口通信实验(VHDL语言实现)
一.前言: 最近在做UART串口通信的相关实验时,在网上查了很多资料,发现网上的大部分文章只注重理论,不注重代码,很多代码有错误不说,而且难以理解.故在完成此实验后,起了写一篇博客的心思,以供有想做相 ...
- 基于FPGA的UART异步串行通信发送模块设计与实现
欢迎关注微信公众号"FPGA科技室",更多内容请关注 下一篇文请点击下列链接(接收模块设计) [基于FPGA的UART异步串行通信接收模块设计与实现] 本文发送模块: 在电子系统中 ...
- 基于FPGA的UART接口协议设计
一.PC终端概述 PC终端,Personal Computer 智能终端,通俗的讲,就是利用电脑GUI界面控制我们的外部硬件电路. 因此设计到了PC与外部硬件电路的通信接口.对于台式电脑.个人笔记本, ...
- 基于 FPGA 的 UART 控制器设计(VHDL)(下)
今天给大侠带来基于FPGA的 UART 控制器设计(VHDL)(下),由于篇幅较长,分三篇.今天带来第三篇,下篇,使用 FPGA 实现 UART.话不多说,上货. 之前有关于 Veriliog HDL ...
- 2.3 基于FPGA的UART协议实现(一)串口信号定义和接线方法-5针串口-9针串口-全功能串口
通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART.它将要传输的资料在串行通信与并行通信之间加以转换.作为把并行输入信号 ...
- 【FPGA】——UART串口通信
UART串口简介 串行通信分为两种方式:同步串行通信和异步串行通信.同步串行通信要求通信双方使用同一时钟,异步则没有这个要求.UART是一种采用异步串行通信方式的通用异步收发传输器(univers ...
- FPGA实现uart串口协议
reference:正点原子视频教程 具体代码请参考B站正点原子官方 UART串口通信原理 是一种采用异步串行通信方式的通用异步手法传输器. 因为是异步通信所以,使用的时候要进行同步到系统时钟下,不然 ...
最新文章
- Go 语言编程 — 逻辑控制语句
- cannot connect to vCenter Single Sign-on server...
- Python 日期时间函数
- REACT map dictionary
- 国家开放大学2021春1474临床医学概论(本)题目
- C++中的sort函数对二维数组排序是按照什么准则?
- java list分批_Java实用笔记——mybatis批量导入
- 类型与通用语言运行时:System.Object
- 资料下载地址和我加入的论坛
- 黑马vue实战项目-(五)参数列表组件的开发
- Python基础: python3书籍推荐
- 获取上周一及上周天日期
- DataV 你值得拥有的大屏展示工具
- @Adaptive注解
- NTFS文件系统文件删除对比
- Ubuntu鼠标移动中闪烁解决方法
- R语言 逻辑回归模型与混淆矩阵
- 微信小程序调试webview_微信小程序内嵌webview相关知识点整理
- 计算机应用领域的实践,计算机技术在通信技术领域的应用实践探微
- php文本输入框,html文本输入框代码是什么?如何创建html文本输入框
热门文章
- 安装DotNetCore.1.0.0-VS2015Tools.Preview2.exe 错误Error 0x81f40001 解决方法
- mysql中更改字符集为utf8mysql中文输入不了问题解决
- 在提交消息中链接到GitHub上的问题编号
- JavaScript中的“ new”关键字是什么?
- 循环报数java代码_循环报数 Java实现
- c 语言 循环判断语句,C值循环语句(七)
- 麦克纳姆轮速度分解再分析
- html语言汇总,第三讲HTML语言全面介绍汇总.ppt
- 洛谷——P1980 [NOIP2013 普及组] 计数问题
- 文字围绕浮动元素的妙用(HTML、CSS)