小弟这边需要通过DMA接收串口的数据,但调试一直未成功,有时候第一次接受到数据,而且数据前8位为0,后面的数据对着?
[mw_shl_code=c,true]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,并且设置接收缓冲以及接收缓冲接收最大数据量
}
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时钟
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_Initure.Pin=GPIO_PIN_9; //PA9
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
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_ENABLE_IT(huart,UART_IT_IDLE); //开启空闲中断
HAL_NVIC_SetPriority(USART1_IRQn,0,0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USART2 DMA Init */
__HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx);
hdma_usart1_rx.Instance = DMA1_Stream0;
hdma_usart1_rx.Init.Request = DMA_REQUEST_USART1_RX;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_usart1_rx.Init.MemBurst=DMA_MBURST_SINGLE; //存储器单次突发传输
hdma_usart1_rx.Init.PeriphBurst=DMA_PBURST_SINGLE; //外设突发单次传输
HAL_DMA_DeInit(&hdma_usart1_rx);
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
//_Error_Handler(__FILE__, __LINE__);
}
//HAL_DMAEx_MultiBufferStart(&hdma_usart1_rx,(uint32_t)&huart->Instance->RDR,(u32)sairecbuf1,(u32)sairecbuf2,10);//开启双缓冲
//__HAL_DMA_DISABLE(&hdma_usart1_rx);
delay_us(10);
__HAL_DMA_CLEAR_FLAG(&hdma_usart1_rx,DMA_FLAG_TCIF0_4); //清除DMA传输完成中断标志位
__HAL_DMA_ENABLE_IT(&hdma_usart1_rx,DMA_IT_TC); //开启传输完成中断
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)//如果是串口1
{
printf("callback
");
}
}
//串口1中断服务程序
void USART1_IRQHandler(void)
{
uint32_t temp = 0;
uint8_t RX_LEN = 0;
u32 i =0;
if((__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_IDLE)!=RESET)) //空闲接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
temp = USART1->ISR;
printf("ISR %d
",temp);
temp = USART1->RDR;
printf("RDR %d
",temp);
//HAL_UART_IRQHandler(&UART1_Handler);
__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
__HAL_UART_CLEAR_IT(&UART1_Handler,UART_FLAG_IDLE);
// __HAL_UART_CLEAR_IT(&UART1_Handler,UART_CLEAR_TCF);
//HAL_UART_AbortReceive(&UART1_Handler);
HAL_UART_DMAStop(&UART1_Handler);
//UART1_Handler.RxState = HAL_UART_STATE_READY;
//temp = (hdma_usart1_rx.Instance)->ISR;
// temp = __HAL_DMA_GET_IT_SOURCE(&UART1_Handler,DMA_IT_TC);
// printf("DMA tc %d
",temp);
// if(__HAL_DMA_GET_FLAG(&UART1_Handler,DMA_FLAG_TCIF0_4))
// {
// printf("tcif
");
// __HAL_DMA_CLEAR_FLAG(&UART1_Handler,DMA_FLAG_TCIF0_4);
// //HAL_UART_DMAStop(&UART1_Handler);
// HAL_UART_AbortReceive(&UART1_Handler);
// }
// temp = ((DMA_Stream_TypeDef *)hdma_usart1_rx.Instance)->NDTR;
temp =__HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
printf("temp = %d
",temp);
RX_LEN = USART_REC_LEN - temp;//RX_LEN为数据长度,暂时不使用
printf("rx len = %d
",RX_LEN);
// for(i = 0;i< RX_LEN; i++)
// {
// printf(" %02x ",USART_RX_BUF);
// }
// if(RX_LEN > 0)
USART_RX_STA = (RX_LEN | 0x8000);
// HAL_UART_Receive_DMA(&UART1_Handler,USART_RX_BUF,USART_REC_LEN);
}
HAL_UART_IRQHandler(&UART1_Handler); //可以不调用他自带的处理函数
}
void DMA1_Stream0_IRQHandler(void)
{
uint32_t temp = 0;
uint8_t RX_LEN = 0;
u32 i =0;
//printf("dma10
");
if(__HAL_DMA_GET_FLAG(&hdma_usart1_rx,DMA_FLAG_TCIF0_4)!=RESET)//DMA传输完成
{
__HAL_DMA_CLEAR_FLAG(&hdma_usart1_rx,DMA_FLAG_TCIF0_4);//清除DMA传输完成中断标志位
printf("dma irq
");
}
}
int main(void)
{
u8 len;
u16 times=0;
u32 i =0;
u8 res =0 ;
Cache_Enable(); //打开L1-Cache
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(160,5,2,4); //设置时钟,400Mhz
delay_init(400); //延时初始化
uart_init(115200); //串口初始化
LED_Init(); //初始化LED
// __HAL_DMA_ENABLE(&hdma_usart1_rx);
while(1)
{
res = HAL_UART_Receive_DMA(&UART1_Handler,USART_RX_BUF,USART_REC_LEN);
printf("res =%d
",res);
if(res == 0)
{
break;
}
//vTaskDelay(1000);
}
__HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_IDLE);//使能idle中断
//delay_ms(500);
while(1)
{
//printf("sta %d
",USART_RX_STA&0x8000);
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("len %d:
",len);
for(i = 0;i< len; i++)
{
printf(" %02x ",USART_RX_BUF);
}
//HAL_UART_Transmit(&UART1_Handler,(uint8_t*)USART_RX_BUF,len,1000); //发送接收到的数据
//while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET); //等待发送结束
printf("
");//插入换行
memset(USART_RX_BUF,0,USART_REC_LEN);
delay_ms(50);
res = HAL_UART_Receive_DMA(&UART1_Handler,USART_RX_BUF,USART_REC_LEN);
printf("res %d
",res);
USART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("
ALIENTEK STM32H7开发板 串口实验
");
printf("正点原子@ALIENTEK
");
}
if(times%200==0)printf("请输入数据,以回车键结束
");
if(times%30==0)LED0_Toggle;//闪烁LED,提示系统正在运行.
delay_ms(10);
}
}
}
[/mw_shl_code]
一周热门 更多>