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

FPGA即插即用Verilog驱动系列——SPI发送模块

实现功能:

按字节以spi模式3发送数据,如果要stm32接收,请在cubemx中将对应的spi接口设置为模式3,详情见代码开头注释

// spi_byte_master.v
// 经过优化的SPI主设备模块,每次使能发送一个字节。
// 它实现了SPI模式3 (CPOL=1, CPHA=1),即时钟空闲为高电平,在第二个边沿(上升沿)采样数据。module spi_byte_master(input              clk,        // SPI 工作时钟 (例如 10MHz)input              rst_n,      // 异步复位,低有效input              ena_mo,     // 模块使能,一个高脉冲触发一次字节传输input      [7:0]   spi_tdata,  // 要发送的8位数据input              spi_miso,   // SPI MISO 信号output reg         spi_mosi,   // SPI MOSI 信号output reg         spi_sck,    // SPI SCK 信号output reg         spi_nss,    // SPI 片选信号output reg [7:0]   spi_rdata,  // 接收到的8位数据output             tr_done     // 一字节传输完成信号
);// 状态机状态定义localparam S_IDLE  = 2'b00; // 等待使能localparam S_TX_L  = 2'b01; // SCK 低电平,改变数据localparam S_TX_H  = 2'b10; // SCK 高电平,采样数据localparam S_DONE  = 2'b11; // 传输完成// 状态机寄存器reg [1:0] state, next_state;// 位计数器reg [3:0] bit_cnt;// 用于锁存待发送数据的寄存器reg [7:0] tdata_reg;// FSM - 状态转移逻辑 (组合逻辑)always @(*) beginnext_state = state; // 默认保持当前状态case (state)S_IDLE: beginif (ena_mo)next_state = S_TX_L;endS_TX_L: beginnext_state = S_TX_H;endS_TX_H: begin// 发送完8位后进入完成状态if (bit_cnt == 4'd7)next_state = S_DONE;elsenext_state = S_TX_L;endS_DONE: begin// 完成后立即返回IDLE,等待下一次触发next_state = S_IDLE;enddefault: next_state = S_IDLE;endcaseend// FSM - 状态输出和数据处理逻辑 (时序逻辑)always @(posedge clk or negedge rst_n) beginif (!rst_n) beginstate <= S_IDLE;bit_cnt <= 4'd0;spi_sck <= 1'b1;    // SPI模式3: 空闲时SCK为高spi_mosi <= 1'b0;spi_nss <= 1'b1;    // 片选默认无效spi_rdata <= 8'd0;tdata_reg <= 8'd0;end else beginstate <= next_state;// 根据状态执行操作case (state)S_IDLE: beginspi_nss <= 1'b1; // 在IDLE状态,取消片选if (ena_mo) beginspi_nss <= 1'b0; // 使能,立即拉低片选,选中从设备bit_cnt <= 4'd0; // 准备发送第一位tdata_reg <= spi_tdata; // 锁存待发送数据endendS_TX_L: begin// 在SCK下降沿改变数据 (CPHA=1)spi_mosi <= tdata_reg[7 - bit_cnt];spi_sck <= 1'b0;endS_TX_H: beginspi_sck <= 1'b1;// 在SCK上升沿采样数据 (CPHA=1)spi_rdata[7 - bit_cnt] <= spi_miso;bit_cnt <= bit_cnt + 1;endS_DONE: begin// 传输完成,为下一次传输做准备bit_cnt <= 4'd0;// nss 信号将会在下一个周期的 IDLE 状态被拉高endendcaseendend// 完成信号,在S_DONE状态时拉高一个时钟周期assign tr_done = (state == S_DONE);endmodule

http://www.dtcms.com/a/327719.html

相关文章:

  • AV、IPS、WAF对比
  • 云手机网速和本机网速的关系
  • 解锁 Appium Inspector:移动端 UI 自动化定位的利器
  • 秋招笔记-8.12
  • STM32_bug总结(TIM定时中断进不去和只进1次)
  • 【Python 爬虫】Playwright 多浏览器支持(Chromium/Firefox/WebKit)
  • AI入门学习--AI模型评测
  • kali linux 2025.2安装WPS并设置无报错的详细步骤
  • 云计算概述
  • 卫生间装修防水怎么做合适?
  • 外卖:重构餐饮的线上服务密码
  • 串口通信“第二次总超时”的复盘
  • XC7A15T-1FTG256C Xilinx AMD Artix-7 FPGA
  • 后端找数据库
  • nvm install 14.21.3 时npm 无法下载和识别
  • 项目实例-页面
  • 股票智能体系统的设计与开发
  • VisualSVN Server 4.2.1 安装教程 - 64位下载与配置步骤详解
  • 【Docker项目实战】使用Docker部署Vikunja任务管理工具
  • 【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day2
  • 嵌入式 - Linux软件编程:文件IO
  • 零售业CRM实战:如何打通线上线下客户数据?
  • Ansible 基本使用
  • UE官方文档学习 C++ TAarry 查询(三)Contain,Find函数的使用
  • Redis--day4--实战-黑马点评--搭建环境
  • WPS JS宏 通用方法整理汇总 实时更新
  • 【Vue 3 响应式系统深度解析:reactive vs ref 全面对比】
  • MySQL(下)
  • C语言入门完结篇_结构体、枚举、时间函数的、变量类型(C语言划分内存各个区块的方法)、文件操作
  • MyBatis 缓存与 Spring 事务相关笔记