打印
[STM32F0]

STM32F030 AD采样怎么每个通道是MCU供电电压值呢?

[复制链接]
6273|38
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
pmw_56|  楼主 | 2015-6-5 10:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32F030 AD采样怎么每个通道是MCU供电电压值呢?我用的MCU供电是3.0v,现在采样出来是3039 mV, 分别采样四个通道的AD值,都是一样的,是什么原因?有没有遇到的朋友



#define ADC1_DR_Address                0x40012440

__IO uint16_t ADC1ConvValue[4] = {0,0,0,0};



void ADC1_DMA_Init(void)
{
  ADC_InitTypeDef     ADC_InitStruct;
  DMA_InitTypeDef     DMA_InitStruct;
        GPIO_InitTypeDef    GPIO_InitStruct;
       
       
        /* ADC1 DeInit */  
  ADC_DeInit(ADC1);

        /* Enable  GPIOA clock */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
       
  /* ADC1 Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
       
  /* DMA1 clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);

  
        /* Configure PA.01  as analog input */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 ;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
        GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStruct);                               


  /* DMA1 Channel1 Config */
  DMA_DeInit( DMA1_Channel1 );
  DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
  DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvValue;
  DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStruct.DMA_BufferSize =4;
  DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStruct.DMA_Priority = DMA_Priority_High;
  DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStruct);

  
//   /* ADC DMA request in circular mode */
  ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);


  /* Enable ADC_DMA */
       
//  ADC_DMACmd(ADC1, ENABLE);


  
  /* Initialize ADC structure */
  ADC_StructInit(&ADC_InitStruct);
  
  /* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits  */
  ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStruct.ADC_ScanDirection = ADC_ScanDirection_Upward;
  ADC_Init(ADC1, &ADC_InitStruct);

//   /* Convert the ADC1 temperature sensor  with 55.5 Cycles as sampling time */
//   ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor , ADC_SampleTime_55_5Cycles);  
//   ADC_TempSensorCmd(ENABLE);
  
  /* Convert the ADC1 Vref  with 55.5 Cycles as sampling time */
  ADC_ChannelConfig(ADC1, ADC_Channel_0  , ADC_SampleTime_55_5Cycles);
        ADC_ChannelConfig(ADC1, ADC_Channel_1  , ADC_SampleTime_55_5Cycles);
        ADC_ChannelConfig(ADC1, ADC_Channel_2  , ADC_SampleTime_55_5Cycles);
        ADC_ChannelConfig(ADC1, ADC_Channel_2  , ADC_SampleTime_55_5Cycles);
       
       
//   ADC_VrefintCmd(ENABLE);
  
  /* ADC Calibration */
//  ADC_GetCalibrationFactor(ADC1);
       
//  ADC_DMACmd(ADC1, ENABLE);
       
  /* DMA1 Channel1 enable */
//  DMA_Cmd(DMA1_Channel1, ENABLE);
       
         /* Enable ADC1 */
//  ADC_Cmd(ADC1, ENABLE);   
  
  /* Wait the ADCEN falg */
//  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
  
  /* ADC1 regular Software Start Conv */
//  ADC_StartOfConversion(ADC1);
       
       
       
       
        /* ADC Calibration */
  ADC_GetCalibrationFactor(ADC1);
  
  /* ADC DMA request in circular mode */
  ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
       
        /* DMA1 Channel1 enable */
  DMA_Cmd(DMA1_Channel1, ENABLE);
  
  /* Enable ADC_DMA */
  ADC_DMACmd(ADC1, ENABLE);  


  
  /* Enable the ADC peripheral */
  ADC_Cmd(ADC1, ENABLE);     
  
  /* Wait the ADRDY flag */
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
  
  /* ADC1 regular Software Start Conv */
  ADC_StartOfConversion(ADC1);
       
       
}
//===========================================

