猎★奇士 发表于 2018-2-8 09:20:42

stm32l051 adc怎么改cubemx配置都不准

本帖最后由 猎★奇士 于 2018-2-8 14:07 编辑

    l051c8t6通过adc测量芯片内部温度传感器和外部电池电压不准,电池电压本来是3.6V的,现在却有7V,温度也是230多℃,相似cubemx配置的ADC采样在stm32f103板子上没问题。而l0不断更改配置cubemx,连DMA都试了,还是错的!只有配置过采样模式电压降过3.8,但降实际电池电压(模拟的)改成3.5V,采集到的电压又升4.2V了,所以有什么可能原因和解决方法?
cubemx配置和测试工程我发上来,大家看看是我配置有问题还是芯片有问题,感激不尽。

关键代码:
void MX_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig;

hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = ENABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
    Error_Handler();
}

sConfig.Channel = ADC_CHANNEL_9;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
    Error_Handler();
}

sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
    Error_Handler();
}
}



#define TEMP130_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007E))
#define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007A))
#define VDD_CALIB ((uint16_t) (300))
#define VDD_APPLI ((uint16_t) (330))
int32_t ComputeTemperature(uint32_t ADValue)
{
int32_t temperature;
temperature = (((int32_t)(130 - 30)) * (ADValue - (int32_t)*TEMP30_CAL_ADDR)) / ((int32_t)(*TEMP130_CAL_ADDR - *TEMP30_CAL_ADDR));
temperature = temperature + 30;
return (temperature);
}

void ADC_GetValue()
{
      uint8_t i=0;
      double VCC=3.3, BAT_VAL=0,CGVol_VAL=0,temperate=0;
      uint32_t VrefADvalue=0;
      uint32_t temp=0,AD_Value_T=0,AD_Value_BAT=0;

      for(i=0;i<16;i++)                                                                  
      {
             HAL_ADC_Start(&hadc);                                                         
             HAL_ADC_PollForConversion(&hadc, 50);                                          
             if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC))
             {
               temp = HAL_ADC_GetValue(&hadc);
            }
            AD_Value_BAT+=temp;
            //printf("Bat_ADC9=%d V",temp);
      
               HAL_ADC_Start(&hadc);                                                            
               HAL_ADC_PollForConversion(&hadc, 50);                                          
               if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC))
            {
                  temp = HAL_ADC_GetValue(&hadc);
            }
            AD_Value_T+=temp;
             //printf("Temperate=%d ¡æ",temp);
            HAL_ADC_Stop(&hadc);   
            HAL_Delay(100);   
      }
      AD_Value_T=AD_Value_T>>4;      
      printf("AD_T%d \r\n",AD_Value_T);
      AD_Value_BAT=AD_Value_BAT>>4;
      printf("AD_V%d \r\n",AD_Value_BAT);

      //temperate=(float)AD_Value_T*(VCC/4096);                                                            
      //temperate=( V30-temperate)/0.00161+30;                                 
      temperate=ComputeTemperature(AD_Value_T);
      printf("Temperate=%lf \r\n",temperate);
   
      BAT_VAL=VCC*4096/AD_Value_BAT;
      printf("BAT_VAL=%lf V\r\n",BAT_VAL);   
}

dxx-381677 发表于 2018-2-26 14:29:34

新年快乐。给朋友几个建议

1.L051A/D的输入阻抗我记得跟速度是有关系的,速度越慢,输入阻抗越大。我看你分压电阻是兆欧级的,而输入阻抗估计只有50K欧左右,你快速的连续采集必然会使得电压不准;那么你采样的时候,全靠104电容放电维持AD的输入采集。你如果采集多次,每次采集的电压会越来越低。建议你2,3秒最好只采一次,不要连续采很多次取平均值。同理DMA也是行不通的。
关于STM32F1系列,AD的最大输入阻抗在300K欧左右,效果要好点,但依然存在这个问题。
2.关于内部的温度。同样的道理,我记得手册上有提到。切换到测量温度通道后,需要保持一段时间,让电平稳定,然后采集一次就可以了,否则采集的电压依然会越来越低。

更具体的数据,请参考芯片手册了。

猎★奇士 发表于 2018-2-8 10:21:44

本帖最后由 猎★奇士 于 2018-2-8 10:23 编辑

