当前位置: 首页 > backend >正文

8-verilog-串口接收与发送模块

verilog-串口接收与发送模块

1.串口接收

module uart_recv_parity(input          sys_clk,          // 系统时钟input          sys_rst_n,        // 系统复位,低电平有效input          uart_rxd,         // UART接收端口output reg     uart_done,        // 接收一帧数据完成标志信号output reg     frame_error,      // 帧错误(停止位不为1)output reg     parity_error,     // 奇偶校验错误output reg [7:0] uart_data       // 接收的数据
);// 参数定义
parameter  CLK_FREQ = 50000000;      // 系统时钟频率
parameter  UART_BPS = 9600;          // 串口波特率
parameter  PARITY   = "ODD";         // 校验类型:"NONE", "ODD", "EVEN"
localparam BPS_CNT  = CLK_FREQ/UART_BPS;  // 每个波特率周期的时钟数
localparam BPS_CNT_HALF = BPS_CNT/2; // 半位周期时钟数// 寄存器定义
reg [1:0]  uart_rxd_sync;           // 同步寄存器
reg [15:0] clk_cnt;                 // 波特率时钟计数器
reg [3:0]  rx_cnt;                  // 接收位计数器
reg        rx_flag;                 // 接收过程标志
reg [7:0]  rxdata;                  // 接收数据寄存器
reg        parity_bit;              // 计算的奇偶校验位
reg        received_parity;         // 接收到的校验位// 检测起始位下降沿
wire start_flag = (uart_rxd_sync == 2'b10); // 同步输入信号,防止亚稳态
always @(posedge sys_clk or negedge sys_rst_n) begin if (!sys_rst_n) uart_rxd_sync <= 2'b11;else uart_rxd_sync <= {uart_rxd_sync[0], uart_rxd};
end// 接收过程控制
always @(posedge sys_clk or negedge sys_rst_n) begin         if (!sys_rst_n)                                  rx_flag <= 1'b0;else if(start_flag)                       // 检测到起始位rx_flag <= 1'b1;                     // 开始接收else if((rx_cnt == 4'd9 && PARITY == "NONE") || (rx_cnt == 4'd10 && PARITY != "NONE"))if(clk_cnt == BPS_CNT_HALF)rx_flag <= 1'b0;                 // 接收完成
end// 波特率时钟计数器和接收位计数器
always @(posedge sys_clk or negedge sys_rst_n) begin         if (!sys_rst_n) begin                             clk_cnt <= 16'd0;                                  rx_cnt  <= 4'd0;end                                                      else if(rx_flag) begin                   // 接收过程中if(clk_cnt < BPS_CNT - 1)clk_cnt <= clk_cnt + 1'b1;else beginclk_cnt <= 16'd0;rx_cnt  <= rx_cnt + 1'b1;endendelse begin                              // 非接收过程clk_cnt <= 16'd0;rx_cnt  <= 4'd0;end
end// 计算奇偶校验位
always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) beginparity_bit <= 1'b0;endelse if (rx_flag && (rx_cnt == 4'd8) && (clk_cnt == BPS_CNT_HALF)) beginif (PARITY == "ODD")parity_bit <= ^rxdata;          // 奇校验else if (PARITY == "EVEN")parity_bit <= ~^rxdata;         // 偶校验end
end// 接收校验位
always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) beginreceived_parity <= 1'b0;endelse if (rx_flag && (rx_cnt == 4'd9) && (clk_cnt == BPS_CNT_HALF) beginreceived_parity <= uart_rxd_sync[1];end
end// 数据位采样
always @(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n)  rxdata <= 8'd0;                                     else if(rx_flag && (clk_cnt == BPS_CNT_HALF)) begincase(rx_cnt)4'd1: rxdata[0] <= uart_rxd_sync[1];4'd2: rxdata[1] <= uart_rxd_sync[1];4'd3: rxdata[2] <= uart_rxd_sync[1];4'd4: rxdata[3] <= uart_rxd_sync[1];4'd5: rxdata[4] <= uart_rxd_sync[1];4'd6: rxdata[5] <= uart_rxd_sync[1];4'd7: rxdata[6] <= uart_rxd_sync[1];4'd8: rxdata[7] <= uart_rxd_sync[1];default: rxdata <= rxdata;endcaseend
end// 输出数据和状态
always @(posedge sys_clk or negedge sys_rst_n) begin        if(!sys_rst_n) beginuart_data   <= 8'd0;                               uart_done   <= 1'b0;frame_error <= 1'b0;parity_error <= 1'b0;endelse if(((rx_cnt == 4'd9) && (PARITY == "NONE")) || ((rx_cnt == 4'd10) && (PARITY != "NONE"))) beginif(clk_cnt == BPS_CNT_HALF) beginuart_data <= rxdata;            // 输出接收数据uart_done <= 1'b1;              // 接收完成信号// 检查停止位(总是第9/10位,取决于是否有校验)if(PARITY == "NONE")frame_error <= ~uart_rxd_sync[1];  // 检查停止位是否为1elseframe_error <= ~uart_rxd_sync[1];  // 检查停止位是否为1// 检查校验位if(PARITY != "NONE")parity_error <= (received_parity != parity_bit);elseparity_error <= 1'b0;endendelse beginuart_done <= 1'b0;               // 完成信号只持续一个周期end    
endendmodule

2.串口发送

在这里插入代码片
http://www.xdnf.cn/news/16880.html

相关文章:

  • docker 可用镜像列表(长期免费)
  • 嵌入式硬件篇---Openmv
  • Java 高频面试考点(下)
  • 【MySQL安全】什么是SQL注入,怎么避免这种攻击:前端防护、后端orm框架、数据库白名单
  • ELECTRICAL靶机
  • SQL157 更新记录(一)
  • Java企业级应用性能优化实战
  • ABAP SQL更新DB小技巧 WITH INDICATORS
  • W3D引擎游戏开发----从入门到精通【10】
  • 第二节 YOLOv5参数
  • 在 macOS 上通过 Docker 部署DM8 (ARM 架构)
  • 团队独立思考的力量
  • 2025-0803学习记录21——地表分类产品的精度验证
  • MySQL存储过程和触发器
  • 【网络安全】日志文件格式
  • 「源力觉醒 创作者计划」_文心大模型4.5系列开源模型, 从一行代码到一个生态:聊聊开源战略那些事儿,顺便扯扯文心大模型 4.5 的使用心得
  • 题解:P4447 [AHOI2018初中组] 分组
  • ospf综合
  • NX947NX955美光固态闪存NX962NX966
  • C++ STL 组件及其关系:从模块化设计到图形化展示
  • [硬件电路-124]:模拟电路 - 信号处理电路 - 测量系统的前端电路详解
  • HTTP数据请求
  • 【密码学】5. 公钥密码
  • 【Linux】多路转接之epoll
  • pytorch简单理解
  • 幂等性介绍和下单接口幂等性保证实现方案
  • python创建一个excel文件
  • realIADD3复现笔记
  • 【BTC】挖矿难度调整
  • AbstractExecutorService:Java并发核心模板解析