内容:如题
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); } }}
在这里,从机还可以单独接收主机发送过来的数据,不发送数据给主机。但是一般情况下,主机想要读取从机的数据,就需要先向从机写数据,于此同时实现读取数据的功能。 |