电池分压图片已上传,上面写5V,但我接了直流电流源的3.6V,1A,也没别的ADC脚了,内部温度传感器也不对,还有我程序的温度公式用下图的公式可以吗

Tcreat 发表于 2018-2-8 09:54:38

如果说怀疑IO口被烧坏了可以换个AD口测试下 但是不要轻易的怀疑芯片本身有问题 另外你的电池电压都达到3V+了 ,电池AD采样这块应该有相关的分压电路 请问你配套的电路呢 社区的大神是很多 但是毕竟都是人 不是神

feixiang20 发表于 2018-2-8 10:27:31

你可以先换个芯片看看结果是否仍旧,测试一下原来的芯片在资料中各个脚位数据是否正确,至于程序相信都是原版设计,你把你修改的地方重新检查, 还是建议一部分一部分的去检查。至于分压电路,你可以先计算理论上的数据,再测量实际的数据做对比,然后调节参数来检测问题。

Tcreat 发表于 2018-2-8 10:54:18

本帖最后由 Tcreat 于 2018-2-8 10:56 编辑

首先你的代码肯定是有问题的,你既不是多通道采样 也不是MDA采样 那么你for循环里采集的AD数值始终是你配置的最后一个通道的AD值(也就是temp的值,并没有采集电池电压的值),并不是你想象的那样 先采集电池电压,然后再采集TEMP的~

猎★奇士 发表于 2018-2-8 11:19:19

本帖最后由 Tcreat 于 2018-2-8 11:41 编辑

Tcreat 发表于 2018-2-8 10:54
首先你的代码肯定是有问题的,你既不是多通道采样 也不是MDA采样 那么你for循环里采集的AD数值始终是你配置 ...
   谢谢版主的回复,但我配置的是多通道非DMA断续采集模式,每次启动采集只是采集一个通道,之前在f103c8t6上都能得到各自的值。然后刚才我又试了单独测试一个通道,结果还是一样的7.78多V,内部温度和外部电池电压都单独测了,电压AD值=1736左右,内部温度AD值=580左右其中一个测试函数:
void ADC_GetValue()
{
   uint8_t i=0;
   double VCC=3.3, BAT_VAL=0,CGVol_VAL=0,temperate=0;
   uint32_t VrefADvalue=0;
   uint32_t temp=0,AD_Value_T=0,AD_Value_BAT=0;
   HAL_ADC_Start(&hadc);                                                         
   HAL_ADC_PollForConversion(&hadc, 50);                                          
   if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC))
   {
      temp = HAL_ADC_GetValue(&hadc);
   }
   AD_Value_BAT+=temp;
   HAL_ADC_Stop(&hadc);
   BAT_VAL=VCC*4096/AD_Value_BAT;
   printf("BAT_VAL=%lf V\r\n",BAT_VAL);       //3.6V

猎★奇士 发表于 2018-2-8 11:21:22

其实DMA我也是试过的,得到的AD值也是一样,我现在也摸不着头脑,不知道哪里有问题,多余的板子目前也没有没法换着测。

Tcreat 发表于 2018-2-8 11:41:26

猎★奇士 发表于 2018-2-8 11:19
谢谢版主的回复,但我配置的是多通道非DMA断续采集模式,每次启动采集只是采集一个通道,之前在f103c8t ...

电池AD 1736左右 根据你的电阻分压关系 得到的电压值 在3.8V 差别不是很大的呀

猎★奇士 发表于 2018-2-8 12:00:28

Tcreat 发表于 2018-2-8 11:41
电池AD 1736左右 根据你的电阻分压关系 得到的电压值 在3.8V 差别不是很大的呀...

是这样的,我用过采样模式oversampling mode配置,得到电池电压AD=3470,根据我程序的计算公式得到的是3.89V,但关掉过采样,采集的电压AD就是1736,计算却得到7V+,肯定不对,难道是我计算公式错了?这是12bit采样时的计算式啊,基准电压就是VDD稳定=3.3V。

猎★奇士 发表于 2018-2-8 12:03:02

还有内部温度按理说跟外部电路没关系,也不准就不知道怎么回事了,我温度的计算公式是根据l0完全手册上写的编的程序,不知道有没有用过l0内部温度传感器的大神说说,是不是像我这样配置、计算其温度
页: [1] 2
查看完整版本: stm32l051 adc怎么改cubemx配置都不准