while (1)
  {
               
                Free_WWDG();
               
                //-----------------------------------------
               
                key_scan();
               
                LED_ON();
       
                while((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET ) Free_WWDG();      
   
                /* Clear DMA TC flag */
    DMA_ClearFlag(DMA1_FLAG_TC1);
               
                batvolt_lsb = ADC1ConvValue[0];
                       
                Display(0,0,batvolt_lsb);
               
                batvolt_lsb = ADC1ConvValue[1];
               
                Display(40,0,batvolt_lsb);
               
                batvolt_lsb = ADC1ConvValue[2];
               
                Display(0,1,batvolt_lsb);
               
                batvolt_lsb = ADC1ConvValue[3];
               
                Display(40,1,batvolt_lsb);

}

主程序显示出来的是 3039       3039
                             3039       3039
沙发
mmuuss586| | 2015-6-5 12:40 | 只看该作者
对了下我的程序,没啥问题;

将IO引脚初始化搬到前面试下看看;

使用特权

评论回复
板凳
pmw_56|  楼主 | 2015-6-5 13:56 | 只看该作者
mmuuss586 发表于 2015-6-5 12:40
对了下我的程序,没啥问题;

将IO引脚初始化搬到前面试下看看;

把引脚初始化放到时钟使能前面,我也试了,所有采样的四个口都是MCU供电的电压值,3039mV

使用特权

评论回复
地板
行云_流水| | 2015-6-5 14:39 | 只看该作者
DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvValue;???

(uint32_t)&ADC1ConvValue  中间是 不是多了个 &?

使用特权

评论回复
5
pmw_56|  楼主 | 2015-6-5 14:55 | 只看该作者
行云_流水 发表于 2015-6-5 14:39
DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvValue;???

(uint32_t)&ADC1ConvValue  中间是  ...

我先在去掉了&取地址符也不行

使用特权

评论回复
6
行云_流水| | 2015-6-5 15:34 | 只看该作者
pmw_56 发表于 2015-6-5 14:55
我先在去掉了&取地址符也不行

更正一 下,看你 程序 处理,你 显示出来的 3039不是 3039 mv(不是你所说的 供电压值),3039是ADC采样的 数字 量,实际 对应地电压值是:(3039/4096)*3.0V

使用特权

评论回复
7
pmw_56|  楼主 | 2015-6-5 16:16 | 只看该作者
行云_流水 发表于 2015-6-5 15:34
更正一 下,看你 程序 处理,你 显示出来的 3039不是 3039 mv(不是你所说的 供电压值),3039是ADC采样的  ...

我转换过的,显示的就是电压值了:)

使用特权

评论回复
8
pmw_56|  楼主 | 2015-6-5 16:17 | 只看该作者
pmw_56 发表于 2015-6-5 16:16
我转换过的,显示的就是电压值了

ConvVolt = (uint16_t) (((batvolt_lsb * 3040 ) ) / 4096);

使用特权

评论回复
9
行云_流水| | 2015-6-5 16:25 | 只看该作者
pmw_56 发表于 2015-6-5 16:17
ConvVolt = (uint16_t) (((batvolt_lsb * 3040 ) ) / 4096);

发一个 我 自己写 的 DMA_ADC,板上验证过 可以 用的 :

__IO uint16_t ADC_ConvertedValue[3];


void GPIO_configure(void)
       
{

GPIO_InitTypeDef        GPIO_InitStructure;

  /* GPIOC Periph clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//ÉÏÀ­£¬ÏÂÀ­ ÉèÖÃ
  GPIO_Init(GPIOA, &GPIO_InitStructure);         


}


void  ADC_configure(void)
{
       
   ADC_InitTypeDef     ADC_InitStructure;
   ADC_DeInit(ADC1);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
       
  
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;

ADC_Init(ADC1, &ADC_InitStructure);
       

       



ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_55_5Cycles);

/* ADC Calibration */
ADC_GetCalibrationFactor(ADC1);

/* ADC DMA request in circular mode */
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
  
/* Enable ADC_DMA */
ADC_DMACmd(ADC1, ENABLE);  

/* Enable the ADC peripheral */
ADC_Cmd(ADC1, ENABLE);     

/* Wait the ADRDY flag */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));

/* ADC1 regular Software Start Conv */
ADC_StartOfConversion(ADC1);


}


void  DMA_configure(void)
{

   DMA_InitTypeDef   DMA_InitStructure;
   
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);


   DMA_DeInit(DMA1_Channel1);
   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
       
   DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue;
   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
       
   DMA_InitStructure.DMA_BufferSize = 3;
   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);
  
  DMA_Cmd(DMA1_Channel1, ENABLE);

}

使用特权

评论回复
10
pmw_56|  楼主 | 2015-6-5 17:01 | 只看该作者
行云_流水 发表于 2015-6-5 16:25
发一个 我 自己写 的 DMA_ADC,板上验证过 可以 用的 :

__IO uint16_t ADC_ConvertedValue[3];

我要采样4路AD呢?要怎么读取,能不能帮我分析呀?我上面的代码行不行

使用特权

评论回复
11
行云_流水| | 2015-6-5 17:08 | 只看该作者
pmw_56 发表于 2015-6-5 17:01
我要采样4路AD呢?要怎么读取,能不能帮我分析呀?我上面的代码行不行

你 要采样4路:

那 就 修改 一下以下几个参数 啊 ,
__IO uint16_t ADC_ConvertedValue[4];

DMA_InitStructure.DMA_BufferSize = 4;

还有这个

ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_55_5Cycles);

看你要用 哪几个 通道

使用特权

评论回复
12
行云_流水| | 2015-6-5 17:10 | 只看该作者
行云_流水 发表于 2015-6-5 17:08
你 要采样4路:

