首页 > 技术 > 内容

fpga串口通信的verilog驱动编程解析

时间:2025-12-04  作者:Diven  阅读:0

串口的全程为串行接口,也称为串行通信接口,是采用串行通信方式的扩展接口。与串口对应的并行接口,例如高速AD和DA,

这些都是用的并行接口,而且在编程也简单一些。

串口有一下特点:

(1)通信线路简单,只要一对传输线就可以实现双向通信。

(2)布线简单,成本低。

(3)通信距离长,可以实现数米到数千米的通信距离。

(4)传输速率慢。

常见的串口速率如4800 , 9600 , 115200bps,代表每秒钟发送多少bit数据,例如9600bps就代表1秒内发送9600bit数据。 

串口协议 :协议比较简单,一般都是10位数据,1个起始位 低电平 ,然后八个数据位,低位在前,一个奇偶校验位,平时

一般不用,最后是一位停止位高电平,这样一帧数据发送结束。

下面介绍一下我的程序框架:

整体框架分为两个部分:一个是串口驱动部分 另一个是串口数据控制部分。串口驱动部分负责串口驱动和波特率的选择,串口数据控制模块

负责控制数据内容的控制和发送速度的控制。

从上面时序图可以看出,每10ms发送一帧数据,这里data_en负责波特率驱动使能,uart_tx_end有两个功能,一个是关闭data_en使能,另一个是给10ms计数器

清零。

