一 前记
SPI接口平时用的比较少,再加上对CUBEMX不是很熟悉,这里踩了不少坑才把问题解决。针对遇到了不少问题,是要值得梳理一下了。
二 源码解析
1 SPI的DMA发送端配置:
2 主函数源码:
uint32_t g_spi_cnt = 0; void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { g_spi_cnt++; } 2 主函数源码: /** * @brief The application entry point. * @retval int */ 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_SPI2_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ uart1_test(); memset(TX_Data,0x01,DATA_SIZE); /* USER CODE END 2 */ HAL_SPI_Transmit_DMA(&hspi2, TX_Data, sizeof(TX_Data)); /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ HAL_Delay(1000); mprintf("g_spi_master_dma_cnt 2.18h is:0x%x \n\r",g_spi_cnt%0xff); for (uint32_t iss = 0; iss < DATA_SIZE; iss++) { /* code */ TX_Data[iss] = g_spi_cnt%0xff; } dump8(TX_Data,sizeof(TX_Data)); HAL_SPI_Transmit_DMA(&hspi2, TX_Data, sizeof(TX_Data)); /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
3 SPI的DMA接收端配置:
4 SPI SLAVE源码:
#define DATA_SIZE 64 uint8_t RX_Data[DATA_SIZE]; uint32_t g_spi_cnt = 0; void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi) { HAL_SPI_Receive_DMA(&hspi2, RX_Data, DATA_SIZE); dump8(RX_Data,10); g_spi_cnt++; mprintf("g_spi_slave_cnt 2.18hh is:%d \n\r",g_spi_cnt); } /** * @brief The application entry point. * @retval int */ 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_SPI2_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ uart1_test(); /* USER CODE END 2 */ memset(RX_Data,0x00,sizeof(RX_Data)); HAL_SPI_Receive_DMA(&hspi2, RX_Data, sizeof(RX_Data)); /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ //HAL_Delay(200); /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
三 总结
1 DMA的配置模式,
笔者刚开始根据网上的资料,配置了circular模式,发现接收侧一直收到莫名其妙的数据,并且数据经常出错。
修改成了normal模式之后,接收到的数据就对了。关于这两种模式的区别,我已经在前文中介绍过了。
2 SPI位宽设置:
这里遇到的另外一个大问题就是SPI位宽,cube软件默认是4bit,加入按照这个模式设置,你会发现只收到后四个bit的数据,前四个bit为零。
所以,把这个改称8bit是一个必备的。如下图所示:
3 感触:
stm32 CUBE MX是一个比较强大的工具,可这个不是意味着你可以没带基础的话随便使用它,理解协议和里面的每一个含义,才能不至于掉入坑里面。
再者,进去了能否出来,这个要考验你的编码水平和经验了。
标签:dma,BEGIN,CODE,SPI,stm32,spi,Init,USER,Data From: https://www.cnblogs.com/dylancao/p/18020729