8941|21

68

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

急问stm32串口使用dma接受的问题 [复制链接]

我是接受gps信息 一次接受500个 因为要接受一次处理一次 所有使用正常模式。
   但是我debug 只能接受一次的数据 我使用重新配置dma的方式 接受下一次  但是好像只是接受到一个字符 然后就像死机一样  再怎么运行 也接受不到数据  
   请香主 告知怎么 任意再次开启dma接受


太急了
此帖出自stm32/stm8论坛

最新回复

                                 还有个问题 请看 while (1)   {    #if 1                 if(!DMA_GetFlagStatus(DMA1_FLAG_TC5) == RESET)           {                  DMA_ClearFlag(DMA1_FLAG_TC5);                                                           GPIO_WriteBit(GPIOC, GPIO_Pin_6, (BitAction)((1-GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_6))));                         RestartUSART_DMA();                                            }                 #endif     for(time=0;time<0xfff;time++); } 在循环里 检测然后处理  那个延时代表别的函数  只要是别的函数运行的超过一定时间  也不能从新开启dma了   为什么啊  难道是在下一次之前不清楚标志位的话 会出现什么错误 请高手验证一下?  详情 回复 发表于 2009-9-17 23:57
点赞 关注
 

回复
举报

74

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
01:31发的贴啊啊 哈哈牛人!!

是这样的!!
你应该是没有仔细看文档。
文档中说的大概意思是需要重新初始化DMA的一个量(我忘记这个量是什么了,呵呵)
在中断中重新初始化这个量。

当然简单的方式是在中断里面对说有的DMA相关初始化都在中断里面重新初始化一遍。




          下面两句话是对那个量进行重新初始化的例子。(这是直接操作寄存器,大概不很直观哈哈 ,你看着办 (*^__^*) 嘻嘻……)
        (*((volatile unsigned long int *)0x40020064)) = (uint32_t)RxBuffer1;       
        (*((volatile unsigned long int *)0x4002005C)) = 30;
此帖出自stm32/stm8论坛
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
上面两句后面还得从新使能DMA。 别忘记啦!!!



===================================================
最简单的方法是将初始化DMA的代码复制粘贴到中断服务程序的末尾,就可以了!!!



希望能解决你的问题啊
此帖出自stm32/stm8论坛
 
 

回复

57

帖子

0

TA的资源

一粒金砂(初级)

4
 
                                 重新配置DMA之前必须先禁用DMA,修改CNT后再使能DMA。
此帖出自stm32/stm8论坛
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

5
 
我是这么做的 但是还是不行呢?
  大侠 能给个程序吗  必须要中断吗?
此帖出自stm32/stm8论坛
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

6
 
DMA_Cmd(pDmaRxChannel, DISABLE);

    DMA_DeInit(pDmaRxChannel);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(pUart->DR));
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)pRxAddr;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = rxLen;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

    DMA_Init(pDmaRxChannel, &DMA_InitStructure);

    USART_ClearFlag(pUart, USART_FLAG_RXNE);
    USART_DMACmd(pUart, USART_DMAReq_Rx, ENABLE);
    DMA_ITConfig(pDmaRxChannel, DMA_IT_TC, ENABLE);

    DMA_Cmd(pRxDmaChannel, ENABLE);
此帖出自stm32/stm8论坛
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

7
 
                                 另外为何一定要使用正常模式呢?循环模式应该更合适。
此帖出自stm32/stm8论坛
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

8
 
在我们去年的巡回研讨会上,专门就这个问题有解说,请下载演讲稿看看:

STM32F10x常见应用解析(2008年9月)
http://www.stmicroelectronics.com.cn/stonline/mcu/MCU_Pages.htm
此帖出自stm32/stm8论坛
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

9
 
                                 因为gps数据是一直发送过来的  要是循环模式 我接受完一次 在操作的时候  dma还在接受 不就把上次的覆盖了吗?
此帖出自stm32/stm8论坛
 
 
 

回复

23

帖子

0

TA的资源

一粒金砂(初级)

10
 
