由于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种输出打印函数:
uint8_t buff_loop[40] = "USART Loop Printf:hello,world\n";
uint8_t buff_dma[40] = "USART DMA Printf:hello,world\n";
uint8_t buff_IT[40] = "USART IT Printf:hello,world\n";
int main(void)
{
CPU_CACHE_Enable();
HAL_Init();
SystemClock_Config();
USART3_Init();
while (1)
{
printf((const char*)buff_loop);
HAL_Delay(1000);
My_Printf_DMA(buff_dma,strlen((const char*)buff_dma));
HAL_Delay(1000);
My_Printf_IT(buff_IT,strlen((const char*)buff_IT));
HAL_Delay(1000);
}
}
可以在电脑串口助手中查看输出如下:
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
|
|