打印
[STM32F0]

STM32F031 UART1 DMA 接收空闲中断请教。

[复制链接]
504|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ihafd|  楼主 | 2020-10-30 10:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 ihafd 于 2020-10-30 10:19 编辑

我用STM32F031 的UART1 加DMA收发数据。DMA>UART1发送数据正常,
用DMA>UART1接收数据加空闲中断不行,收到的都是00
接收数据长度10个字节左右,长度变化的。

配置如下,查了两天了,找不到原因。
请指教!感谢!!

void UART1_Init(void)
{
             USART_InitTypeDef USART_InitStructure;
            GPIO_InitTypeDef GPIO_InitStructure;
            NVIC_InitTypeDef NVIC_InitStructure;
            DMA_InitTypeDef DMA_InitStructure;        
               
            RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);        
           RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟        
            RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
        

            GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
            GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);
        
                        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9;        
                        GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF;
                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                        GPIO_Init(GPIOA, &GPIO_InitStructure);        
        
                        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10;        
                        GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF;
                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                        GPIO_Init(GPIOA, &GPIO_InitStructure);
        
                        USART_InitStructure.USART_BaudRate = 115200;
                        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
                        USART_InitStructure.USART_StopBits = USART_StopBits_1;
                        USART_InitStructure.USART_Parity = USART_Parity_No;
                        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
                        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
                        USART_Init(USART1, &USART_InitStructure); //初始化串口1


                        USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启空闲中断
                        USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);   //使能串口3 DMA接收               
                        USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);   //使能串口3 DMA发送        
                        USART_Cmd(USART1, ENABLE);  //使能串口1

                        //Usart1 NVIC 配置
                        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
                        NVIC_InitStructure.NVIC_IRQChannelPriority = 2;
                        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
                        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器、

    //UART1 DMA 接收配置。
                DMA_DeInit(DMA1_Channel3);                                     //将DMA的通道3寄存器重设为缺省值  串口3对应的是DMA通道3
                DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->RDR);   //DMA外设ADC基地址
                DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&UART1_Rec_Buff[0];    //DMA内存基地址
                DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;             //数据传输方向,从外设读取发送到内存
                DMA_InitStructure.DMA_BufferSize = UART1_DMA_Rec_Len;          //DMA通道的DMA缓存的大小
                DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
                DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         //内存地址寄存器递增
                DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
                DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
                DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                    //工作在正常缓存模式
                DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;            //DMA通道 x拥有中优先级                                 
                DMA_Init(DMA1_Channel3, &DMA_InitStructure);                     //根据DMA_InitStruct中指定的参数初始化DMA的通道                        
                DMA_Cmd(DMA1_Channel3, ENABLE);                                  //正式驱动DMA传输
                                                
                //DMA发送中断设置
                NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_3_IRQn;  
                NVIC_InitStructure.NVIC_IRQChannelPriority = 2;  
                NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
                NVIC_Init(&NVIC_InitStructure);

    //UART1_DMA发送配置                 
                DMA_DeInit(DMA1_Channel2);  //DMA1通道2配置                 
                DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->TDR); //外设地址                    
                DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&UART1_Send_Buff[0]; //内存地址                 
                DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //dma传输方向单向                  
                DMA_InitStructure.DMA_BufferSize = 100;  //设置DMA在传输时缓冲区的长度                  
                DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //设置DMA的外设递增模式,一个外设                 
                DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //设置DMA的内存递增模式                  
                DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //外设数据字长                  
                DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;  //内存数据字长                 
                DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //设置DMA的传输模式                 
                DMA_InitStructure.DMA_Priority = DMA_Priority_High;  //设置DMA的优先级别                  
                DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //设置DMA的2个memory中的变量互相访问
                DMA_Init(DMA1_Channel2,&DMA_InitStructure);
               
                DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);
               
                UART1_DMA_RX_OK = 0;

}
/**********************************************UART1 MDA接收中断******************************************/
void USART1_IRQHandler(void)                        
{
                u16 Res;
            
                if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  //接收空闲中断
                {
                          Res = USART_ReceiveData(USART1);                       //读取数据 注意:这句必须要,否则不能够清除中断标志位。               

                          DMA_Cmd(DMA1_Channel3, DISABLE);                 //失能UART1的DMA
                          UART1_DMA_RX_LEN = UART1_DMA_Rec_Len-DMA_GetCurrDataCounter(DMA1_Channel3); //算出接本帧数据长度
                          USART_ClearITPendingBit(USART1, USART_IT_IDLE);         //清除中断标志
                        
                          UART1_DMA_RX_OK = OPEN;
                                 
                }
               
}

到底错在哪里???
是这句错吗?基地址应该是什么?
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->RDR);   //DMA外设ADC基地址
感谢!感谢!

使用特权

评论回复
沙发
ihafd|  楼主 | 2020-10-30 10:52 | 只看该作者
现在试了下,它只可 接收四个字节中的第一个
例如接收 99 AA BB CC  它就只收到99
例如拉接 11 22 33 44 55 66 77 88 它就只收到55

为什么啊?

使用特权

评论回复
板凳
ihafd|  楼主 | 2020-11-1 00:07 | 只看该作者
啊!自己顶一下。谢谢。

使用特权

评论回复
地板
Prry| | 2020-11-25 23:53 | 只看该作者
参考实现,高速通信(1.5Mbps)不翻车:https://acuity.blog.csdn.net/article/details/108367512

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

290

主题

844

帖子

3

粉丝