使用循环模式结合缓冲区半满中断,在半满时处理前面已经收到的数据,同时DMA会继续接收后续数据;当缓冲区全满中断时,再处理后半区的数据,此时DMA会继续接收数据并从缓冲区开头存储。

只要处理半区数据的时间,小于接收满半区数据的时间,就不会发生数据丢失的情况。
此帖出自stm32/stm8论坛
 
 
 

回复

92

帖子

0

TA的资源

纯净的硅(中级)

11
 
恩 这个确实一个方法 也想过 但是关键 我的程序不能即时的响应他的标志位  也可能他置位很长时间了 我还没运行到那段程序

下面是我的程序:
RCC_Configuration();
  NVIC_Configuration();
  GPIO_Configuration();
USART_Configuration();
   DMA_Configuration();
while (1)
  {
          if(!DMA_GetFlagStatus(DMA1_FLAG_TC5) == RESET        )
          {                  DMA_ClearFlag(DMA1_FLAG_TC5);
             DMA_Cmd(DMA1_Channel5, DISABLE);
                   (*((volatile unsigned long int *)0x40020064)) = (u32)RxBuffer1;        
        (*((volatile unsigned long int *)0x4002005C)) = 500;
                           DMA_Cmd(DMA1_Channel5, ENABLE);
                }
  }

while 里面是判断 一次500接受完成  然后这里我没处理 直接开启下次转换

问题:
  第一次转换完成后 执行里面的
    DMA_ClearFlag(DMA1_FLAG_TC5);
             DMA_Cmd(DMA1_Channel5, DISABLE);
                   (*((volatile unsigned long int *)0x40020064)) = (u32)RxBuffer1;        
        (*((volatile unsigned long int *)0x4002005C)) = 500;
                           DMA_Cmd(DMA1_Channel5, ENABLE);
来开启下一次 转换  但是这个时候只能接受一个字节 从此以后在接受不到  

????????????????
此帖出自stm32/stm8论坛
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

12
 
                                 还有就是 debug全速运行 如果此时硬件复位 他就会执行一次
此帖出自stm32/stm8论坛
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

13
 
                                 不介意的话把代码都放上来吧,我前阵子用过UART+DMA,中断里面开DMA,比你还复杂些
此帖出自stm32/stm8论坛
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

14
 
你的也是一直有数据过来吗?

void RCC_Configuration(void)
{
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();

  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);

    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
  
    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    /* Enable PLL */
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }
   
  /* DMA1 clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  /* Enable USART1, GPIOA, GPIOx and AFIO clocks */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

}
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

15
 
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;


  /* Configure USART1 Rx (PA.10) as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);


  
  /* Configure USART1 Tx (PA.09) as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  
}
此帖出自stm32/stm8论坛
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

16
 
void DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStructure;

  /* DMA1 Channel4 (triggered by USART1 Tx event) Config */
  DMA_DeInit(DMA1_Channel5);  
  DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)RxBuffer1;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = TxBufferSize2;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel5, &DMA_InitStructure);
           /* Enable DMA1 Channel5 */
  DMA_Cmd(DMA1_Channel5, ENABLE);
}
void USART_Configuration(void)
{         

USART_InitStructure.USART_BaudRate = 38400;
  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;
  
  /* Configure USART1 */
  USART_Init(USART1, &USART_InitStructure);
  /* Configure USART2 */


  /* Enable USART1 DMA Rx and TX request */
  USART_DMACmd(USART1, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE);
         USART_Cmd(USART1, ENABLE);
  }
此帖出自stm32/stm8论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

17
 
                                 lz的情况我没有复现
建议搞个LED翻转下,看看到底能不能正常收
此帖出自stm32/stm8论坛
 
 
 

回复

50

帖子

0

TA的资源

一粒金砂(初级)

18
 
                                 对啊 第一次是能收到 但是在打开dma  就接受不到了
此帖出自stm32/stm8论坛
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

19
 
                                 你debug  也能每次都收到?
此帖出自stm32/stm8论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

20
 
我的不是用的中断啊 你可以全速运行  然后停止 看看接受的数据 然后再全速运行 再停止 看看接受的数据
  是不是有变化   我这是没变化  设断点 也不是每次都运行到断点
此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表