查看: 4956|回复: 4

ADC 内部温度通道 采样不准确

[复制链接]

41

主题

59

帖子

485

积分

高级工程师

Rank: 3Rank: 3

积分
485
发表于 2023-2-25 15:55:30 | 显示全部楼层 |阅读模式
adc 通道14 采样正常,内部温度采样输出不正确,仿真的时候看,每次获取的采样值差别就很大,使用查询方式的时候就正常,是温度只能用查询的方式获取吗???

  1. /**
  2.   * @brief  ADC_Common Initialization function
  3.   * @param  void
  4.   * @retval None
  5.   */
  6. void MF_ADC_Common_Init(void)
  7. {
  8.     FL_ADC_CommonInitTypeDef    Common_InitStruct;

  9.     Common_InitStruct.clockSource = FL_CMU_ADC_CLK_SOURCE_RCHF;
  10.     Common_InitStruct.clockPrescaler = FL_ADC_CLK_PSC_DIV8;
  11.     Common_InitStruct.referenceSource = FL_ADC_REF_SOURCE_VDDA;
  12.     Common_InitStruct.bitWidth = FL_ADC_BIT_WIDTH_12B;

  13.     FL_ADC_CommonInit(&Common_InitStruct);   
  14. }
复制代码
  1. /**
  2.   * @brief  ADC_Sampling Initialization function
  3.   * @param  void
  4.   * @retval None
  5.   */
  6. void MF_ADC_Sampling_Init(void)
  7. {
  8.     FL_GPIO_InitTypeDef    GPIO_InitStruct;

  9.     FL_ADC_InitTypeDef    Sampling_InitStruct;

  10.     /* PC9 ADC_IN14 */
  11.     GPIO_InitStruct.pin = FL_GPIO_PIN_9;
  12.     GPIO_InitStruct.mode = FL_GPIO_MODE_ANALOG;
  13.     GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
  14.     GPIO_InitStruct.pull = FL_DISABLE;
  15.     GPIO_InitStruct.remapPin = NULL;
  16.     GPIO_InitStruct.analogSwitch = FL_DISABLE;
  17.     FL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  18.     Sampling_InitStruct.conversionMode = FL_ADC_CONV_MODE_SINGLE;
  19.     Sampling_InitStruct.autoMode = FL_ADC_SINGLE_CONV_MODE_AUTO;
  20.     Sampling_InitStruct.waitMode = FL_ENABLE;
  21.     Sampling_InitStruct.overrunMode = FL_ENABLE;
  22.     Sampling_InitStruct.scanDirection = FL_ADC_SEQ_SCAN_DIR_FORWARD;
  23.     Sampling_InitStruct.externalTrigConv = FL_ADC_TRIGGER_EDGE_NONE;
  24.     Sampling_InitStruct.triggerSource = FL_DISABLE;
  25.     Sampling_InitStruct.fastChannelTime = FL_ADC_FAST_CH_SAMPLING_TIME_2_ADCCLK;
  26.     Sampling_InitStruct.lowChannelTime = FL_ADC_SLOW_CH_SAMPLING_TIME_512_ADCCLK;
  27.     Sampling_InitStruct.oversamplingMode = FL_ENABLE;
  28.     Sampling_InitStruct.overSampingMultiplier = FL_ADC_OVERSAMPLING_MUL_16X;
  29.     Sampling_InitStruct.oversamplingShift = FL_ADC_OVERSAMPLING_SHIFT_4B;

  30.     FL_ADC_Init(ADC, &Sampling_InitStruct);

  31.     FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_TS);

  32.     FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_VREF1P2);

  33.     // FL_ADC_EnableSequencerChannel(ADC, FL_ADC_EXTERNAL_CH14);   
  34. }
