你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32l051 adc怎么改cubemx配置都不准

[复制链接]
猎★奇士 提问时间:2018-2-8 09:20 /
本帖最后由 猎★奇士 于 2018-2-8 14:07 编辑

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

关键代码:
  1. void MX_ADC_Init(void)
  2. {
  3.   ADC_ChannelConfTypeDef sConfig;

  4.   hadc.Instance = ADC1;
  5.   hadc.Init.OversamplingMode = DISABLE;
  6.   hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  7.   hadc.Init.Resolution = ADC_RESOLUTION_12B;
  8.   hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
  9.   hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  10.   hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  11.   hadc.Init.ContinuousConvMode = DISABLE;
  12.   hadc.Init.DiscontinuousConvMode = ENABLE;
  13.   hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  14.   hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  15.   hadc.Init.DMAContinuousRequests = DISABLE;
  16.   hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  17.   hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  18.   hadc.Init.LowPowerAutoWait = DISABLE;
  19.   hadc.Init.LowPowerFrequencyMode = DISABLE;
  20.   hadc.Init.LowPowerAutoPowerOff = DISABLE;
  21.   if (HAL_ADC_Init(&hadc) != HAL_OK)
  22.   {
  23.     Error_Handler();
  24.   }

  25.   sConfig.Channel = ADC_CHANNEL_9;
  26.   sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  27.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  28.   {
  29.     Error_Handler();
  30.   }

  31.   sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  32.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  33.   {
  34.     Error_Handler();
  35.   }
  36. }



  37. #define TEMP130_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007E))
  38. #define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007A))
  39. #define VDD_CALIB ((uint16_t) (300))
  40. #define VDD_APPLI ((uint16_t) (330))
  41. int32_t ComputeTemperature(uint32_t ADValue)
  42. {
  43.   int32_t temperature;
  44.   temperature = (((int32_t)(130 - 30)) * (ADValue - (int32_t)*TEMP30_CAL_ADDR)) / ((int32_t)(*TEMP130_CAL_ADDR - *TEMP30_CAL_ADDR));
  45.   temperature = temperature + 30;
  46.   return (temperature);
  47. }

  48. void ADC_GetValue()
  49. {
  50.         uint8_t i=0;
  51.         double VCC=3.3, BAT_VAL=0,CGVol_VAL=0,temperate=0;  
  52.         uint32_t VrefADvalue=0;
  53.         uint32_t temp=0,AD_Value_T=0,AD_Value_BAT=0;
  54.   
  55.         for(i=0;i<16;i++)                                                                  
  56.         {
  57.              HAL_ADC_Start(&hadc);                                                         
  58.              HAL_ADC_PollForConversion(&hadc, 50);                                          
  59.              if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC))
  60.              {
  61.                  temp = HAL_ADC_GetValue(&hadc);
  62.               }
  63.               AD_Value_BAT+=temp;
  64.               //printf("Bat_ADC9=%d V",temp);
  65.       
  66.                HAL_ADC_Start(&hadc);                                                            
  67.                HAL_ADC_PollForConversion(&hadc, 50);                                            
  68.                if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC))
  69.               {
  70.                   temp = HAL_ADC_GetValue(&hadc);
  71.               }
  72.               AD_Value_T+=temp;
  73.              //printf("Temperate=%d ¡æ",temp);
  74.               HAL_ADC_Stop(&hadc);   
  75.               HAL_Delay(100);     
  76.       }
  77.         AD_Value_T=AD_Value_T>>4;        
  78.         printf("AD_T%d \r\n",AD_Value_T);
  79.         AD_Value_BAT=AD_Value_BAT>>4;
  80.         printf("AD_V%d \r\n",AD_Value_BAT);
  81.   
  82.         //temperate=(float)AD_Value_T*(VCC/4096);                                                            
  83.         //temperate=( V30-temperate)/0.00161+30;                                   
  84.         temperate=ComputeTemperature(AD_Value_T);
  85.         printf("Temperate=%lf \r\n",temperate);
  86.    
  87.         BAT_VAL=VCC*4096/AD_Value_BAT;
  88.         printf("BAT_VAL=%lf V\r\n",BAT_VAL);     
  89. }
复制代码


test.zip

下载

543.84 KB, 下载次数: 29, 下载积分: ST金币 -1

评分

参与人数 1 ST金币 -5 收起 理由
Tcreat -5 连相关的电路也不配上 大神也是人 不是神~.

查看全部评分

收藏 评论15 发布时间:2018-2-8 09:20

举报

15个回答
dxx-381677 回答时间:2018-2-26 14:29:34
新年快乐。给朋友几个建议

1.L051  A/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脚了,内部温度传感器也不对,还有我程序的温度公式用下图的公式可以吗
电池分压.png
计算公式.png
Tcreat 回答时间:2018-2-8 09:54:38
如果说怀疑IO口被烧坏了  可以换个AD口测试下 但是不要轻易的怀疑芯片本身有问题 另外你的电池电压都达到3V+了 ,电池AD采样这块应该有相关的分压电路 请问你配套的电路呢 社区的大神是很多 但是毕竟都是人 不是神

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

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

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

Tcreat 回答时间:2018-2-8 10:54:18
本帖最后由 Tcreat 于 2018-2-8 10:56 编辑

首先你的代码肯定是有问题的,你既不是多通道采样 也不是MDA采样 那么你for循环里采集的AD数值始终是你配置的最后一个通道的AD值(也就是temp的值,并没有采集电池电压的值),并不是你想象的那样 先采集电池电压,然后再采集TEMP的~
1.jpg
猎★奇士 回答时间: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左右其中一个测试函数:
  1. void ADC_GetValue()
  2. {
  3.    uint8_t i=0;
  4.    double VCC=3.3, BAT_VAL=0,CGVol_VAL=0,temperate=0;  
  5.    uint32_t VrefADvalue=0;
  6.    uint32_t temp=0,AD_Value_T=0,AD_Value_BAT=0;
  7.    HAL_ADC_Start(&hadc);                                                         
  8.    HAL_ADC_PollForConversion(&hadc, 50);                                          
  9.    if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC))
  10.    {
  11.       temp = HAL_ADC_GetValue(&hadc);
  12.    }
  13.    AD_Value_BAT+=temp;
  14.    HAL_ADC_Stop(&hadc);
  15.    BAT_VAL=VCC*4096/AD_Value_BAT;
  16.    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内部温度传感器的大神说说,是不是像我这样配置、计算其温度
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版