OpenEdv-开源电子网

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

串口DMA接收问题?

[复制链接]

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2016-10-31
在线时间
18 小时
发表于 2016-12-31 16:07:18 | 显示全部楼层 |阅读模式
1金钱
求助:我用USART1接收数据,将数据用DMA存放在内存的BUFF中,通过轮询查看USART1的DMA接收完成标志,判断BUFF是否存满,然后在用串口4将存的BUFF中的数据读出来。现在问题是:程序下载后,只能通过串口4收到一次数据(只能最开始检查到一次USART1的DMA接收完成标志),之后DMA接收完成标志一直为0,串口4再也收不到数据了,请问是什么原因?(在网上,论坛看了很多相关的问题,但都没有解决此问题)

下面是main函数程序:
u8 PlayLoadByte,streamByte;
u8 USART1_RECEIVE_BUF[USART1_RECEIVE_MAX];
int main(void)
{
        int i;
        delay_init();
        UART4_Init(9600);
        USART1_Init(57600);
        USART1_DMARX_Init((u32)&USART1->DR,(u32)USART1_RECEIVE_BUF,USART1_RECEIVE_MAX);
//        UART4_DMATX_Init((u32)&UART4->DR,(u32)&PlayLoadByte,1);
        while(1)
        {
   USART1_DMA_Enable();
                while(1)
                {
                        if(DMA_GetFlagStatus(DMA1_FLAG_TC5)==SET)
                        {
                                DMA_Cmd(DMA1_Channel5,DISABLE);
                                DMA_ClearFlag(DMA1_FLAG_TC5);
                                USART_GetFlagStatus(UART4,USART_FLAG_TC);
                                for(i=0;i<(USART1_RECEIVE_MAX-DMA_GetCurrDataCounter(DMA1_Channel5));i++)
                                {
                                        streamByte = USART1_RECEIVE_BUF[i];
                                        USART_SendData(UART4,streamByte);
                                        while(USART_GetFlagStatus(UART4,USART_FLAG_TC)!=SET);
                                }
                                break;
                        }
                        delay_ms(100);
                        LED0=!LED0;
                }
                delay_ms(100);
                LED1=!LED1;
        }       
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2016-10-31
在线时间
18 小时
 楼主| 发表于 2016-12-31 16:08:36 | 显示全部楼层
下面是USART配置:
void UART4_Init(u32 bound)
{
        USART_InitTypeDef USART_InitStruct;
        GPIO_InitTypeDef GPIO_InitStruct;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);//ê1&#196;üUSART4ê±&#214;ó
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE,ENABLE);
       
        //UART4μ&#196;IO&#191;ú&#197;&#228;&#214;&#195;
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;//PC10&#206;aUART4μ&#196;TX&#182;&#203;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//í&#198;&#195;a&#184;′ó&#195;ê&#228;3&#246;&#196;£ê&#189;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC,&GPIO_InitStruct);
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;//PC11&#206;aUART4μ&#196;RX&#182;&#203;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//&#184;&#161;&#191;&#213;ê&#228;è&#235;&#196;£ê&#189;
        GPIO_Init(GPIOC,&GPIO_InitStruct);
       
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOE,&GPIO_InitStruct);
       
        USART_InitStruct.USART_BaudRate = bound;//′&#174;&#191;ú2¨ì&#216;&#194;ê
        USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//ê&#213;/·¢&#196;£ê&#189;
        USART_InitStruct.USART_Parity = USART_Parity_No;//&#206;T&#198;&#230;&#197;&#188;D£&#209;é&#206;&#187;
        USART_InitStruct.USART_StopBits = USART_StopBits_1;//ò&#187;&#184;&#246;í£&#214;1&#206;&#187;
        USART_InitStruct.USART_WordLength = USART_WordLength_8b;//8&#206;&#187;êy&#190;Y3¤&#182;è
        USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//&#206;Tó2&#188;tá÷&#191;&#216;&#214;&#198;
        USART_Init(UART4,&USART_InitStruct);//3&#245;ê&#188;&#187;ˉ′&#174;&#191;ú4
       
        USART_Cmd(UART4,ENABLE);//ê1&#196;ü′&#174;&#191;ú4
}
/*****************************************************************************************************

*****************************************************************************************************/
void USART1_Init(u32 bound)
{
        USART_InitTypeDef USART_InitStruct;
        GPIO_InitTypeDef GPIO_InitStruct;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
       
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;//PC10&#206;aUART4μ&#196;TX&#182;&#203;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//í&#198;&#195;a&#184;′ó&#195;ê&#228;3&#246;&#196;£ê&#189;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStruct);
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;//PC11&#206;aUART4μ&#196;RX&#182;&#203;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//&#184;&#161;&#191;&#213;ê&#228;è&#235;&#196;£ê&#189;
        GPIO_Init(GPIOA,&GPIO_InitStruct);
       
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,&GPIO_InitStruct);
       
        USART_InitStruct.USART_BaudRate = bound;//′&#174;&#191;ú2¨ì&#216;&#194;ê
        USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//ê&#213;/·¢&#196;£ê&#189;
        USART_InitStruct.USART_Parity = USART_Parity_No;//&#206;T&#198;&#230;&#197;&#188;D£&#209;é&#206;&#187;
        USART_InitStruct.USART_StopBits = USART_StopBits_1;//ò&#187;&#184;&#246;í£&#214;1&#206;&#187;
        USART_InitStruct.USART_WordLength = USART_WordLength_8b;//8&#206;&#187;êy&#190;Y3¤&#182;è
        USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//&#206;Tó2&#188;tá÷&#191;&#216;&#214;&#198;
        USART_Init(USART1,&USART_InitStruct);//3&#245;ê&#188;&#187;ˉ′&#174;&#191;ú4
       
        USART_Cmd(USART1,ENABLE);//ê1&#196;ü′&#174;&#191;ú4
}
下面是DMA配置:
void UART4_DMATX_Init(u32 cpar,u32 cmar,u16 cndtr)
{
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);        //ê1&#196;üDMA2′&#171;ê&#228;
       
        DMA_DeInit(DMA2_Channel5);//&#189;&#171;DMA2μ&#196;í¨μà5&#188;&#196;′&#230;&#198;÷&#214;&#216;éè&#206;aè±ê&#161;&#214;μ
       
        DMA1_MEM_LEN = cndtr;
        DMA_InitStructure.DMA_BufferSize = cndtr;//DMAí¨μà′&#171;ê&#228;μ&#196;êy&#190;Yá&#191;
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//êy&#190;Y′&#171;ê&#228;·&#189;&#207;ò£&#172;′ó&#196;ú′&#230;μ&#189;íaéè
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//2&#187;&#191;a&#198;&#244;&#196;ú′&#230;μ&#189;&#196;ú′&#230;′&#171;ê&#228;
        DMA_InitStructure.DMA_MemoryBaseAddr = cmar;//DMA&#196;ú′&#230;&#187;ùμ&#216;&#214;·
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//êy&#190;Y&#191;í&#182;è&#206;a8&#206;&#187;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//&#196;ú′&#230;μ&#216;&#214;·&#188;&#196;′&#230;&#198;÷μY&#212;&#246;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//1¤×÷&#212;ú&#213;y3£&#196;£ê&#189;£&#172;2&#187;&#209;-&#187;·2é&#188;ˉêy&#190;Y
        DMA_InitStructure.DMA_PeripheralBaseAddr =cpar;//DMAíaéè&#187;ùμ&#216;&#214;·
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//êy&#190;Y&#191;í&#182;è&#206;a8&#206;&#187;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //íaéèμ&#216;&#214;·&#188;&#196;′&#230;&#198;÷2&#187;±&#228;
        DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//′&#203;DMAí¨μàóD×&#238;&#184;&#223;ó&#197;&#207;èè¨
        DMA_Init(DMA2_Channel5,&DMA_InitStructure);//3&#245;ê&#188;&#187;ˉDMA2í¨μà5£¨UART4_TX£&#169;
}
/*********************************************************************************
*********************************************************************************/
void USART1_DMARX_Init(u32 cpar,u32 cmar,u16 cndtr)
{
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);       
       
        DMA_DeInit(DMA1_Channel5);
       
        DMA1_MEM_LEN = cndtr;
        DMA_InitStructure.DMA_BufferSize = cndtr;
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
        DMA_InitStructure.DMA_MemoryBaseAddr = cmar;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
        DMA_InitStructure.DMA_PeripheralBaseAddr =cpar;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;
        DMA_Init(DMA1_Channel5,&DMA_InitStructure);
}
/******************************************************************************/
/******************************************************************************/
void UART4_DMA_Enable(void)
{
        DMA_Cmd(DMA2_Channel5,DISABLE);
        DMA_SetCurrDataCounter(DMA2_Channel5,1);
        USART_DMACmd(UART4,USART_DMAReq_Tx,ENABLE);
        DMA_Cmd(DMA2_Channel5,ENABLE);
}
/**********************************************************************************
**********************************************************************************/
void USART1_DMA_Enable(void)
{
        DMA_Cmd(DMA1_Channel5,DISABLE);
        DMA_SetCurrDataCounter(DMA1_Channel5,USART1_RECEIVE_MAX);
        ((DMA_Channel_TypeDef*)DMA1_Channel5)->CMAR=(u32)USART1_RECEIVE_BUF;
        USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
        DMA_Cmd(DMA1_Channel5,ENABLE);
}
回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2016-10-31
在线时间
18 小时
 楼主| 发表于 2016-12-31 16:09:58 | 显示全部楼层
