由于Nucleo 开发板没有带有显示屏幕,如果自己不想扩展LCD,那么在使用Nucleo 调试中想打印输出一些调整信息到PC就很有必要。我们使用Nucleo板子上自带的STLINK上的虚拟串口连接到STM32F767ZIT6上的串口3,这样我们的调试信息就可以通过STLINK的虚拟串口发送到电脑的串口助手了。
硬件连接图如下:
 
下面我们分别使用串口的3中输出模式来打印调试信息:
1)查询模式发送数据:这个模式使用的是重定向printf函数实现的,使用之前要选择keil的Mocro LIB。
发送的重定向函数如下:
- fputc(int ch, FILE *f)
- {
- /* Place your implementation of fputc here */
- /* e.g. write a character to the USART3 and Loop until the end of transmission */
- HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 0xFFFF);
- return ch;
- }
2)串口中断发送模式是使用串口发送中断实现的,实现函数如下:
- void My_Printf_IT(uint8_t *pData, uint16_t Size)
- {
- HAL_UART_Transmit_IT(&UartHandle,pData,Size);
- }
3)串口DMA中断发送模式:
- void My_Printf_IT(uint8_t *pData, uint16_t Size)
- {
- HAL_UART_Transmit_IT(&UartHandle,pData,Size);
- }
需要注意的是上面后2种是使用中断发送的所以要控制发送的时间间隔。
在串口的初始化中我们要初始化串口的dma发送和使能发送中断打开:
- void HAL_UART_MspInit(UART_HandleTypeDef *huart)
- {
- static DMA_HandleTypeDef hdma_rx;
- static DMA_HandleTypeDef hdma_tx;
- GPIO_InitTypeDef GPIO_InitStruct;
- RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
- __HAL_RCC_GPIOD_CLK_ENABLE();
-
- /* Select SysClk as source of USART1 clocks */
- RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
- RCC_PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_SYSCLK;
- HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
- /* Enable USARTx clock */
- __HAL_RCC_USART3_CLK_ENABLE();
-
- __HAL_RCC_DMA1_CLK_ENABLE();
- /* UART TX GPIO pin configuration */
- GPIO_InitStruct.Pin = GPIO_PIN_8;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
- HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
- /* UART RX GPIO pin configuration */
- GPIO_InitStruct.Pin = GPIO_PIN_9;
- GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
- HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
-
- hdma_tx.Instance = DMA1_Stream3;
- hdma_tx.Init.Channel = DMA_CHANNEL_4;
- hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
- hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
- hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
- hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
- hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
- hdma_tx.Init.Mode = DMA_NORMAL;
- hdma_tx.Init.Priority = DMA_PRIORITY_HIGH;
- hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
- hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
- hdma_tx.Init.MemBurst = DMA_MBURST_INC4;
- hdma_tx.Init.PeriphBurst = DMA_PBURST_INC4;
- HAL_DMA_Init(&hdma_tx);
- /* Associate the initialized DMA handle to the UART handle */
- __HAL_LINKDMA(&UartHandle, hdmatx, hdma_tx);
- hdma_rx.Instance = DMA1_Stream1;
- hdma_rx.Init.Channel = DMA_CHANNEL_4;
- hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
- hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
- hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
- hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
- hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
- hdma_rx.Init.Mode = DMA_NORMAL;
- hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
- hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
- hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
- hdma_rx.Init.MemBurst = DMA_MBURST_INC4;
- hdma_rx.Init.PeriphBurst = DMA_PBURST_INC4;
- HAL_DMA_Init(&hdma_rx);
- /* Associate the initialized DMA handle to the UART handle */
- __HAL_LINKDMA(&UartHandle, hdmarx, hdma_rx);
- HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0, 1);
- HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
- HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 1);
- HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
- HAL_NVIC_SetPriority(USART3_IRQn, 0, 1);
- HAL_NVIC_EnableIRQ(USART3_IRQn);
- }
最后我们在main函数中测试3种输出打印函数:
可以在电脑串口助手中查看输出如下:
USART DMA Printf:hello,world
USART IT Printf:hello,world
USART Loop Printf:hello,world
USART DMA Printf:hello,world
USART IT Printf:hello,world
USART Loop Printf:hello,world
USART DMA Printf:hello,world
USART IT Printf:hello,world
USART Loop Printf:hello,world
USART DMA Printf:hello,world
USART IT Printf:hello,world
USART Loop Printf:hello,world
USART DMA Printf:hello,world
USART IT Printf:hello,world
USART Loop Printf:hello,world
USART DMA Printf:hello,world
|