FPGA主SPI与STM32从机通信

这篇具有很好参考价值的文章主要介绍了FPGA主SPI与STM32从机通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

概述

FPGA的SPI主机代码

STM32从机

SPI模式配置

SPI参数设置

 SPI的DMA传输配置

STM32从机SPI接收代码


概述

        不说一些SPI原理之类的废话,浪费空间。我使用的硬件环境为STM32F407VET6和DE0-nano,长什么样子如下图。

stm32与fpga的spi通讯,fpga开发,stm32,嵌入式硬件

 使用cubemx配置工程,FPGA使用Quartus软件,时序仿真图如下

stm32与fpga的spi通讯,fpga开发,stm32,嵌入式硬件

FPGA的SPI主机代码

        txd_signal信号为上升沿触发,led0,1,2为调试灯,可去掉。

        一个SCK周期为16个clk周期,我测试时使用50MHz晶振,故SPI时钟为3.125MHz。

        需要改动通信速率可以通过改动cnt1相关值改变。

        时钟相位参考STM32从机配置

//时钟极性高,采样沿上升沿
module SPI_Master(
  clk,        // 系统时钟
  rst,        // 复位,低有效
  txd_flag,   // 高电平表示发送完成处于忙碌状态,低电平表示处于空闲状态
  sck,        // 时钟输出
  cs,         // 片选输出
  mosi,       // 主设备输出信号
  miso,       // 主设备输入信号
  txd_signal, // 发送触发信号,给一个信号发送8bit
  rxd_out,    // 接收的数据
  txd_in,     // 发送的数据
  led0,
  led1,
  led2
);
//调试引脚
output led0,led1,led2;
assign led0=txd_signal;
assign led1=txd_flag;
assign led2=cs;
// 输入信号
input clk, rst, miso, txd_signal;
// 输出信号
output reg mosi, txd_flag;
output wire sck, cs;
output reg [7:0] rxd_out;
input [7:0] txd_in;

// 内部寄存器和变量
reg [2:0] txd_start;
reg [2:0] txd_start_outside;
reg [3:0] cnt;
reg [3:0] cnt1;
reg csr;
assign sck = cnt1[3];
assign cs = csr;

