独立片选拓扑
SPI外设的MOSI、MISO、SCK还是照用不误,但是片选我们不用,设置成通用输出模式,再用其他的GPIO片选从芯片即可。
上代码看看:
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hspi->Instance==SPI1)
{
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
PA15 ------> SPI1_NSS 但是这里不用
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);*/
}
}
初始化SPI外设
#define SPI_CS1 GPIO_PIN_1
#define SPI_CS1_PORT GPIOC
#define SPI_CS2 GPIO_PIN_2
#define SPI_CS2_PORT GPIOC
#define SPI_CS3 GPIO_PIN_3
#define SPI_CS3_PORT GPIOC
static void init_spi(SPI_HandleTypeDef * spi_handle)
{
/* SPI1 parameter configuration*/
spi_handle->Instance = SPI1;
spi_handle->Init.Mode = SPI_MODE_MASTER;
spi_handle->Init.Direction = SPI_DIRECTION_2LINES;
spi_handle->Init.DataSize = SPI_DATASIZE_8BIT;
spi_handle->Init.CLKPolarity = SPI_POLARITY_LOW;
spi_handle->Init.CLKPhase = SPI_PHASE_1EDGE;
spi_handle->Init.NSS = SPI_NSS_HARD_OUTPUT;
spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
spi_handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
spi_handle->Init.TIMode = SPI_TIMODE_DISABLE;
spi_handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spi_handle->Init.CRCPolynomial = 10;
ASSERT (HAL_SPI_Init(spi_handle) != HAL_OK);
GPIO_InitTypeDef GPIO_InitStructure;
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStructure.Pin = SPI_CS1;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(SPI_CS1_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pin = SPI_CS2;
HAL_GPIO_Init(SPI_CS2_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pin = SPI_CS3;
HAL_GPIO_Init(SPI_CS3_PORT, &GPIO_InitStructure);
}
从而原来SPI的收发函数前后加上片选信号即可:
typedef enum
{
SPI_CH_1=0,
SPI_CH_2,
SPI_CH_3,
SPI_CH_LAST,
} SPI_CH;
static HAL_StatusTypeDef SPI_Select(SPI_CH ch)
{
switch (ch)
{
case SPI_CH_1:
HAL_GPIO_WritePin(SPI_CS1_PORT,SPI_CS1,GPIO_PIN_RESET);
break;
case SPI_CH_2:
HAL_GPIO_WritePin(SPI_CS2_PORT,SPI_CS2,GPIO_PIN_RESET);
break;
case SPI_CH_3:
HAL_GPIO_WritePin(SPI_CS3_PORT,SPI_CS3,GPIO_PIN_RESET);
break;
default:
return HAL_ERROR;
}
return HAL_OK;
}
static HAL_StatusTypeDef SPI_DeSelect(SPI_CH ch)
{
switch (ch)
{
case SPI_CH_1:
HAL_GPIO_WritePin(SPI_CS1_PORT,SPI_CS1,GPIO_PIN_SET);
break;
case SPI_CH_2:
HAL_GPIO_WritePin(SPI_CS2_PORT,SPI_CS2,GPIO_PIN_SET);
break;
case SPI_CH_3:
HAL_GPIO_WritePin(SPI_CS3_PORT,SPI_CS3,GPIO_PIN_SET);
break;
default:
return HAL_ERROR;
}
return HAL_OK;
}
HAL_StatusTypeDef SPI_TransmitReceive(SPI_CH ch,
SPI_HandleTypeDef *hspi,
uint8_t *pTxData,
uint8_t *pRxData,
uint16_t Size,
uint32_t Timeout)
{
HAL_StatusTypeDef ret;
if(ch>=SPI_CH_LAST)
return HAL_ERROR;
SPI_Select(ch);
ret = HAL_SPI_TransmitReceive(hspi,pTxData,pRxData,Size,Timeout);
SPI_DeSelect(ch);
return ret;
}
HAL_StatusTypeDef SPI_Transmit(SPI_CH ch,
SPI_HandleTypeDef *hspi,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout)
{
HAL_StatusTypeDef ret;
if(ch>=SPI_CH_LAST)
return HAL_ERROR;
SPI_Select(ch);
ret = HAL_SPI_Transmit(hspi,pData,Size,Timeout);
SPI_DeSelect(ch);
return ret;
}
|