请各位坛友帮忙看一下,这个问题搞了好长时间了。。
回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2016-10-31
在线时间
18 小时
 楼主| 发表于 2016-12-31 19:23:33 | 显示全部楼层
把程序下载后,需要每次按下复位键,可以正常在串口显示一次缓存中的数据
回复

使用道具 举报

0

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
137
金钱
137
注册时间
2016-12-25
在线时间
28 小时
发表于 2016-12-31 20:25:20 | 显示全部楼层
DMA_SetCurrDataCounter(DMA2_Channel5,1);
串口4的DMA只传递一个数据么?
回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2016-10-31
在线时间
18 小时
 楼主| 发表于 2016-12-31 21:03:32 | 显示全部楼层
qzl200 发表于 2016-12-31 20:25
DMA_SetCurrDataCounter(DMA2_Channel5,1);
串口4的DMA只传递一个数据么?

对的,串口4的DMA正常。主要是串口1的DMA接收有问题,每次需要按下复位键,程序可以正常执行一次(串口4正常显示一次缓存数据)
回复

使用道具 举报

6

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2016-10-31
在线时间
18 小时
 楼主| 发表于 2017-1-1 11:01:27 | 显示全部楼层
现在出现情况是:我开启USART1的接收中断,在USART1的接收中断中读USART1->DR,USART1的DMA接收正常,但是这违背了尽量不使用中断初衷,不知道是什么原因?还请各位知道原因的坛友帮忙看一下。
回复

使用道具 举报

2

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2017-12-20
在线时间
15 小时
发表于 2017-12-21 00:12:02 | 显示全部楼层
请问,这个问题解决了吗?我也遇到了这个问题
回复

使用道具 举报

2

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2017-12-20
在线时间
15 小时
发表于 2017-12-21 09:41:43 | 显示全部楼层
穆义 发表于 2016-12-31 19:23
把程序下载后,需要每次按下复位键,可以正常在串口显示一次缓存中的数据

请问,该问题解决了吗,我也遇到了,太烦了!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-14 15:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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