OpenEdv-开源电子网

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

STM32F0 DMA采样多路ADC只能采到初始值问题

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
9
金钱
9
注册时间
2019-12-9
在线时间
2 小时
发表于 2019-12-20 17:40:11 | 显示全部楼层 |阅读模式
1金钱
做了个DMA ADC采样的一个案子,采集十路ADC的电压值  ,STM32F0
调试的时候发现10路ADC的值只采样了一次,DMA 的ADC变量就一直不更新了。。。(主循环里不更新)
不得已没办法解,我就在主循环里加上了:ADC_StartOfConversion(ADC1);调试是可以更新的
while(1)
{
...
ADC_StartOfConversion(ADC1);

...
}
但是我个人理解的是在ADC初始化里ADC_StartOfConversion(ADC1);这个语句应该启用后就开始连续模式更新我定义的AD Value变量才对。
请教下高手还有其他方法吗,直接初始化完了就能实时的更新ADC采样值到DMA变量数组里?

附上我初始化函数:(DMA,ADC1)
-----------------------------------------------------------------分割线---------------------------------------------------------------------

volatile uint16_t ADCConvertedValue[10][10]; // READ 10 TIMES for each ADC_INx

void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;  
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);   // ENABLE CLOCK

  DMA_DeInit(DMA1_Channel1);   // channel-1 register as default value
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);  //define peripheral BaseAddr to ADC1-DR  
                                                                   //&(ADC1->DR) :add of struct SP
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue; // DMA add of ADC ConvertedValue                                                                 //&(ADC1->DR)  addr of <struct SP>
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // Peripheral is purpose or src ? this's src
DMA_InitStructure.DMA_BufferSize = 10*10;    // DMA Channel BuffSize
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  // Peripheral register addr inc?
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Memory register addr inc?
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // DataSize is 16bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // DataSize is 16bit
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // operating mode is a loop buff
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // priority level
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// DMA mem to mem
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  
//DMA_Cmd(DMA1_Channel1, DISABLE);
}

void ADC_Config(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = (uint16_t)0x00ff;    // PA0~PA7   fixed 32bit for compile
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  ADC_InitTypeDef ADC_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_AHBPeriph_GPIOA,ENABLE);
  RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
  //ADC_DeInit(ADC1);
  //ADC_StructInit(&ADC_InitStructure);
  
  
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;  // 12bit ppi
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // High bit maybe reserved
  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
  ADC_Init(ADC1,&ADC_InitStructure);
  
  ADC_ChannelConfig(ADC1,ADC_Channel_0,ADC_SampleTime_239_5Cycles);
  ADC_ChannelConfig(ADC1,ADC_Channel_1,ADC_SampleTime_239_5Cycles);
  ADC_ChannelConfig(ADC1,ADC_Channel_2,ADC_SampleTime_239_5Cycles);
  ADC_ChannelConfig(ADC1,ADC_Channel_3,ADC_SampleTime_239_5Cycles);
  ADC_ChannelConfig(ADC1,ADC_Channel_4,ADC_SampleTime_239_5Cycles);
  ADC_ChannelConfig(ADC1,ADC_Channel_5,ADC_SampleTime_239_5Cycles);
  ADC_ChannelConfig(ADC1,ADC_Channel_6,ADC_SampleTime_239_5Cycles);
  ADC_ChannelConfig(ADC1,ADC_Channel_7,ADC_SampleTime_239_5Cycles);
  ADC_ChannelConfig(ADC1,ADC_Channel_8,ADC_SampleTime_239_5Cycles);
  ADC_ChannelConfig(ADC1,ADC_Channel_9,ADC_SampleTime_239_5Cycles);
  
  ADC_GetCalibrationFactor(ADC1);   // must be placed in front of 'ADC_DMACmd(ADC1, ENABLE);'
  ADC_DMACmd(ADC1, ENABLE); //enable ADC-DMA support
  //ADC_GetCalibrationFactor(ADC1);
  ADC_Cmd(ADC1, ENABLE);   //enable ADC1
  
  
  while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_ADRDY));  // Waiting for ADC be ready
  DMA_Cmd(DMA1_Channel1, ENABLE);
  ADC_StartOfConversion(ADC1);
  }

