实现功能:
按字节以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 @(*) begin
next_state = state; // 默认保持当前状态
case (state)
S_IDLE: begin
if (ena_mo)
next_state = S_TX_L;
end
S_TX_L: begin
next_state = S_TX_H;
end
S_TX_H: begin
// 发送完8位后进入完成状态
if (bit_cnt == 4'd7)
next_state = S_DONE;
else
next_state = S_TX_L;
end
S_DONE: begin
// 完成后立即返回IDLE,等待下一次触发
next_state = S_IDLE;
end
default: next_state = S_IDLE;
endcase
end
// FSM - 状态输出和数据处理逻辑 (时序逻辑)
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= 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 begin
state <= next_state;
// 根据状态执行操作
case (state)
S_IDLE: begin
spi_nss <= 1'b1; // 在IDLE状态,取消片选
if (ena_mo) begin
spi_nss <= 1'b0; // 使能,立即拉低片选,选中从设备
bit_cnt <= 4'd0; // 准备发送第一位
tdata_reg <= spi_tdata; // 锁存待发送数据
end
end
S_TX_L: begin
// 在SCK下降沿改变数据 (CPHA=1)
spi_mosi <= tdata_reg[7 - bit_cnt];
spi_sck <= 1'b0;
end
S_TX_H: begin
spi_sck <= 1'b1;
// 在SCK上升沿采样数据 (CPHA=1)
spi_rdata[7 - bit_cnt] <= spi_miso;
bit_cnt <= bit_cnt + 1;
end
S_DONE: begin
// 传输完成,为下一次传输做准备
bit_cnt <= 4'd0;
// nss 信号将会在下一个周期的 IDLE 状态被拉高
end
endcase
end
end
// 完成信号,在S_DONE状态时拉高一个时钟周期
assign tr_done = (state == S_DONE);
endmodule