基于FPGA的串口发送

这篇具有很好参考价值的文章主要介绍了基于FPGA的串口发送。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于FPGA的串口发送(E/FPGACode/uart_tx_new)

一、串口

  • 串口简称UART
  • 设计的目的是用来发送数据的,因此需要有一个数据输入端口,用来发送这8bit数据。类似于实验中的Ctrl,用来指定亮灭模式
  • 支持不同的波特率,所以需要有一个波特率设置端口。类似于计数器实验中的Time
  • 如下图所示,本质是把这8位的并行数据通过一根信号线在不同的时刻分别以高低电平一位一位得传出去。并行输入,串行输出

fpga串口发送数据,fpga开发

  • 1位的低电平标志串行传输的开始待8位数据传输完成之后,再以1位的高电平标志传输的结束
    fpga串口发送数据,fpga开发
  • 数据什么时候发?答:发送开始信号-Send_en
  • 一串数据什么时候发送结束?答:发送完成标志信号-Tx_Done

二、串口简易图

uart_tx=起始位+data[7:0]+结束位

fpga串口发送数据,fpga开发

三、 问题


module uart_byte_tx(
	input [7:0] data,
	input Send_en,
	input Clk,
	input Reset_n,
	input [2:0] Baud_set,//假设只支持8种波特率
	output reg uart_tx,
	output reg Tx_Done
    );
	
	reg [17:0] div_cnt;
	
	//计算不同波特率时计数的次数
	//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@(*)begin
		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	
	end
	
	
	//计数基本时间单元
	always@(posedge Clk or negedge Reset_n)begin
		if(!Reset_n)begin
			div_cnt<=0;
		end else if(Send_en)begin
			if(div_cnt == bps_DR-1) begin
				div_cnt<=0;
			end else begin
				div_cnt<=div_cnt+1'b1;
			end
		end else
			div_cnt<=0;
	end
	
	reg [3:0] bps_cnt;
	
	//发送10个段:开始+8数据+结束,一共需要11个clk确定
	always@(posedge Clk or negedge Reset_n)begin
		if(!Reset_n)begin
			bps_cnt<=0;
		end else if(Send_en)begin
			if(div_cnt == bps_DR-1) begin
				if(bps_cnt==11)
					bps_cnt<=0;
				else
					bps_cnt<=bps_cnt+1'b1;
			end 
		end else
			bps_cnt<=0;
	end
	
	always@(posedge Clk or negedge Reset_n)begin
		if(!Reset_n)begin
			Tx_Done<=1'b0;
			uart_tx<=1'b1;
		end else begin
			case(bps_cnt)
				0:begin uart_tx<=1'b0;Tx_Done<=0;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<=1'b1;
				10:begin uart_tx=1'b1;Tx_Done<=1;end
				default:uart_tx=1'b1;
			endcase
		end
	end
	
endmodule

fpga串口发送数据,fpga开发

1、当Send_en从0变成1时,代表开始传递数据。uart_tx初始为1,所以当send_en上升沿时,uart_tx应该同时变成0,代表传输START(低电平)位。
但是由图片可知,uart_tx大概早了将近1位的时间就将其拉为低电平。

  • 分析:由代码可知,当bps_cnt=0时,将uart_tx=0;
  • 解决方法:将case(bps_cnt)改成从1-11.

fpga串口发送数据,fpga开发
改完之后的波形图如上图所示,当bps_cnt=1时,才将uart_tx=0,传输开始位。

fpga串口发送数据,fpga开发
2、两个蓝色的marker标志在这个空闲时间中,是让uart_tx一直保持为1。但是这个有必要吗?如何进行更改?

  • 分析:这两个marker是因为当Send_en为1时,才开始计时,当div_cnt == bps_DR-1,即div_cnt计满一次,bps_cnt才+1.所以就相当于多计了一个bps_cnt.
			if(div_cnt == bps_DR-1) begin
				if(bps_cnt==11)
					bps_cnt<=0;
				else
					bps_cnt<=bps_cnt+1'b1;
			end 
  • 修改:当div_cnt=1时,就进行+1.
		if(div_cnt == 1) begin
				if(bps_cnt==11)
					bps_cnt<=0;
				else
					bps_cnt<=bps_cnt+1'b1;
			end 

