你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32f103c8t6 串口空闲中断DMA接收问题

[复制链接]
just88 提问时间:2020-2-11 23:06 /
悬赏1ST金币未解决
Usart1-Rx作为外设,DMA接收到内存Buf,设置串口空闲中断,结果是空闲中断后得到数据没有按照一个Byte拆包,很纳闷是怎么回事:比如串口助手发送数据A1B2C3D4,中断后接收到数据是Buf【0】=D4C3B2A1;DMA初始化中设置数据传输是8位,不应该是 Buf【0】=A1,Buf【1】=B2,Buf【2】=C3,Buf【3】=D4;一个Byte数据一个地址递增吗?
Usart1初始化:
        //GPIO端口设置
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);        //使能USART1,GPIOA时钟

        //USART1_TX   GPIOA.9
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

        //USART1_RX          GPIOA.10初始化
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

        //Usart1 NVIC 配置
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器

        //USART 初始化设置

        USART_InitStructure.USART_BaudRate = bound;//串口波特率
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
        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_RXNE, ENABLE);        //开启串口接受中断
        USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
        USART_Cmd(USART1, ENABLE);                            //使能串口1

//*********************************************************************************
dma初始化:
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);                                     //使能DMA传输
        DMA_DeInit(DMA1_Channel5);                                                                               //将DMA的通道1寄存器重设为缺省值
        DMA1_MEM_LEN=100;
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;                  //DMA外设基地址
        DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)Usart1RxBuf;                          //DMA内存基地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                                          //数据传输方向,从内存读取发送到外设
        DMA_InitStructure.DMA_BufferSize = 100;                                                                  //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_InitStructure.DMA_M2M = DMA_M2M_Disable;                                                  //DMA通道x没有设置为内存到内存传输
        DMA_Init(DMA1_Channel5, &DMA_InitStructure);                                                        //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
        USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
        DMA_Cmd(DMA1_Channel5,ENABLE);

//*********************************************************************************
IDLE中断:
        uint8_t Res;
        if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  //
        {
//                USART_ClearFlag(USART1,USART_FLAG_IDLE);
                Res=USART1->SR;
                Res=USART1->DR;
                DMA_Cmd(DMA1_Channel5,DISABLE);
                DMA_SetCurrDataCounter(DMA1_Channel5,100);
                DMA_Cmd(DMA1_Channel5,ENABLE);
               
               
                memcpy(Usart1RxData,Usart1RxBuf,100);
                memset(Usart1RxBuf,0x00,100);
        }

123.png
收藏 评论6 发布时间:2020-2-11 23:06

举报

6个回答
radio2radio 回答时间:2020-2-11 23:12:08
缓存Usart1RxBuf的类型, 改为 uint8_t 。

评分

参与人数 1ST金币 +1 收起 理由
just88 + 1 赞一个!

查看全部评分

just88 回答时间:2020-2-11 23:19:20
源地址和目标地址要一致,实际测试也是接收不到数据。
tyhjrwx2011 回答时间:2020-2-11 23:35:29
内存数据默认是小端模式的缘故

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

yklstudent-1794 回答时间:2020-2-12 11:15:59
字节方式,Usart1RxBuf定义成uint32_t类型,都不一致

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

just88 回答时间:2020-2-12 11:21:56
多谢上面两位兄弟指点,把Usart1RxBuf数据定义改为uint8_t,但是DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)Usart1RxBuf;
还是要写成(uint32_t)Usart1RxBuf;这样就就可以了。
butterflyspring 回答时间:2020-2-17 11:15:38
从截图上看是STM32的内存排列顺序。芯片内部的排列是上面兄弟说的小端模式,也就是地位地址放地位字节,所以调试模式下显示的好像倒过来一样,其实是正确的

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版