打印

STM32的DMA有没有这个功能?

[复制链接]
3179|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mxinfa|  楼主 | 2009-8-9 21:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用在ADC上,一个通道即可,我是想这样,stm32在干别的事,DMA接收AD的数据,接收到一定的数量比如1K,stm32读回来做处理,然后dma继续接收,如有这个功能求个程序,谢谢
感觉应该有这个功能,好像不少ARM都有,折腾一下午没成功,adc用9M的时钟,239.5的转换时间,每次1K的数量,转换35次我串口打出点东西,计算好的
(239.5+12.5)*1024*35应该基本是每秒输出一次东西,却发现速度明显快很多,下面是我用的代码,代码比较山寨,全是照着书上或网上改的

    /* DMA channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADValuetest;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 1024;
  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_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);

     
  /* ADC1 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
  /* ADC1 regular channel1 configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);
  
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);   

  /* Enable ADC1 reset calibaration register */   
  ADC_ResetCalibration(ADC1);
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));
  /* Start ADC1 calibaration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));
   /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    /* Enable DMA channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);
while(1)
  {
  for(i=0;i<35;i++)
  {
  while(DMA_GetCurrDataCounter(DMA1_Channel1)<1024);
  CurrDataCounter=0;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  }
   printf("\r\n USART1   \r\n");  
  }
沙发
香水城| | 2009-8-9 21:03 | 只看该作者
可以实现。

使用DMA的循环模式既可实现“dma继续接收

使用特权

评论回复
板凳
mxinfa|  楼主 | 2009-8-9 21:10 | 只看该作者
谢谢,上面代码已经设置循环模式了,为了保险每次收到1K数据以后我还重新初始化,能循环收到1K字节的数据,我的判断感觉数据基本也是正确的,但感觉速度不对;我用直接读的方式,读多少次大约1秒钟是很准的

使用特权

评论回复
地板
香水城| | 2009-8-9 21:27 | 只看该作者
发现速度明显快很多”,有多快?

adc用9M的时钟”,这个设置正确吗?

使用特权

评论回复
5
mxinfa|  楼主 | 2009-8-9 22:30 | 只看该作者
快非常多,眼睛反应不过来;9M的时钟应该是正确的,用直接读的方式,读多少次大约1秒钟是很准的
    /* PLLCLK = 12MHz * 6 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_6);
    RCC_HCLKConfig(RCC_SYSCLK_Div1);   
    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);
    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);
    /* ADCCLK = PCLK2/8 */
    RCC_ADCCLKConfig(RCC_PCLK2_Div8);

使用特权

评论回复
6
rasar| | 2009-8-10 08:48 | 只看该作者
路过

使用特权

评论回复
7
香水城| | 2009-8-10 10:55 | 只看该作者
本帖最后由 香水城 于 2009-8-10 10:56 编辑

这样的话,你可以检查一下239.5这个参数设置是否正确,最好看看对应的寄存器。

另外,你的串口速度多少?每次送出多少字符?你最好算一下这些字符,在这样的速度下需要多少时间送完,是否有可能显示较慢,上次显示刚结束,下次显示又来了,给你造成错觉。为了避免这样的错觉,建议不要用串口,直接翻转一个I/O口,再用示波器测量,人的感觉是不准确的。

使用特权

评论回复
8
ST_ARM| | 2009-8-10 11:06 | 只看该作者
你每次输出的数据的个数是:1024×35吗?

使用特权

评论回复
9
mxinfa|  楼主 | 2009-8-10 12:47 | 只看该作者
输出数据连回车换行什么的都算上是28个字符,输出数据主要是太快了,远大于一秒钟一次感觉,连眼睛都反应不过来;我个人认为还是设置的问题,就是自己水平实在有限,只能在已有的这些语句上修修补补,不敢做大的改动

使用特权

评论回复
10
香水城| | 2009-8-10 14:17 | 只看该作者
还是那句话,你最好能够给出一个具体的数字,到底有多快?

使用特权

评论回复
11
香水城| | 2009-8-10 21:32 | 只看该作者
请按照我在7楼的建议:检查一下239.5这个参数设置是否正确,最好看看对应的寄存器。

在调试器的寄存器窗口直接看ADC_SMPR1或ADC_SMPR2的内容。

使用特权

评论回复
12
香水城| | 2009-8-10 21:41 | 只看该作者
如果快了大约17.4倍,很可能是采样时间设置错误。

(239.5+12.5)/(1.5+12.5) = 18,这个数刚好接近17.4,所以非常怀疑你的参数设置不对。

回头看你的初始化:ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
这里参数表示是CH1,请问你的ADC通道是CH1吗?

使用特权

评论回复
13
mxinfa|  楼主 | 2009-8-10 22:30 | 只看该作者
本帖最后由 mxinfa 于 2009-8-10 22:32 编辑

通道1没错,智林的开发板,在通道1上接了个电位器,因为采样值是准确的
不知道怎么传图片

使用特权

评论回复
14
mxinfa|  楼主 | 2009-8-17 11:22 | 只看该作者
问题还是没有解决
测试了几组数据没有发现规律,均是1分钟
9M   239.5时钟 123帧 两次
18M 239.5时钟 131帧 两次
18M 1.5时钟    213帧 一次
18M 7.5时钟    150帧 一次
以上均是28字节的帧,担心串口影响,用8字节的帧试了一下
9M   1.5时钟    199帧 一次
9M   239.5时钟 123帧 一次
18M     1.5时钟 214帧 一次
以上测试均是DMA读取1024个AD转换的数据350次,然后串口打印一帧
使用MDK环境,不知道为什么仿真的时候reg窗口能查看的寄存器特别少,找不到香水说的ADC_SMPR1或ADC_SMPR2,按照库手册尝试改了不少地方没有解决问题。采样值一直正确

使用特权

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

本版积分规则

33

主题

198

帖子

1

粉丝