RobotHardware-UESTC/Hardware/银星机器人底盘/PiRobot-YH_Firmware v1.1/STM32/BSPLIB/spi.c

133 lines
4.5 KiB
C

#ifdef __cplusplus
extern "C"
{
#endif
#include "spi.h"
#include "nvic.h"
#define GPIO_SPI1 GPIOA
#define RCC_SPI1 RCC_APB2Periph_GPIOA
#define SPI1_NSS GPIO_Pin_4
#define SPI1_SCK GPIO_Pin_5
#define SPI1_MISO GPIO_Pin_6
#define SPI1_MOSI GPIO_Pin_7
#define GPIO_SPI2 GPIOB
#define RCC_SPI2 RCC_APB2Periph_GPIOB
#define SPI2_NSS GPIO_Pin_12
#define SPI2_SCK GPIO_Pin_13
#define SPI2_MISO GPIO_Pin_14
#define SPI2_MOSI GPIO_Pin_15
void PB_SPI_Init(uint8_t SPI_Channel, unsigned char GPIO_AF) // SPI interface initialization, input parameter SPI1 SPI2
{
SPI_TypeDef *SPIx;
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure; // initialize SPI structure
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI设置为两线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // config SPI working on master mode
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI发送接收为8位数据帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // 串行时钟在不操作时,时钟为低电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第一个时钟沿开始采集数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // NSS有软件(使用SSI为)管理
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // SPI波特率预分频值为8
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // data start transmiss at MSB
SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式
if (SPI_Channel == 1)
{
SPIx = SPI1;
}
else if (SPI_Channel == 2)
{
SPIx = SPI2;
}
else if (SPI_Channel == 3)
{
SPIx = SPI3;
}
else
{
return;
}
if (SPIx == SPI1)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
if (GPIO_AF == 0)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Multiplexing push-pull output
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_SPI1, &GPIO_InitStructure);
GPIO_SetBits(GPIO_SPI1, SPI1_MISO | SPI1_MOSI | SPI1_SCK);
}
else if (GPIO_AF == 1)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SPI1, ENABLE); // Pin Multiplexing to spi1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Multiplexing push-pull output
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_SPI1, &GPIO_InitStructure);
GPIO_SetBits(GPIO_SPI1, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5);
}
}
else if (SPIx == SPI2)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
if (GPIO_AF == 0)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = SPI2_MISO | SPI2_MOSI | SPI2_SCK;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Multiplexing push-pull output
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_SPI2, &GPIO_InitStructure);
GPIO_SetBits(GPIO_SPI2, SPI2_MISO | SPI2_MOSI | SPI2_SCK);
}
else if (GPIO_AF == 1)
{
}
}
SPI_Init(SPIx, &SPI_InitStructure);
SPI_Cmd(SPIx, ENABLE);
PB_SPI_ReadWriteByte(SPI_Channel, 0xff); // start transmission
}
uint8_t PB_SPI_ReadWriteByte(uint8_t SPI_Channel, uint8_t TxData)
{
SPI_TypeDef *SPIx;
if (SPI_Channel == 1)
{
SPIx = SPI1;
}
else if (SPI_Channel == 2)
{
SPIx = SPI2;
}
else if (SPI_Channel == 3)
{
SPIx = SPI3;
}
else
{
return 0;
}
while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)
; // flag of send cache is not reset
SPI_I2S_SendData(SPIx, TxData); // send data
while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET)
; // flag of receivecache is not reset
return SPI_I2S_ReceiveData(SPIx); // receive data
}
#ifdef __cplusplus
}
#endif