前言
- bsp_lpspi 兼容软件模拟io驱动,32硬件SPI驱动,兼容类比芯片IC驱动。
- 类比半导体为一家模拟及数模混合芯片和解决方案供应商,公司成立于2018年,由一批来自于国际顶尖半导体公司的本土工程师创建。公司总部位于上海,在上海张江、临港、苏州、深圳、西安、北京分别设有研发和技术支持中心。公司专注于信号链、电源管理、MCU/DSP等领域的芯片设计,产品主要面向工业、通讯、医疗、汽车等市场。类比核心使命是为客户提供高品质芯片,为世界科技化和智能化提供最底层的芯片支持。
一、代码

通过修改bsp_lpspi.h,宏定义切换软件硬件SPI.
1.bsp_lpspi.c
代码如下(示例):
#include "bsp_lpspi.h"
#ifdef HardWare_SPI //Begin of hard_spi
SPI_HandleTypeDef SpiHandle;
void Spi_delay(uint32_t count)
{
volatile uint32_t i = 0;
for (i = 0; i < count; ++i)
{
__asm("NOP"); /* 调用nop空指令 */
__asm("NOP"); /* 调用nop空指令 */
__asm("NOP"); /* 调用nop空指令 */
__asm("NOP"); /* 调用nop空指令 */
__asm("NOP"); /* 调用nop空指令 */
}
}
void LPSPI_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* Enable SPI1 clock */
SPIx_CLK_ENABLE();
SPIx_SCK_GPIO_CLK_ENABLE();
SPIx_MISO_GPIO_CLK_ENABLE();
SPIx_MOSI_GPIO_CLK_ENABLE();
SPIx_CS_GPIO_CLK_ENABLE();
/* 初始化GPIO 配置*/
/*##-1- Configure peripheral GPIO ##########################################*/
/* SPI SCK GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_SCK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
//GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
//GPIO_InitStruct.Alternate = SPIx_SCK_AF;
HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
/* SPI MISO GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_MISO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
//GPIO_InitStruct.Alternate = SPIx_MISO_AF;
HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct);
/* SPI MOSI GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_MOSI_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
//GPIO_InitStruct.Alternate = SPIx_MOSI_AF;
HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct);
/* SPI CS GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_CS_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SPIx_CS_GPIO_PORT, &GPIO_InitStruct);
/* 初始化SPI 配置*/
/*##-2- Configure the SPI peripheral #######################################*/
/* Set the SPI parameters */
SpiHandle.Instance = SPIx;
SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
SpiHandle.Init.CLKPhase = SPI_PHASE_2EDGE ;
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SpiHandle.Init.CRCPolynomial = 7;
SpiHandle.Init.NSS = SPI_NSS_SOFT;
SpiHandle.Init.Mode = SPI_MODE_MASTER;
//初始化SPI
HAL_SPI_Init(&SpiHandle);
__HAL_SPI_ENABLE(&SpiHandle);
//默认拉高CS引脚
HAL_GPIO_WritePin(SPIx_CS_GPIO_PORT,SPIx_CS_PIN,GPIO_PIN_SET);
}
void Lpspi_Start(void)
{
HAL_GPIO_WritePin(SPIx_CS_GPIO_PORT,SPIx_CS_PIN,GPIO_PIN_RESET);
}
void Lpspi_Stop(void)
{
HAL_GPIO_WritePin(SPIx_CS_GPIO_PORT,SPIx_CS_PIN,GPIO_PIN_SET);
}
void Lpspi_Write(uint8_t datasize,uint8_t *data)
{
//写数据
HAL_GPIO_WritePin(SPIx_CS_GPIO_PORT,SPIx_CS_PIN,GPIO_PIN_RESET);
HAL_SPI_Transmit(&SpiHandle,data, datasize, 5000);
Spi_delay(30);
HAL_GPIO_WritePin(SPIx_CS_GPIO_PORT,SPIx_CS_PIN,GPIO_PIN_SET);
}
void Lpspi_Read(uint8_t datasize,uint8_t *data,uint8_t *Rxdata)
{
// 读写数据
HAL_GPIO_WritePin(SPIx_CS_GPIO_PORT,SPIx_CS_PIN,GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&SpiHandle,data,Rxdata, datasize, 5000);
Spi_delay(30);
HAL_GPIO_WritePin(SPIx_CS_GPIO_PORT,SPIx_CS_PIN,GPIO_PIN_SET);
}
#endif //end of hard_spi
#ifdef Soft_SPI //begin of soft_spi
SPI_HandleTypeDef SpiHandle;
void Spi_delay(uint32_t count)
{
volatile uint32_t i = 0;
for (i = 0; i < count; ++i)
{
__asm("NOP"); /* 调用nop空指令 */
__asm("NOP"); /* 调用nop空指令 */
__asm("NOP"); /* 调用nop空指令 */
__asm("NOP"); /* 调用nop空指令 */
__asm("NOP"); /* 调用nop空指令 */
}
}
void LPSPI_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* Enable SPI1 clock */
//SPIx_CLK_ENABLE();
SPIx_SCK_GPIO_CLK_ENABLE();
SPIx_MISO_GPIO_CLK_ENABLE();
SPIx_MOSI_GPIO_CLK_ENABLE();
SPIx_CS_GPIO_CLK_ENABLE();
/* 初始化GPIO 配置*/
/*##-1- Configure peripheral GPIO ##########################################*/
/* SPI SCK GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_SCK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
//GPIO_InitStruct.Alternate = SPIx_SCK_AF;
HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
/* SPI MISO GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_MISO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
//GPIO_InitStruct.Alternate = SPIx_MISO_AF;
HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct);
/* SPI MOSI GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_MOSI_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//GPIO_InitStruct.Alternate = SPIx_MOSI_AF;
HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct);
/* SPI CS GPIO pin configuration */
GPIO_InitStruct.Pin = SPIx_CS_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SPIx_CS_GPIO_PORT, &GPIO_InitStruct);
//默认拉高CS引脚
HAL_GPIO_WritePin(SPIx_CS_GPIO_PORT,SPIx_CS_PIN,GPIO_PIN_SET);
//SCLK空闲拉低
HAL_GPIO_WritePin(SPIx_SCK_GPIO_PORT,SPIx_SCK_PIN,GPIO_PIN_RESET);
//SCLK空闲拉高
//HAL_GPIO_WritePin(SPIx_SCK_GPIO_PORT,SPIx_SCK_PIN,GPIO_PIN_SET);
}
void Lpspi_Start(void)
{
HAL_GPIO_WritePin(SPIx_CS_GPIO_PORT,SPIx_CS_PIN,GPIO_PIN_RESET);
}
void Lpspi_Stop(void)
{
HAL_GPIO_WritePin(SPIx_CS_GPIO_PORT,SPIx_CS_PIN,GPIO_PIN_SET);
}
void SCLK_H(void)
{
HAL_GPIO_WritePin(SPIx_SCK_GPIO_PORT,SPIx_SCK_PIN,GPIO_PIN_SET);
}
void SCLK_L(void)
{
HAL_GPIO_WritePin(SPIx_SCK_GPIO_PORT,SPIx_SCK_PIN,GPIO_PIN_RESET);
}
void SPI_Transmit_Data_mode0(uint8_t *Data ,uint8_t Size) //SCLK low first edge
{
uint8_t i,a=0,data=0;
for(a=0;a<Size;a++)
{
data = Data[a];
for(i = 0;i < 8;i++)
{
SCLK_L();
if(data&(0x80))//data bit = 1
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_SET);//MOSI SET 1
}
else
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_RESET);//MOSI SET 0
}
SCLK_H();
data <<=1;
}
}
}
void SPI_Receive_Data_mode0( uint8_t *Data,uint8_t *Rxdata ,uint8_t Size) //SCLK low first edge
{
uint8_t i,a,data,rxdata;
for(a=0;a<Size;a++)
{
data = Data[a];
Rxdata[a]=0;
for(i = 0;i < 8;i++)
{
SCLK_L();
if(data&(0x80))//data bit = 1
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_SET);//MOSI SET 1
}
else
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_RESET);//MOSI SET 0
}
if(HAL_GPIO_ReadPin(SPIx_MISO_GPIO_PORT,SPIx_MISO_PIN)==1)
{
Rxdata[a]|=(0x80 >>i);
}
SCLK_H();
data <<=1;
}
}
}
void SPI_Transmit_Data_mode1(uint8_t *Data ,uint8_t Size) //SCLK low second edge
{
uint8_t i,a=0,data=0;
for(a=0;a<Size;a++)
{
data = Data[a];
for(i = 0;i < 8;i++)
{
SCLK_H();
if(data&(0x80))//data bit = 1
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_SET);//MOSI SET 1
}
else
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_RESET);//MOSI SET 0
}
data <<=1;
SCLK_L();
}
}
}
void SPI_Receive_Data_mode1( uint8_t *Data,uint8_t *Rxdata ,uint8_t Size) //SCLK low second edge
{
uint8_t i,a,data,rxdata;
for(a=0;a<Size;a++)
{
data = Data[a];
Rxdata[a]=0;
for(i = 0;i < 8;i++)
{
SCLK_H();
if(data&(0x80))//data bit = 1
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_SET);//MOSI SET 1
}
else
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_RESET);//MOSI SET 0
}
data <<=1;
SCLK_L();
if(HAL_GPIO_ReadPin(SPIx_MISO_GPIO_PORT,SPIx_MISO_PIN)==1)
{
Rxdata[a]|=(0x80 >>i);
}
}
}
}
void SPI_Transmit_Data_mode2(uint8_t *Data ,uint8_t Size) //SCLK high first edge
{
uint8_t i,a=0,data=0;
for(a=0;a<Size;a++)
{
data = Data[a];
for(i = 0;i < 8;i++)
{
SCLK_H();
//Spi_delay(1);
if(data&(0x80))//data bit = 1
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_SET);//MOSI SET 1
}
else
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_RESET);//MOSI SET 0
}
//Spi_delay(1);
SCLK_L();
//Spi_delay(1);
data <<=1;
SCLK_H();
//Spi_delay(1);
}
}
}
void SPI_Receive_Data_mode2( uint8_t *Data,uint8_t *Rxdata ,uint8_t Size) //SCLK low first edge
{
uint8_t i,a,data,rxdata;
for(a=0;a<Size;a++)
{
data = Data[a];
Rxdata[a]=0;
for(i = 0;i < 8;i++)
{
SCLK_H();
//Spi_delay(1);
if(data&(0x80))//data bit = 1
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_SET);//MOSI SET 1
}
else
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_RESET);//MOSI SET 0
}
SCLK_L();
if(HAL_GPIO_ReadPin(SPIx_MISO_GPIO_PORT,SPIx_MISO_PIN)==1)
{
Rxdata[a]|=(0x80 >>i);
}
data <<=1;
SCLK_H();
}
}
}
void SPI_Transmit_Data_mode3(uint8_t *Data ,uint8_t Size) //SCLK high second edge
{
uint8_t i,a=0,data=0;
for(a=0;a<Size;a++)
{
data = Data[a];
for(i = 0;i < 8;i++)
{
SCLK_L();
if(data&(0x80))//data bit = 1
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_SET);//MOSI SET 1
}
else
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_RESET);//MOSI SET 0
}
data <<=1;
SCLK_H();
}
}
}
void SPI_Receive_Data_mode3( uint8_t *Data,uint8_t *Rxdata ,uint8_t Size) //SCLK low second edge
{
uint8_t i,a,data,rxdata;
for(a=0;a<Size;a++)
{
data = Data[a];
Rxdata[a]=0;
for(i = 0;i < 8;i++)
{
SCLK_L();
if(data&(0x80))//data bit = 1
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_SET);//MOSI SET 1
}
else
{
HAL_GPIO_WritePin(SPIx_MOSI_GPIO_PORT,SPIx_MOSI_PIN,GPIO_PIN_RESET);//MOSI SET 0
}
data <<=1;
SCLK_H();
if(HAL_GPIO_ReadPin(SPIx_MISO_GPIO_PORT,SPIx_MISO_PIN)==1)
{
Rxdata[a]|=(0x80 >>i);
}
}
}
}
void Lpspi_Write(uint8_t datasize,uint8_t *data)
{
//写数据
Lpspi_Start();
SPI_Transmit_Data_mode1(data,datasize);
Spi_delay(30);
Lpspi_Stop();
}
void Lpspi_Read(uint8_t datasize,uint8_t *data,uint8_t *Rxdata)
{
// 读写数据
Lpspi_Start();
SPI_Receive_Data_mode1( data,Rxdata ,datasize);
Spi_delay(30);
Lpspi_Stop();
}
#endif //end of soft_spi
2.bsp_lpspi.h
代码如下(示例):
/*
analogysemi
xutong 2023/10/19
*/
#ifndef __BSP_LPSPI_H
#define __BSP_LPSPI_H
//#include "stm32h7xx_hal.h"
//#include "stm32g0xx_hal.h"
#include "stm32f1xx.h"
//#define HardWare_SPI
#define Soft_SPI
#define SPIx SPI1
#define SPIx_CLK_ENABLE() __HAL_RCC_SPI1_CLK_ENABLE()
#define SPIx_SCK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define SPIx_MISO_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define SPIx_MOSI_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define SPIx_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
/* Definition for SPIx Pins */
#define SPIx_SCK_PIN GPIO_PIN_5
#define SPIx_SCK_GPIO_PORT GPIOA
#define SPIx_SCK_AF GPIO_AF5_SPI1
#define SPIx_MISO_PIN GPIO_PIN_6
#define SPIx_MISO_GPIO_PORT GPIOA
#define SPIx_MISO_AF GPIO_AF5_SPI1
#define SPIx_MOSI_PIN GPIO_PIN_7
#define SPIx_MOSI_GPIO_PORT GPIOA
#define SPIx_MOSI_AF GPIO_AF5_SPI1
#define SPIx_CS_PIN GPIO_PIN_4
#define SPIx_CS_GPIO_PORT GPIOA
void Spi_delay(uint32_t count);
void LPSPI_Init(void);
void Lpspi_Start(void);
void Lpspi_Stop(void);
void Lpspi_Write(uint8_t datasize,uint8_t *data);
void Lpspi_Read(uint8_t datasize,uint8_t *data,uint8_t *Rxdata);
void SCLK_H(void);
void SCLK_L(void);
void SPI_Receive_Data( uint8_t *Data,uint8_t *Rxdata ,uint8_t Size);
void SPI_Transmit_Data(uint8_t *Data ,uint8_t Size);
#endif /* __BSP_LPSPI_H */
总结
类比芯片 bsp_lpspi 兼容 软件控制io驱动,硬件驱动,通过修改头文件宏定义切换硬件软件驱动
BSP_LPSPI:软件与硬件SPI驱动切换及类比芯片接口实现,
3068