module uart_tx_driver( //global clock input clk , //system clock input rst_n , //sync reset //uart interface output reg uart_tx , //user interface input [1:0] bps_select , //波特率选择 input [7:0] uart_data , input data_en , //发送数据使能 output reg uart_tx_end);//--------------------------------//Funtion : 参数定义parameter BPS_4800 = 14'd10417 , BPS_9600 = 14'd5208 , BPS_115200 = 14'd434 ;reg [13:0] cnt_bps_clk ;reg [13:0] bps ;reg bps_clk_en ; //bps使能时钟reg [3:0] bps_cnt ;wire [13:0] BPS_CLK_V = bps >> 1 ;//--------------------------------//Funtion : 波特率选择always @(posedge clk or negedge rst_n)begin if(!rst_n) bps <= 1'd0; else if(bps_select == 2'd0) bps <= BPS_115200; else if(bps_select == 2'd1) bps <= BPS_9600; else bps <= BPS_4800;end//--------------------------------//Funtion : 波特率计数always @(posedge clk or negedge rst_n)begin if(!rst_n) cnt_bps_clk <= 1'd0;    else if(cnt_bps_clk >= bps - 1 && data_en == 1'b0) cnt_bps_clk <= 1'd0; else cnt_bps_clk <= cnt_bps_clk + 1'd1;end //--------------------------------//Funtion : 波特率使能时钟always @(posedge clk or negedge rst_n)begin if(!rst_n) bps_clk_en <= 1'd0; else if(cnt_bps_clk == BPS_CLK_V - 1) bps_clk_en <= 1'd1; else bps_clk_en <= 1'd0;end//--------------------------------//Funtion : 波特率帧计数always @(posedge clk or negedge rst_n)begin if(!rst_n) bps_cnt <= 1'd0; else if(bps_cnt == 11) bps_cnt <= 1'd0; else if(bps_clk_en) bps_cnt <= bps_cnt + 1'd1;end//--------------------------------//Funtion : uart_tx_endalways @(posedge clk or negedge rst_n)begin if(!rst_n) uart_tx_end <= 1'd0; else if(bps_cnt == 11) uart_tx_end <= 1'd1; else uart_tx_end <= 1'd0;end//--------------------------------//Funtion : 发送数据always @(posedge clk or negedge rst_n)begin if(!rst_n) uart_tx <= 1'd1; else case(bps_cnt) 4'd0 : uart_tx <= 1'd1; 4'd1 : uart_tx <= 1'd0; //begin 4'd2 : uart_tx <= uart_data[0];//data 4'd3 : uart_tx <= uart_data[1]; 4'd4 : uart_tx <= uart_data[2]; 4'd5 : uart_tx <= uart_data[3]; 4'd6 : uart_tx <= uart_data[4]; 4'd7 : uart_tx <= uart_data[5]; 4'd8 : uart_tx <= uart_data[6]; 4'd9 : uart_tx <= uart_data[7]; 4'd10 : uart_tx <= 1; //stop default : uart_tx <= 1; endcaseendendModule 
Module uart_tx_control( //global clock input clk , //system clock input rst_n , //sync reset //user interface output reg [7:0] uart_data , output reg data_en , input uart_tx_end );//--------------------------------//Funtion : 参数定义paRAMeter DELAY_10MS = 500_000 ;reg [31:0] cnt_10ms ;wire delay_10ms_done ;//data definereg [31:0] cnt_1s;//--------------------------------//Funtion : cnt_10msalways @(posedge clk or negedge rst_n)begin if(!rst_n) cnt_10ms <= 1'd0; else if(cnt_10ms == DELAY_10MS - 1 && uart_tx_end == 1'd1) cnt_10ms <= 1'd0; else cnt_10ms <= cnt_10ms + 1'd1;endassign delay_10ms_done = (cnt_10ms == DELAY_10MS - 1) ? 1'd1 : 1'd0;//--------------------------------//Funtion : data_enalways @(posedge clk or negedge rst_n)begin if(!rst_n) data_en <= 1'd0; else if(delay_10ms_done) data_en <= 1'd1; else if(uart_tx_end) data_en <= 1'd0;end///////////////////////数据测试///////////////////////////////--------------------------------//Funtion : cnt_1salways @(posedge clk or negedge rst_n)begin if(!rst_n) cnt_1s <= 1'd0; else if(cnt_1s == 49_999_999) cnt_1s <= 1'd0; else cnt_1s <= cnt_1s + 1'd1;end//--------------------------------//Funtion : uart_dataalways @(posedge clk or negedge rst_n)begin if(!rst_n) uart_data <= 1'd0;    else if(uart_data >= 10) uart_data <= 1'd0; else if(cnt_1s == 49_999_999) uart_data <= uart_data + 1'd1;endendmodule 

编辑:黄飞

 

猜您喜欢


电子元器件中,电容器是重要组成部分。瓷片电容和独石电容是两种常见类型。很多人可能不清楚之间的区别。本文将简单介绍这两种电容器的特点和差异。材料构成不同瓷片电容是...
2025-03-27 06:00:34
YAGEO(国巨)作为压敏电阻领域的佼佼者,凭借其很好的性能和的应用赢得了众多用户的青睐。本文将深入探讨YAGEO压敏电阻与其品牌之间的区别,帮助您更好地理解其...
2021-12-16 13:37:37
贴片电阻上的「010」标识并非直接代表阻值,而是采用一种特殊的编码方式来表示。010代表的是10欧姆的阻值。这种编码方式通常采用三位数字表示,前两位数字代表有效...
2024-11-26 11:29:33
在现代计算机和电子设备中,PCI(外围组件互连)和PCIe(PCI扩展)连接器是非常重要的配件。是连接主板与各种扩展卡的桥梁,支持显卡、声卡、网卡等硬件的安装与...
2011-06-09 00:00:00
贴片电阻,作为电子电路中很重要的元件,其封装形式直接影响着电路板的空间利用率和性能表现。别看身材小巧,却在电路中是重要的配件,控制着电流的流动。常见的贴片电阻封...
2024-11-29 10:25:42
一字螺丝批因其独特的设计和多功能性,成为了日常工具箱中的必备利器。刀头形状简单明了,适用于多种一字螺丝,使用方便,减少了寻找合适工具的时间。一字螺丝批通常具有较...
2009-07-29 00:00:00
发光二极管(LED)是应用于照明、显示和信号指示等领域的半导体器件。正确判断发光二极管的正负极对其正常工作非常重要。由于LED的极性决定了电流的流向,若接反可能...
2025-03-31 20:30:35
保险丝作为保护电路安全的重要元件,有着着不可替代的作用。作为行业内知名品牌,Kacon 凯昆保险丝很好的性能和的应用赢得了市场的高度认可。本文将详细介绍Kaco...
2020-03-29 02:09:30
1使用55075器件测试齿轮齿感应最好的齿轮由冷轧低碳钢制成,烧结金属齿也可以使用,但必须注意确保材料成分和密度的一致性。图1齿轮齿Littelfuse...
2025-01-15 14:34:00