复制代码


  1. /**
  2.   * @brief  ADC Interrupt Initialization function
  3.   * @param  void
  4.   * @retval None
  5.   */
  6. void MF_ADC_Interrupt_Init(void)
  7. {
  8.     FL_ADC_ClearFlag_EndOfConversion(ADC);
  9.     FL_ADC_EnableIT_EndOfConversion(ADC);  
  10. }
  11. /**
  12. * @brief  NVIC Initialization function
  13. * @param  void
  14. * @retval None
  15. */
  16. static void MF_NVIC_Init(void)
  17. {
  18.     FL_NVIC_ConfigTypeDef InterruptConfigStruct;

  19.     InterruptConfigStruct.preemptPriority = 0x2; /*配置中断优先级*/
  20.     FL_NVIC_Init(&InterruptConfigStruct, ADC_IRQn);
  21. }
复制代码
  1. uint32_t GetSingleChannelVoltage_IT(void)
  2. {
  3.     uint32_t GetChannelVoltage = 0;

  4.     if(VREF1P2ChannelSample != 0)
  5.     {
  6.         GetChannelVoltage = (uint32_t)(((uint64_t)ExChannelSample * 3000 * (ADC_VREF)) / ((uint64_t)VREF1P2ChannelSample * 4095));
  7.     }

  8.     // 转换结果
  9.     return GetChannelVoltage;
  10. }

  11. float GetTS_IT(void)
  12. {
  13.     uint32_t VPTAT = 0, VPTAT_30 = 0;
  14.     float GetTS = 0.00f;

  15.     if(VREF1P2ChannelSample != 0)
  16.     {
  17.         VPTAT = (uint32_t)(((uint64_t)GetTSChannelSample * 3000 * (ADC_VREF)) / ((uint64_t)VREF1P2ChannelSample * 4095));
  18.         VPTAT_30 = ((uint32_t)ADC_TS * 3000) / (4095);
  19.         GetTS = ((float)VPTAT - (float)VPTAT_30) / (2.6f) + (30.0f);
  20.     }
  21.     // 转换结果
  22.     return GetTS;
  23. }
复制代码




回复

使用道具 举报

3

主题

10

帖子

51

积分

中级工程师

Rank: 2

积分
51
发表于 2024-6-28 16:48:13 | 显示全部楼层
请问一下,这个问题的原因找到了吗,大佬;我也遇到了同样的问题,ADC外部通道采样挺准的,使用ADC内部温度采样(ADC单端+中断)无法采集到一个稳定的值
回复

使用道具 举报

3

主题

10

帖子

51

积分

中级工程师

Rank: 2

积分
51
发表于 2024-6-28 16:49:47 | 显示全部楼层
大佬,问一下,原因找到了吗,我使用ADC单端采样+中断也是一样的问题,采不到一个稳定的值
回复

使用道具 举报

3

主题

10

帖子

51

积分

中级工程师

Rank: 2

积分
51
发表于 2024-7-2 09:55:42 | 显示全部楼层
大佬,这个问题你解决了吗,我也遇到一样的问题
回复

使用道具 举报

3

主题

10

帖子

51

积分

中级工程师

Rank: 2

积分
51
发表于 2024-7-30 17:17:45 | 显示全部楼层
这个问题的解决方案如下:
在使用ADC+中断进行ADC内部温度采样的前,要开启VERF的使能设置,才可以采样准确;
FL_CMU_SetADCPrescaler(FL_CMU_ADC_PSC_DIV2);                                                                                                                        //配置ADC工作时钟分频
        FL_VREF_EnableVREFBuffer(VREF);                                                                                                                                                                                //使能VREF BUFFER
        FL_ADC_DisableSequencerChannel(ADC, FL_ADC_ALL_CHANNEL);                                                                        //清空打开的通道
        FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_VREF1P2);                                                        //通道选择VREF
        FL_ADC_ClearFlag_EndOfConversion(ADC);                                                                                                                                                //清标志
        FL_ADC_Enable(ADC);                                                                                                                                                                                                              // 启动ADC
        FL_ADC_EnableSWConversion(ADC);                                                                                                                                                                          // 开始转换
回复

使用道具 举报

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

本版积分规则

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