现象:把DMA配置成循环模式就能正常接受串口1的数据,配置成普通模式只能正常接受第一次,第二次就不行了,这是为什么??? 使用的是阿波罗的板,STM32F429
串口初始化如下:
void uart_init(u32 bound)
{
//UART 初始化设置
UART1_Handler.Instance=USART1; //USART1
UART1_Handler.Init.BaudRate=bound; //波特率
UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
UART1_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
UART1_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
UART1_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&UART1_Handler); //HAL_UART_Init()会使能UART1
//HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量(使用回调函数处理中断需要调用该函数)
}
//UART底层初始化,时钟使能,引脚配置,中断配置
//此函数会被HAL_UART_Init()调用
//huart:串口句柄
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_Initure;
if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
{
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
__HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟
GPIO_Initure.Pin=GPIO_PIN_9; //PA9
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FAST; //高速
GPIO_Initure.Alternate=GPIO_AF7_USART1; //复用为USART1
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA9
GPIO_Initure.Pin=GPIO_PIN_10; //PA10
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10
__HAL_UART_DISABLE_IT(huart,UART_IT_TC);
__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
__HAL_UART_ENABLE_IT(huart,UART_IT_IDLE); //开启空闲中断
//SET_BIT(USART1->CR3,USART_CR3_DMAR); //使能串口1的DMA接受
#if EN_USART1_RX
// __HAL_UART_ENABLE_IT(huart,UART_IT_RXNE); //开启接收中断
HAL_NVIC_EnableIRQ(USART1_IRQn); //使能USART1中断通道
HAL_NVIC_SetPriority(USART1_IRQn,3,3); //抢占优先级3,子优先级3
#endif
}
}
DMA初始化如下:
void My_DMA_Init()
{
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_LINKDMA(&UART1_Handler,hdmarx,Uart1Rx_DMA_handle);
Uart1Rx_DMA_handle.Instance=DMA2_Stream5;
Uart1Rx_DMA_handle.Init.Channel=DMA_CHANNEL_4;
Uart1Rx_DMA_handle.Init.Direction=DMA_PERIPH_TO_MEMORY;
Uart1Rx_DMA_handle.Init.PeriphInc=DMA_PINC_DISABLE;
Uart1Rx_DMA_handle.Init.MemInc=DMA_MINC_ENABLE;
Uart1Rx_DMA_handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;
Uart1Rx_DMA_handle.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE;
Uart1Rx_DMA_handle.Init.Mode=DMA_CIRCULAR; //就是这里,配置成DMA_NORMAL就不行了
Uart1Rx_DMA_handle.Init.Priority=DMA_PRIORITY_MEDIUM;
Uart1Rx_DMA_handle.Init.FIFOMode=DMA_FIFOMODE_DISABLE;
Uart1Rx_DMA_handle.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;
Uart1Rx_DMA_handle.Init.MemBurst=DMA_MBURST_SINGLE;
Uart1Rx_DMA_handle.Init.PeriphBurst=DMA_PBURST_SINGLE;
HAL_DMA_DeInit(&Uart1Rx_DMA_handle);
HAL_DMA_Init(&Uart1Rx_DMA_handle);
HAL_UART_Receive_DMA(&UART1_Handler,USART1_RX_BUF,200);//开启dma接收
}
串口中断如下:
void USART1_IRQHandler(void)
{
if((__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_IDLE)!=RESET)) //空闲中断
{
printf("进入空闲中断了
");
__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
HAL_UART_DMAStop(&UART1_Handler);
USART1_RX_NUM = UART1_Handler.hdmarx->Instance->NDTR;
USART1_RX_NUM = 200 - USART1_RX_NUM;
printf("接受到了%d个数据
",USART1_RX_NUM);
HAL_UART_Receive_DMA(&UART1_Handler,USART1_RX_BUF,200);//开启dma接收
for(i=0;i<USART1_RX_NUM;i++)
{
printf("%x ",USART1_RX_BUF[i]);
}
printf("
");
}
HAL_UART_IRQHandler(&UART1_Handler);
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
DMA_Cmd(DMA2_Stream5,DISABLE);
DMA_ClearFlag(DMA2_Stream5,DMA_FLAG_TCIF5);
len = set_recLen - DMA_GetCurrDataCounter(DMA2_Stream5);
DMA_SetCurrDataCounter(DMA2_Stream5,set_recLen);
DMA_Cmd(DMA2_Stream5,ENABLE);
HAL_UART_Receive_DMA(&UART1_Handler,USART1_RX_BUF,200);//开启dma接收
这个函数里有设了,这个函数有调用DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);。是设了的
HAL库没有用过,你找下有没有跟上面功能相同的函数
一周热门 更多>