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)波形基本正确,但单片机读不到,待解决。