FPGA与STM32 模拟32位SPI通信(一)

1)quartus ii编译成功后不产生.pof文件(用于AS模式的下载);

 

在assignments >>device>>device and pin option>>configuration >>勾上Use Configuration device,配置芯片(我的是epcs4)。 选择configuration scheme为Active Serial

即可

2)STM32RCT6代码源码自https://blog.csdn.net/weixin_40779546/article/details/81772857

spi.h

#ifndef __SPI_H
#define __SPI_H
#include "stm32l0xx.h"

#ifdef  SPI_GLOBALS
#define SPI_EXT  
#else
#define SPI_EXT  extern
#endif

#define M_CS_H     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET)   
#define M_CS_L     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET)
#define S_CS_H     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)   
#define S_CS_L     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)
#define SCLK_H     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET)
#define SCLK_L     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET)
#define MOSI_H     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET)  
#define MOSI_L     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET)
#define MISO       HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)

SPI_EXT uint32_t spi_send_byte32(uint32_t data);
SPI_EXT uint32_t spi_send_bytes32(uint32_t *buf,uint16_t len);
SPI_EXT uint32_t spi_read_bytes32(uint32_t *buf,uint16_t len);
#endif

 

spi.c

/****************************************Copyright (c)**************************************************
**                                                      他乡&学子
**                                      
**
**                                 https://mp.csdn.net/postedit/81772857
**
**--------------文件信息--------------------------------------------------------------------------------
**文件名    : spi.c
**创 建人   : 他乡&学子
**创建日期: 2017年6月15日
**描 述       : STM32平台gpio模拟SPI通信实现
**                     
********************************************************************************************************/

#define SPI_GLOBALS
#include "string.h"
#include "spi.h"


/*******************************************************************************
* 函数名称:  uint32_t spi_send_byte32(uint32_t data)
* 函数功能:  发送一个32位字
* 函数说明:  gpio模拟spi
* 输入参数:  data 待发送字
* 输出参数:  
* 返回值    :  接收一个32位字
*******************************************************************************/
uint32_t spi_send_byte32(uint32_t data)  
{  
    uint8_t i = 0;  
    uint32_t temp=0x00000000;
 
    for(i=32;i>0;i--){  
        if(data&0x80000000){ //if((data&0x80000000) == 0x80000000){
            GPIOA->BSRR = GPIO_PIN_6;//MOSI_H;//写1
        }else{
            GPIOA->BRR = GPIO_PIN_6;//MOSI_L;//写0
        }
        data<<=1;//高位在前
        GPIOA->BSRR = GPIO_PIN_5;//SCLK_H;//sck高
        temp<<=1;
        if(MISO ==1){
            temp++;//读到1
        }
        GPIOA->BRR = GPIO_PIN_5;//SCLK_L;//sck低
    }  
    return temp;  
}
/*******************************************************************************
* 函数名称:  uint32_t spi_send_bytes32(uint32_t *buf,uint16_t len)
* 函数功能:  发送多个32位字
* 函数说明:  gpio模拟spi
* 输入参数:  
* 输出参数:  
* 返回值    :  
*******************************************************************************/
uint32_t spi_send_bytes32(uint32_t *buf,uint16_t len)
{
    uint16_t i;
    
    for(i=0;i<len;i++){
        spi_send_byte32(buf[i]);
    }
    
    return 0;
}
/*******************************************************************************
* 函数名称:  uint32_t spi_read_byte32(void)
* 函数功能:  读一个32位字
* 函数说明:  gpio模拟spi
* 输入参数:  
* 输出参数:  
* 返回值    :  
*******************************************************************************/
uint32_t spi_read_byte32(void)
{
  return spi_send_byte32(0);
}
/*******************************************************************************
* 函数名称:  uint32_t spi_read_bytes32(void)
* 函数功能:  读多个32位字
* 函数说明:  gpio模拟spi
* 输入参数:  
* 输出参数:  
* 返回值  :  
*******************************************************************************/
uint32_t spi_read_bytes32(uint32_t *buf,uint16_t len)
{
    uint16_t i;
    
    for(i=0;i<len;i++){
        buf[i] = spi_read_byte32();
    }
    
    return 0;
}
1)宏定义解决GPIO_PIN_5,6,7等名字差别问题

#define GPIO_PIN_3 GPIO_Pin_3
#define GPIO_PIN_4 GPIO_Pin_4
#define GPIO_PIN_5 GPIO_Pin_5
#define GPIO_PIN_6 GPIO_Pin_6
#define GPIO_PIN_7 GPIO_Pin_7
#define HAL_GPIO_ReadPin GPIO_ReadInputDataBit
#define HAL_GPIO_WritePin GPIO_WriteBit
#define GPIO_PIN_SET Bit_SET
#define GPIO_PIN_RESET Bit_RESET

3)

需要在主函数初始化PA5,6,7引脚(CS视情况初始化)

        /*定义一个GPIO_InitTypeDef类型的结构体*/
        GPIO_InitTypeDef GPIO_InitStructure;
        /*开启LED相关的GPIO外设时钟*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
            /*设置引脚模式为通用推挽输出*/
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
        /*设置引脚速率为50MHz */   
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

4)SPI发送单个u32时产生SCK不理想,加入2ms延时

uint32_t spi_send_byte32(uint32_t data)  
{  
    uint8_t i = 0;  
    uint32_t temp=0x00000000;
 
    for(i=32;i>0;i--){  
        if(data&0x80000000){ //if((data&0x80000000) == 0x80000000){
            GPIOA->BSRR = GPIO_PIN_6;//MOSI_H;//写1
        }else{
            GPIOA->BRR = GPIO_PIN_6;//MOSI_L;//写0
        }
        data<<=1;//高位在前
        GPIOA->BSRR = GPIO_PIN_5;//SCLK_H;//sck高
        temp<<=1;
        if(MISO ==1){
            temp++;//读到1
        }
                delay_ms(2);
        GPIOA->BRR = GPIO_PIN_5;//SCLK_L;//sck低
                delay_ms(2);
    }  
    return temp;  
}

5)波形基本正确,但单片机读不到,待解决。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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协议的要求和特性,充分利用相应的硬件资源和软件工具,以确保通信的准确性和可靠性。同时,还要根据具体的应用需求和系统设计,选择合适的芯片和外设,进行相应的配置和编程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值