内容:如题
1、硬件连接
主机和从机之间:MOSI--MOSI;MISO--MISO;SCK--SCK;NSS(主机可以随便GPIO,后面讲到)--NSS
2、SPI配置问题:
利用STMCube MX软件配置。
软件下载地址:https://www.st.com/zh/development-tools/stm32cubemx.html
(1)主机:这里选取的是SPI2
因为主机端是主导整个通信,不论是读数据还是写数据,都是主机先引导。所以主机端配置也是主导地位,时钟的配置,数据长度,高位先发送还是低位先发送,都是主机这边确定。关键点在于NSS引脚的问题,主机端选择从器件软件管理模式这样内部的SSI值就直接赋值给了NSS内部引脚(这个可以去看看一些坛友的解读),也就是在配置的时候Hardware NSS Signal 选择Disable。所以这个NSS引脚就可以当成普通的IO去使用了,那如果是这样的话,在从机的NSS引脚,随便接一根GPIO就可以了。只要将该引脚设置为output即可。
(2)从机:这里选取的是SPI2,软件配置几乎和主机没什么变化,主要是在于NSS选择。在配置的时候Hardware NSS Signal 选择Hardware NSS Input Signal 。从机设置为硬件输入比较好。
3、发送接收程序:
(1)主机的发送接收函数:
为什么是发送and接收呢?因为spi的全双工模式之下,发送和接收是同时发生的,移位寄存器的数据环流。可以去看具体的时序图找结果。
while (1)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi2,txbuff1,rxbuff,10,1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
HAL_Delay(1000);
cnt++;
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi2,txbuff2,rxbuff,10,1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
HAL_Delay(1000);
cnt++;
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
(2)从机的接收发送函数:
关键注意点:在进入回调函数之前,必须先执行一遍
void SPI2_init_IT(void)
{
HAL_SPI_TransmitReceive_DMA(&hspi2,txbuff1,rxbuff,10);
}
在main.c中,在初始化spi之后,执行上面这就话就可以。
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SPI1_Init();
MX_SPI2_Init();
/* USER CODE BEGIN 2 */
SPI2_init_IT();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
在spi.c文件中写回调函数
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
if(hspi==&hspi2)
{
cnt++;
if(cnt%2==1)
{
HAL_SPI_TransmitReceive_IT(&hspi2,txbuff1,rxbuff,10);
}
else
{
HAL_SPI_TransmitReceive_IT(&hspi2,txbuff2,rxbuff,10);
}
}
}
在这里,从机还可以单独接收主机发送过来的数据,不发送数据给主机。但是一般情况下,主机想要读取从机的数据,就需要先向从机写数据,于此同时实现读取数据的功能。