四、 串口发送数据任务

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

问题一

//每隔10ms发送一个数据
    always @(posedge Clk or negedge Reset_n) begin
        if (!Reset_n) begin
            counter<=0;
        end
        else if (counter == 500000-1) begin
            counter<=0;
        end else
            counter<=counter+1;
    end

    always @(posedge Clk or negedge Reset_n) begin
        if (!Reset_n) begin
            Send_en<=0;
        end
        else if (counter==1) begin
            Send_en<=1;
        end else if(Tx_Done) begin
            Send_en<=0;
        end
    end

    always @(posedge Tx_Done or negedge Reset_n) begin
        if (!Reset_n) begin
            data<=0;
        end else begin
            data <= data+1'b1;
        end
    end

fpga串口发送数据,fpga开发
波形图:1、Tx_Done一直为1,导致poedeg Tx_Done检测不到,所以data无法进行自加
2、继续分析,Tx_Done什么时候0->1,1->0
看E://uart_byte_tx,当bps_cnt=1时,Tx_Done=1,当bps_cnt=11时,Tx_Done=1。
当Tx_Done=1时,Send_En就会变成0.此时bps_cnt就不会再+1.由此成了一个死循环.
修改:可以从波形图看到,bps_cnt是从0->a,然后就一直持续为0.刚好我们前面有一个为0的状态位没有用到。此时就将bps_cnt=0时,

问题二:串口波形图的时序要求,Tx_Done从3个节拍改为1个节拍,所以不能使用posedge Tx_Done

fpga串口发送数据,fpga开发

分析:为什么是3个周期?
当bps_cnt=11时,Tx_Done=1.此时,Send_En从1->0.但在下一个节拍才能变为0(非阻塞赋值)。再到下一个节拍才能知晓已经为0,此时bps_cnt才从11变成0.当bps_cnt=0时,再过一个节拍Tx_Done=0.
修改:

always@(posedge Clk or negedge Reset_n)begin
		if(!Reset_n)begin
			Tx_Done<=1'b0;
			uart_tx<=1'b1;
		end else begin
			case(bps_cnt)
				0:Tx_Done<=0;
				1:uart_tx<=1'b0;
				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'b1;
				11:uart_tx=1'b1;
				default:uart_tx=1'b1;
			endcase
		end
	end

	always @(posedge Clk or negedge Reset_n)begin
		if(!Reset_n)
			Tx_Done<=0;
		else if((bps_cnt==10)&&(bps_clk==1))
			Tx_Done<=1;
		else
			Tx_Done<=0;
	end

五、板级编译

最后上板子调试,发现一直接收的是00,后看了一篇博客发现是在不同的always块中对同一个信号进行赋值。这是不允许的!!!!!
这是那篇博客/提问链接:https://ask.csdn.net/questions/7737125

六、 运行成功

串口之数据传输文章来源地址https://www.toymoban.com/news/detail-614831.html