最佳答案

查看完整内容[请看2#楼]

初始化历程如下:你看一下 BOOL ADC_bInit( void ) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // ENABLE CLOCK DMA_DeInit(DMA1_Channel1); // channel-1 register as default value DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR); //define peripher ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2017-4-24
在线时间
45 小时
发表于 2019-12-20 17:40:12 | 显示全部楼层
初始化历程如下:你看一下
BOOL ADC_bInit( void )
{       
       
ADC_InitTypeDef ADC_InitStructure;
   GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;  
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);   // ENABLE CLOCK

  DMA_DeInit(DMA1_Channel1);   // channel-1 register as default value
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);  //define peripheral BaseAddr to ADC1-DR  
                                                                   //&(ADC1->DR) :add of struct SP
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&u16AD_Value; // DMA add of ADC ConvertedValue                                                                 //&(ADC1->DR)  addr of <struct SP>
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // Peripheral is purpose or src ? this's src
DMA_InitStructure.DMA_BufferSize = 1;    // DMA Channel BuffSize
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  // Peripheral register addr inc?
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Memory register addr inc?
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // DataSize is 16bit
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // DataSize is 16bit
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // operating mode is a loop buff
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // priority level
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// DMA mem to mem
DMA_Init(DMA1_Channel1, &DMA_InitStructure);  
//DMA_Cmd(DMA1_Channel1, DISABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;    // PA0~PA7   fixed 32bit for compile
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_AHBPeriph_GPIOA,ENABLE);
  RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);

  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;  // 12bit ppi
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // High bit maybe reserved
  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
  ADC_Init(ADC1,&ADC_InitStructure);
  ADC_ChannelConfig(ADC1,ADC_Channel_4,ADC_SampleTime_239_5Cycles);

  ADC_GetCalibrationFactor(ADC1);   // must be placed in front of 'ADC_DMACmd(ADC1, ENABLE);'
  ADC_DMACmd(ADC1, ENABLE); //enable ADC-DMA support
  //ADC_GetCalibrationFactor(ADC1);
  ADC_Cmd(ADC1, ENABLE);   //enable ADC1
   /* ADC DMA request in circular mode */
  ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
  
  while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_ADRDY));  // Waiting for ADC be ready
  DMA_Cmd(DMA1_Channel1, ENABLE);
       
  ADC_StartOfConversion(ADC1);
  
//          ADC1_GPIO_Config();
//          ADC1_Mode_Config();
        return TRUE;
}这样在main函数就不用再写ADC_StartOfConversion(ADC1);这句话了,我已验证,我用的单片机是STM32F042G6U6
回复

使用道具 举报

13

主题

264

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5348
金钱
5348
注册时间
2017-8-14
在线时间
239 小时
发表于 2019-12-24 22:43:35 | 显示全部楼层
可参考我们的 程序2路ADC  示例:
HAL_1CANWeb_STMF103RCT6源程序191224.rar (1.08 MB, 下载次数: 47)
详细资料扣扣群204408503自行下载
回复

使用道具 举报

0

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2017-4-24
在线时间
45 小时
发表于 2020-1-16 12:55:22 | 显示全部楼层
你好,你初始化少了一句话。   /* ADC DMA request in circular mode */
  ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
回复

使用道具 举报

7

主题

46

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
400
金钱
400
注册时间
2019-7-4
在线时间
89 小时
发表于 2022-6-15 10:34:51 | 显示全部楼层
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_AHBPeriph_GPIOA,ENABLE);这句,其中GPIOA时钟定义错了吧
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-27 00:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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