STM32L053 DMA串口接收不定长数据初始化问题
项目需求第一次用HAL库,百度了下串口接收不定长数据除了频繁进中断就只能用DMA了,初始化一直死机,大牛们给看看啊UART_HandleTypeDef Uart1Handle;
DMA_HandleTypeDef DMA_USART1_rx;
DMA_HandleTypeDef DMA_USART1_tx;
int Rx1_flag;
int Rx1_cnt ;
unsigned char Rx1_buf;
unsigned char Tx1_buf;
void UART1_Init(void)
{
GPIO_InitTypeDefGPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* UART TX GPIO pin configuration*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* UART RX GPIO pin configuration*/
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Uart1Handle.Instance = USART1;
Uart1Handle.Init.BaudRate = 115200;
Uart1Handle.Init.WordLength = UART_WORDLENGTH_8B;
Uart1Handle.Init.StopBits = UART_STOPBITS_1;
Uart1Handle.Init.Parity = UART_PARITY_NONE;
Uart1Handle.Init.HwFlowCtl= UART_HWCONTROL_NONE;
Uart1Handle.Init.Mode = UART_MODE_TX_RX;
Uart1Handle.Init.OverSampling = UART_OVERSAMPLING_16;
Uart1Handle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
Uart1Handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if(HAL_UART_Init(&Uart1Handle) != HAL_OK)
{
while(1);
}
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
__HAL_UART_ENABLE_IT(&Uart1Handle, UART_IT_IDLE);
DMA_USART1_rx.Instance = DMA1_Channel3;
DMA_USART1_rx.Init.Request = DMA_REQUEST_3;
DMA_USART1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
DMA_USART1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
DMA_USART1_rx.Init.MemInc = DMA_MINC_ENABLE;
DMA_USART1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
DMA_USART1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
DMA_USART1_rx.Init.Mode = DMA_NORMAL;
DMA_USART1_rx.Init.Priority = DMA_PRIORITY_LOW;
__HAL_LINKDMA(&Uart1Handle,hdmarx,DMA_USART1_rx);
if (HAL_DMA_Init(&DMA_USART1_rx) != HAL_OK)
{
while(1);
}
DMA_USART1_tx.Instance = DMA1_Channel2;
DMA_USART1_tx.Init.Request = DMA_REQUEST_3;
DMA_USART1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
DMA_USART1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
DMA_USART1_tx.Init.MemInc = DMA_MINC_ENABLE;
DMA_USART1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
DMA_USART1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
DMA_USART1_tx.Init.Mode = DMA_NORMAL;
DMA_USART1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&DMA_USART1_tx) != HAL_OK)
{
while(1);
}
__HAL_LINKDMA(&Uart1Handle,hdmatx,DMA_USART1_tx);
HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
HAL_UART_Receive_DMA(&Uart1Handle, Rx1_buf,Rx1_cnt);
}
void USART1_SendStr(unsigned char *Tx,int length)
{
HAL_UART_Transmit(&Uart1Handle,Tx,length,0xffff);
}
void dma_printf(const char *format, ...)
{
uint32_t length;
va_list args;
va_start(args, format);
length = vsnprintf((char *)Tx1_buf, sizeof(Tx1_buf), (char *)format, args);
va_end(args);
HAL_UART_Transmit_DMA(&Uart1Handle, (uint8_t *)Tx1_buf, length);
}
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&Uart1Handle);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
一直死机,死在哪个位置?建议你使用cubeMX配置初始化代码 是执行完 HAL_DMA_Init 死吗?
没有看到DMA中断入口的处理程序。
建议解决过程:
先测试串口是否已经初始化完成,并且可以发送数据,
再测试DMA是否初始化成功,并且可以接收数据。
还有,建议为while(1),增加超时退出功能。 本帖最后由 power568 于 2017-11-14 13:08 编辑
串口一般不会导致死机的,建议:1. 检查你的SysTick中断是否打开,有可能死在某个超时等待处;
2. 使用STM32Cube软件生成初始化程序,看是软件问题还是硬件问题,测试稳定后再移植到你的工程中;
3. 使用HAL库的话,SysTick中断一定要打开,库里的很多超时都是基于SysTick的;
我很少用DMA,一帧数据 用IDLE中断没有的开个定时器自己模拟一个 初始化死机正是你用仿真一步一步跟踪的好时机,自己的程序自己来看,自己的问题最终都是自己解决的, 我都很少用DMA直接用定时器模拟比较好 HAL库DMA的问题太多了 很多坑
页:
[1]