基于SPI实现stm32与fpga通信(三)

使用stm32与fpga之间的spi通信,stm32通过fpga控制DAC输出模拟电压,使用三线制。

使用FPGA驱动MS5541,采用3线制,输出时钟(20MHz),片选信号,输出信号,主机端时钟为100MHz,将时钟5分频,然后设置片选信号与并行转串行输出信号在20MHz时钟上升沿输出

inputclk
inputrst

input

start
input

i16_dac_data

output

o_dac_sclk

output

o_dac_cs

output

o_dac_MOSI

module dac_core(
    input				clk,	                                 
    input				rst,	                          
    input				start,
	input	[15:0]		i16_dac_data,	                  
    
	output  wire       	o_dac_sclk,	                       
	output  reg      	o_dac_cs,		           
    output  reg      	o_dac_mosi	           
    );	

reg	                    [5:0]	            tri_cnt;
reg                     [4:0] 	            data_count;
reg                     [15:0]	            i16_dac_data_reg;
wire                                        sclk_posedge;
reg                                         o_dac_sclk_buf;

/**************************************************************************
                            100MHz 5分频
**************************************************************************/
reg		[3:0]	state1;
reg		[3:0]	state2;

always@(posedge clk)
    begin
        if(rst)
            begin
            state1 <= 4'b0000;
            end
        else
            begin
                case(state1)
                    4'b0000: state1 <= 4'b0010;
                    4'b0010: state1 <= 4'b0110;
                    4'b0110: state1 <= 4'b0001;
                    4'b0001: state1 <= 4'b0011;
                    4'b0011: state1 <= 4'b0000;
                    default: state1 <= 4'b0000;
                endcase
            end
    end

always@(negedge clk)
    begin
        if(rst)
            begin
            state2 <= 4'b0 ;
            end
        else
            begin
                case(state2)
                    4'b0000: state2 <= 4'b0010;
                    4'b0010: state2 <= 4'b0110;
                    4'b0110: state2 <= 4'b0001;
                    4'b0001: state2 <= 4'b0011;
                    4'b0011: state2 <= 4'b0000;
                    default: state2 <= 4'b0000;
                endcase
            end
    end
 
assign o_dac_sclk = state1[0] | state2[0];
/******************************************************************************
                                输出时钟边沿   
******************************************************************************/
always@(posedge clk) begin
    if(rst) begin
        o_dac_sclk_buf <= 1'b0;
    end
    else begin
        o_dac_sclk_buf <= o_dac_sclk;
    end
end

assign sclk_posedge = (o_dac_sclk_buf == 1'b0 && o_dac_sclk == 1'b1);
/**************************************************************************
                                 状态转移  
**************************************************************************/  
reg                     [2:0]                       cnt;   
reg                     [2:0]                       state_cur;
reg                     [2:0]                       state_nex;
parameter                                           SM01  =  3'b001,  
                                                    SM02  =  3'b010,  
                                                    SM03  =  3'b100;
always@(posedge clk) begin
    if(rst) begin
        cnt <= 2'd0;
    end
    else begin
        if((state_cur == 3'd0 && cnt <3'd3)) begin
                cnt <= cnt + 1'b1;
        end
        else begin
            cnt <= 3'd0;
        end
    end
end
always@(*) begin
    if(rst) begin
        state_cur       <= 3'd0;
    end
    else begin
        state_cur       <= state_nex;
    end
end
always @(posedge clk) begin         
	if (rst) begin                                 
		o_dac_cs 		<= 1'b1;
		o_dac_mosi		<= 1'b0;
		data_count	    <= 4'd0;
		i16_dac_data_reg<= i16_dac_data;
        state_nex       <= 3'b0;
		tri_done 	    <= 1'b0;
    end
    else begin
        case(state_cur)
            SM01: begin
                o_dac_cs 	        <= 1'b1;
                o_dac_mosi	        <= 1'b0;
                tri_done            <= 1'b0;			
                if(cnt == 3'd3) begin
                    state_nex       <= SM02;
                    i16_dac_data_reg<= i16_dac_data;
                end
            end
            SM02: begin
                tri_done <= 1'b1;
                if (start) begin
                    if(o_dac_cs == 1'b1) begin
                        o_dac_cs 			        <= 1'b0;
                        data_count		            <= 4'd0;
                        o_dac_mosi 	 	            <= i16_dac_data_reg[15];
                        i16_dac_data_reg 	        <= i16_dac_data_reg << 1;
                    end
                    else begin
                        if(sclk_posedge == 1'b1)begin
                            if (data_count < 4'd15) begin
                                o_dac_mosi 	        <= i16_dac_data_reg[15];
                                i16_dac_data_reg    <= i16_dac_data_reg << 1;
                                data_count 	        <= data_count + 4'd1;
                            end
                            else begin
                                data_count <= 2'd0;
                                o_dac_mosi	        <= 1'b0;
                                state_nex	        <= SM03;
                                o_dac_cs 	        <= 1'b1;
                            end
                        end
                        else begin
                                o_dac_cs 			<= o_dac_cs;
                                data_count		    <= data_count;
                                o_dac_mosi 	 	    <= o_dac_mosi;
                                i16_dac_data_reg 	<= i16_dac_data_reg;
                        end
                    end
                end
            end
            SM03: begin
                state_nex	<= SM01;
            end
        endcase
    end
end
endmodule	
	

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
FPGA(现场可编程门阵列)和STM32是两种不同的芯片。FPGA是一种可编程逻辑器件,它可以按照用户需求重新配置其逻辑电路,适用于复杂的数字电路设计。而STM32是一种微控制器,它包含了一个处理器核心以及丰富的外设,适用于嵌入式系统设计。 SPI(串行外设接口)是一种常用的串行通信协议,可以用于连接多个设备,实现设备之间的数据传输。FPGASTM32都支持SPI通信,可以通过相应的硬件接口和软件配置实现。 在使用FPGA实现SPI通信时,我们可以通过编写Verilog或VHDL代码来定义FPGA中的SPI接口,配置FPGA的引脚和时钟,并实现发送和接收数据的逻辑。FPGA可以使用其可编程逻辑电路来处理SPI通信协议的各个部分,例如时序、数据格式和校验等。通过适当的配置和连接,我们可以将FPGA与其他SPI设备(如传感器、存储器或其他嵌入式设备)进行通信。 而在STM32实现SPI通信,我们可以使用STM32的内置SPI外设来实现。首先,我们需要配置SPI外设的相关寄存器,包括时钟速率、数据格式和模式等。然后,使用STM32的GPIO外设来配置相关引脚,使其与SPI外设连接。最后,通过编写适当的软件代码,实现SPI数据的发送和接收。这些代码可以使用STM32的相关库函数或直接操作寄存器来实现。通过配置和连接,我们可以将STM32与其他SPI设备进行通信实现数据的传输和交互。 无论是通过FPGA还是STM32实现SPI通信,我们都需要仔细了解SPI协议的要求和特性,充分利用相应的硬件资源和软件工具,以确保通信的准确性和可靠性。同时,还要根据具体的应用需求和系统设计,选择合适的芯片和外设,进行相应的配置和编程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值