到了这里,关于基于FPGA的串口发送的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA串口接收解帧、并逐帧发送有效数据——1

    工程实现的功能:FPGA串口接收到串口调试助手发来的数据,将其数据解帧。判断到正确的帧头和帧尾之后,将有效数据存入rx_data中;另一方面发送端将有效数据逐帧发送出去。 参考:正点原子官方FPGA串口通信实验 模块构成: 在原子哥的基础上改的代码。 添加了接收状态机

    2024年02月05日
    浏览(39)
  • 通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置

    目录 1.算法理论概述 串口通信模块 指令解析模块 位置控制模块 显示器驱动模块 2.部分核心程序 3.算法运行软件版本 4.算法运行效果图预览 5.算法完整程序工程         通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置是一种常见的应用场景,用于实现对显示器

    2024年02月16日
    浏览(54)
  • FPGA 按键控制串口发送

    消抖时间一般为10ms,我使用的板子是ACX720,晶振为50MHZ,20ns为一周期。 状态机 模块设计 设计文件 仿真验证 **注意:**电平信号的传输线中有一个参考电平线(一般是GND),然后信号线上的信号值是由信号线电平和参考电平线的电压差决定。 所以我们一定要养成模块之间共地的

    2024年04月11日
    浏览(37)
  • FPGA初步学习之串口发送模块【单字节和字符串的发送】

    UART 在发送或接收过程中的一帧数据由4部分组成,起始位、数据位、奇偶校验位和停止位,如图所示。其中,起始位标志着一帧数据的开始,停止位标志着一帧数据的结束,数据位是一帧数据中的有效数据。 通常用的串口数据帧格式是:8位数据位,无校验位,1位停止位。

    2024年02月14日
    浏览(45)
  • 【FPGA零基础学习之旅#14】串口发送字符串

    🎉欢迎来到FPGA专栏~串口发送字符串 ☆* o(≧▽≦)o *☆ 嗨 ~我是 小夏与酒 🍹 ✨ 博客主页: 小夏与酒的博客 🎈该系列 文章专栏: FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 📜 欢迎大家关注! ❤️ 🥝 发送Hello: 🥝 发送数字字符并自

    2024年02月08日
    浏览(40)
  • 【FPGA零基础学习之旅#13】串口发送模块设计与验证

    🎉欢迎来到FPGA专栏~串口发送模块 ☆* o(≧▽≦)o *☆ 嗨 ~我是 小夏与酒 🍹 ✨ 博客主页: 小夏与酒的博客 🎈该系列 文章专栏: FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 📜 欢迎大家关注! ❤️ 🥝 发送测试: 🥝 issp调试测试: 数据

    2024年02月09日
    浏览(55)
  • 【FPGA】UART串口通信---基于FIFO

    我们在上一章完成了UART串口通信的收发模块,这一章我们将FIFO引入进来,使用FIFO进行缓存数据,来连接串口通信的收发模块 FIFO即First In First Out,是一种先进先出数据存储、缓冲器,我们知道一般的存储器是用外部的读写地址来进行读写,而FIFO这种存储器的结构并不需要外

    2023年04月14日
    浏览(82)
  • FPGA开发基础篇之一(接口篇)UART串口

    写在前面 从本文开始,将连载fpga开发基础知识,将这几年浅显的fpga开发经验整理出来,一是梳理一下这几年给别人做fpga的经历,同时也是分享给大家,也希望大牛批评指正。 一、UART串口通信基本概念 串口通信是非常基本且应用十分广泛的低速通信接口,无论是在dsp、单片

    2024年02月02日
    浏览(60)
  • 基于FPGA的超声波测距——UART串口输出

    环境: 1、Quartus18.0 2、vscode 3、板子型号:EP4CE10F17C8 4、超声波模块:HC_SR04 要求: 使用 EP4CE10F17C8开发板驱动 超声波检测模块(HC_SR04 ),并将所测得数据显示到串口助手上。 HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发

    2024年02月14日
    浏览(44)
  • 基于FPGA的SDI发送接口调试,FPGA+GV7700实现1080p和720p的显示

    # 基于FPGA的SDI发送接口调试,FPGA+GV7700实现1080p和720p的显示 上一篇文章已经调试了bt11200接口,本章将基于bt1120接口完善代码,实现1080p60Hz和720p60Hz的显示兼容。 720p60Hz的数据格式 1080p60Hz的数据格式 上板测试,显示彩条 顶层文件 GBR to YUV422顶层 RGB to YUV444 YUV444 to YUV422 YUV422 t

    2024年02月13日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包