OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2448|回复: 5

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

[复制链接]

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2016-3-24
在线时间
20 小时
发表于 2020-2-10 23:34:50 | 显示全部楼层 |阅读模式
8金钱
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
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2016-3-24
在线时间
20 小时
 楼主| 发表于 2020-2-10 23:36:54 | 显示全部楼层
本帖最后由 ccwinner 于 2020-2-10 23:43 编辑

路过大神帮指点下,这是哪里的问题?原元件如下:

实验22 DMA实验.rar

2.68 MB, 下载次数: 51

回复

使用道具 举报

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2016-3-24
在线时间
20 小时
 楼主| 发表于 2020-2-11 17:38:14 | 显示全部楼层
自己顶个
回复

使用道具 举报

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2016-3-24
在线时间
20 小时
 楼主| 发表于 2020-2-11 21:24:15 | 显示全部楼层
有人来帮解释下吗?
回复

使用道具 举报

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
70
金钱
70
注册时间
2016-3-24
在线时间
20 小时
 楼主| 发表于 2020-2-12 11:17:00 | 显示全部楼层
问题已解决,把Usart1RxBuf数组定义为uint8_t,但是 DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)Usart1RxBuf; 这句还得写成(uint32_t)Usart1RxBuf。
回复

使用道具 举报

5

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2019-11-24
在线时间
24 小时
发表于 2020-2-12 12:30:55 | 显示全部楼层
ccwinner 发表于 2020-2-12 11:17
问题已解决,把Usart1RxBuf数组定义为uint8_t,但是 DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)Usa ...

兄弟,用DMA可以发送连续2个break(或空闲)信号么?比如在发送一帧数据前,发送一个持续16位的低电平
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-20 11:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表