那 就 修改 一下以下几个参数 啊 ,

还有对应的 GPIO口也 要 修改为   GPIO_Mode_AN  模式

使用特权

评论回复
13
行云_流水| | 2015-6-5 17:11 | 只看该作者
行云_流水 发表于 2015-6-5 17:08
你 要采样4路:

那 就 修改 一下以下几个参数 啊 ,

有对应的 GPIO口也 要 修改为   GPIO_Mode_AN  模式

使用特权

评论回复
14
行云_流水| | 2015-6-5 17:11 | 只看该作者
pmw_56 发表于 2015-6-5 17:01
我要采样4路AD呢?要怎么读取,能不能帮我分析呀?我上面的代码行不行

有对应的 GPIO口也 要 修改为   GPIO_Mode_AN  模式

使用特权

评论回复
15
pmw_56|  楼主 | 2015-6-5 17:15 | 只看该作者
行云_流水 发表于 2015-6-5 17:11
有对应的 GPIO口也 要 修改为   GPIO_Mode_AN  模式

while (1)
  {
               
                Free_WWDG();
               
                //-----------------------------------------
               
                key_scan();
               
                LED_ON();
       
       
                if((DMA_GetFlagStatus(DMA1_FLAG_TC1)) != RESET )
                {
                       

                /* Clear DMA TC flag */
               
    DMA_ClearFlag(DMA1_FLAG_TC1);
               
               
               
                batvolt_lsb = ADC1ConvValue_Buf[0];
                       
                Display(0,0,batvolt_lsb);
               
               
                batvolt_lsb = ADC1ConvValue_Buf[1];
               
                Display(40,0,batvolt_lsb);
               
               
                batvolt_lsb = ADC1ConvValue_Buf[2];
               
                Display(0,1,batvolt_lsb);
               
               
                batvolt_lsb = ADC1ConvValue_Buf[3];
               
                Display(40,1,batvolt_lsb);
               
        }

}

使用特权

评论回复
16
pmw_56|  楼主 | 2015-6-5 17:17 | 只看该作者
pmw_56 发表于 2015-6-5 17:15
while (1)
  {
               

这样在主程序中读取,并显示行不行?实际上我现在用你的给那个代码试了,没有显示,也就是说没有DMA转换完成的标志位 DMA_FLAG_TC1

使用特权

评论回复
17
行云_流水| | 2015-6-5 17:19 | 只看该作者
给你个 建议:

(1)先按照我上面所说的 GPIO   ADC  DMA 的 配置方法进行 配置,(这个我子一个 项目上 验证过的)

(2)先对一个通道 进行 采样,看 结果是否对?不要 显示转换成 电压的 结果,直接显示采样 出来的 ADC数字 量,说不 定你 的 ADC数字量是 对的,换算处理 出错了

使用特权

评论回复
18
行云_流水| | 2015-6-5 17:23 | 只看该作者
pmw_56 发表于 2015-6-5 17:17
这样在主程序中读取,并显示行不行?实际上我现在用你的给那个代码试了,没有显示,也就是说没有DMA转换 ...

我 给 你 的 代码是 我 项目代码里面,对 GPIO    ADC    DMA配置的 部分

至于怎么读ADC值,你 可以按照 直接 思路 来 处理

(1)先按照我上面所说的 GPIO   ADC  DMA 的 配置方法进行 配置,(这个我子一个 项目上 验证过的)

(2)先对一个通道 进行 采样,看 结果是否对?不要 显示转换成 电压的 结果,直接显示采样 出来的 ADC数字 量,说不 定你 的 ADC数字量是 对的,换算处理 出错了

使用特权

评论回复
19
pmw_56|  楼主 | 2015-6-5 17:23 | 只看该作者
行云_流水 发表于 2015-6-5 17:19
给你个 建议:

(1)先按照我上面所说的 GPIO   ADC  DMA 的 配置方法进行 配置,(这个我子一个 项目上 验 ...

读取是直接在主程序中吗?
  if((DMA_GetFlagStatus(DMA1_FLAG_TC1)) != RESET )
   {
                       
                /* Clear DMA TC flag */
               
             DMA_ClearFlag(DMA1_FLAG_TC1);
            
               batvolt_lsb = ADC1ConvValue_Buf[0];
                        
               Display(0,0,batvolt_lsb);

}

使用特权

评论回复
20
pmw_56|  楼主 | 2015-6-5 17:24 | 只看该作者
pmw_56 发表于 2015-6-5 17:23
读取是直接在主程序中吗?
  if((DMA_GetFlagStatus(DMA1_FLAG_TC1)) != RESET )
   {

非常感谢你这位热心的朋友!我搞这个AD采样几天了,一直没有解决

使用特权

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

本版积分规则

34

主题

215

帖子

1

粉丝