利用STM32CubeMX软件实现stm32f427双机SPI全双工模式发送接收成功(HAL库函数)

2019-07-20 00:53发布

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

0条回答

一周热门 更多>