// 任务:根据计数器 cnt1 的值更新时钟状态
task clk_states;
  if (cnt1 == 4'b0000) begin
    cnt1 <= 4'b1111;
    cnt <= cnt + 1'b1;
  end else
    cnt1 <= cnt1 - 1'b1;
endtask

// always 块:根据时钟和复位信号控制发送过程和计数器的更新
always @(posedge clk or negedge rst) begin
  if (!rst) begin
    // 复位所有状态和寄存器
    txd_flag <= 1'b0;
    txd_start <= 3'd1;
    cnt <= 4'd0;
    cnt1 <= 4'b1111;
    csr <= 1'b1;
  end else begin
    if (txd_start == txd_start_outside) begin
      csr <= 1'b0;
      txd_flag <= 1'b1; // txd_flag 信号与 cs 信号相反,电路当处于通信时为高电平,表示忙碌状态
      case (cnt) // 为低电平表示空闲状态
        0: clk_states();//进八次cnt加1,SCK经过一个周期,SCK高电平持续时间为4和CLK
        1: clk_states();
        2: clk_states();
        3: clk_states();
        4: clk_states();
        5: clk_states();
        6: clk_states();
        7: begin
          if (cnt1 == 4'b0000) begin
            cnt1 <= 4'b1111;
            cnt <= 4'd8;
          end else
            cnt1 <= cnt1 - 1'b1;
        end
        8: begin
          // 多加一个状态延长 cs 的低电平时间,给从机足够的时间接收数据
          txd_start <= txd_start + 1'b1;
          cnt <= 4'd0;
        end
      endcase
    end else begin
      csr <= 1'b1;
      txd_flag <= 1'b0;
    end
  end
end

// always 块:外部触发发送脉冲,上升沿触发发送一次
always @(posedge txd_signal or negedge rst) begin
  if (!rst)
    txd_start_outside <= 1'b0;
  else begin
    if (!txd_flag)
      txd_start_outside <= txd_start_outside + 1'b1;
    else;
  end
end

// always 块:sck 上升沿采样数据
reg [7:0] rxd_outr;
reg [2:0] rec_cnt;
always @(posedge sck or negedge rst) begin
  if (!rst) begin
    rxd_out <= 8'h00;
    rec_cnt <= 3'd0;
  end else begin
    case (rec_cnt)
      0: begin
        rxd_outr[7] <= miso;
        rec_cnt <= 3'd1;
      end
      1: begin
        rxd_outr[6] <= miso;
        rec_cnt <= 3'd2;
      end
      2: begin
        rxd_outr[5] <= miso;
        rec_cnt <= 3'd3;
      end
      3: begin
        rxd_outr[4] <= miso;
        rec_cnt <= 3'd4;
      end
      4: begin
        rxd_outr[3] <= miso;
        rec_cnt <= 3'd5;
      end
      5: begin
        rxd_outr[2] <= miso;
        rec_cnt <= 3'd6;
      end
      6: begin
        rxd_outr[1] <= miso;
        rec_cnt <= 3'd7;
      end
      7: begin
        rxd_outr[0] <= miso;
        rxd_out <= {rxd_outr[7:1], miso};
        rec_cnt <= 3'd0;
      end
      default:;
    endcase
  end
end

// always 块:sck 下降沿时发送数据
reg [2:0] send_cnt;
always @(negedge sck or negedge rst) begin
  if (!rst)
    send_cnt <= 3'd0;
  else begin
    case (send_cnt)
      0: begin
        mosi <= txd_in[7];
        send_cnt <= 3'd1;
      end
      1: begin
        mosi <= txd_in[6];
        send_cnt <= 3'd2;
      end
      2: begin
        mosi <= txd_in[5];
        send_cnt <= 3'd3;
      end
      3: begin
        mosi <= txd_in[4];
        send_cnt <= 3'd4;
      end
      4: begin
        mosi <= txd_in[3];
        send_cnt <= 3'd5;
      end
      5: begin
        mosi <= txd_in[2];
        send_cnt <= 3'd6;
      end
      6: begin
        mosi <= txd_in[1];
        send_cnt <= 3'd7;
      end
      7: begin
        mosi <= txd_in[0];
        send_cnt <= 3'd0;
      end
      default:;
    endcase
  end
end

endmodule

STM32从机

SPI模式配置

stm32与fpga的spi通讯,fpga开发,stm32,嵌入式硬件

SPI参数设置

 stm32与fpga的spi通讯,fpga开发,stm32,嵌入式硬件

 SPI的DMA传输配置

stm32与fpga的spi通讯,fpga开发,stm32,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-783767.html

STM32从机SPI接收代码
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	uint8_t data=0;
	HAL_SPI_Receive_DMA(&hspi1,&data,1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		//FPGA RESET
		HAL_GPIO_WritePin(RST_GPIO_Port,RST_Pin,GPIO_PIN_RESET);
		HAL_Delay(10);
		HAL_GPIO_WritePin(RST_GPIO_Port,RST_Pin,GPIO_PIN_SET);
		//等待发送空闲
		while(HAL_GPIO_ReadPin(txd_flag_GPIO_Port,txd_flag_Pin)==GPIO_PIN_SET){
		};
		//延迟便于观察串口输出
		HAL_Delay(2000);
		//上升沿触发FPGA主机发送
		HAL_GPIO_WritePin(txd_signal_GPIO_Port,txd_signal_Pin,GPIO_PIN_SET);
		HAL_Delay(100);
		HAL_GPIO_WritePin(txd_signal_GPIO_Port,txd_signal_Pin,GPIO_PIN_RESET);
		//串口打印data查看数据
		printf("data is %d \r\n",data);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

到了这里,关于FPGA主SPI与STM32从机通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32】BLDC驱动&控制开发笔记 | 07_SPI通信测试 - STM32F407用SPI配置DRV8323驱动芯片

    最近在埋头搞STM32 + 无刷直流电机控制,想实现用自己的STM32F407VGT6芯片板子,外加一块驱动板(目前选用到TI的DRV8302或者DRV8323驱动芯片),搞定电机驱动,最后实现比较好的控制效果。如果不是同一块芯片的同学也不用急着走,大体上都是可借鉴哒~ 本文主要实现使用SPI通信

    2024年02月08日
    浏览(46)
  • STM32——SPI通信

    SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线 四根通信线: SCK(Serial Clock)【CLK或SCL或CK】、 MOSI(Master Output Slave Input)【DO(Data Output)】、 MISO(Master Input Slave Output)【DI(Data Input)】、 SS(Slave Select)【CS或NSS】 同步,全双工 支持总线挂载多设备

    2024年02月11日
    浏览(32)
  • 【STM32】SPI通讯控制ILI9341显示屏

    ILI9341是一款分辨率为 240x320 分辨率 的a- tft液晶显示单片SOC驱动,由720通道源驱动、320通道门驱动、 172800字节GRAM (240RGBx320点位图形显示数据)和电源电路组成。 ILI9341支持并行8-/9-/16-/18位数据总线MCU接口,6-/16-/18位数据总线RGB接口和3 /4线串行外围接口 SPI通讯 。通过窗口地址函

    2024年01月21日
    浏览(41)
  • 【【STM32-SPI通信协议】】

    STM32-SPI通信协议 •SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线 •四根通信线:SCK(Serial Clock)、MOSI(Master Output Slave Input)、MISO(Master Input Slave Output)、SS(Slave Select) •同步,全双工 •支持总线挂载多设备(一主多从) 既然是同步的,我们就会发

    2024年02月12日
    浏览(31)
  • stm32 AD7606 芯片驱动 hal库 spi通讯

             这两天用来个ad7606 的芯片,结果硬件出来个问题,花了不少时间看这个芯片手册,干脆分享一下。         OS0 OS1 OS2         这个三个引脚用于配置芯片的采样频率,只要不设置为111即可正常采样; CONVSTA CONVSTB 这两个引脚用于启动芯片采集转换,默认高电平,

    2024年04月26日
    浏览(33)
  • 【STM32】学习笔记-SPI通信

    SPI通信(Serial Peripheral Interface)是一种同步的串行通信协议,用于在微控制器、传感器、存储器、数字信号处理器等之间进行通信。SPI通信协议需要使用4个线路进行通信:时钟线(SCLK)、主输入/主输出线(MISO)、主输出/主输入线(MOSI)和片选线(SS)。其中,SCLK由主设备提供,用于

    2024年02月09日
    浏览(34)
  • STM32—SPI详解入门(使用SPI通讯读写W25Q128模块)

    目录 一、SPI是什么 二、SPI物理架构 三、SPI工作原理 四、SPI工作模式 五、SPI相关寄存器介绍 六、SPI用到的结构体与函数 1.结构体 2.函数 七、W25Q128芯片 1.W25Q128介绍 2.W25Q128存储架构 3.W25Q128常用指令 4.W25Q128状态寄存器 5.W25Q128常见操作流程 八、实验(使用SPI通讯读写W25Q128模块

    2024年02月14日
    浏览(42)
  • STM32使用SPI协议主从通信

    目录 前言 一、理论部分      SPI简介   SPI特征 SPI物理层 SPI协议层 SPI配置过程 SPI数据发送与接收过程 二、代码部分 主机代码 从机代码 这是一篇学习笔记,记录自己学习SPI通信。方便之后运用的时候回顾。参考《STM32中文参考手册》          SPI 协议是由摩托罗拉公

    2024年02月13日
    浏览(31)
  • STM32硬件SPI通信详解-------附代码

    1.STM32内部集成了 硬件SPI收发电路 ,可以由 硬件自动执行时钟生成 、 数据收发 等功能, 减轻CPU的负担 2.可配置 8位/16位数据帧 、 高位先行/低位先行 3. 时钟频率 : fPCLK / (2, 4, 8, 16, 32, 64, 128, 256) 4.支持 多主机模型 、 主或从操作 5.可精简为 半双工/单工通信 6. 支持DMA 7. 兼

    2024年04月27日
    浏览(36)
  • STM32 HAL库 SPI主从双机通信

    最近因为项目需求,需要在一块板子内实现一个主机和五个从机的通信; 主机平台选用的是STM32F407VGT6,从机平台选用的是STM32F103C8T6;通信总线选用的是SPI总线。在构想是觉得采用SPI进行主从通信会很简单,但在实际开发的过程中,各种坑,通信时而正常时而混乱。不过在不

    2024年01月17日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包