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

STM32L476,CubeMx生成底层,AD转换误差较大,误差接近40mV。

[复制链接]
千棵树 提问时间:2018-4-2 14:49 /
悬赏1ST金币已解决
一、主芯片选用STM32L476RCTx;
二、CubeMx版本为4.23;
三、配置如下:

1.png
2.png
3.png

最佳答案

查看完整内容

建议参考一下例程,因为cubeMx只是生成底层库... Repository\STM32Cube_FW_L4_V1.10.0\Projects\STM32L476G_EVAL\Examples\ADC\ADC_DMA_Transfer /* ### - 2 - Start calibration ############################################ */ if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK) { Error_Handler(); }
收藏 评论9 发布时间:2018-4-2 14:49

举报

9个回答
butterflyspring 回答时间:2018-4-2 14:49:24
建议参考一下例程,因为cubeMx只是生成底层库...

Repository\STM32Cube_FW_L4_V1.10.0\Projects\STM32L476G_EVAL\Examples\ADC\ADC_DMA_Transfer

/* ### - 2 - Start calibration ############################################ */
  if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) !=  HAL_OK)
  {
    Error_Handler();
  }

评分

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

查看全部评分

千棵树 回答时间:2018-4-2 14:50:37
生成后的代码如下:
  1. #include "adc.h"

  2. #include "gpio.h"
  3. #include "dma.h"

  4. /* USER CODE BEGIN 0 */

  5. /* USER CODE END 0 */

  6. ADC_HandleTypeDef hadc1;
  7. ADC_HandleTypeDef hadc2;
  8. DMA_HandleTypeDef hdma_adc1;
  9. DMA_HandleTypeDef hdma_adc2;

  10. /* ADC1 init function */
  11. void MX_ADC1_Init(void)
  12. {
  13.   ADC_MultiModeTypeDef multimode;
  14.   ADC_ChannelConfTypeDef sConfig;

  15.     /**Common config
  16.     */
  17.   hadc1.Instance = ADC1;
  18.   hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
  19.   hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  20.   hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  21.   hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  22.   hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  23.   hadc1.Init.LowPowerAutoWait = DISABLE;
  24.   hadc1.Init.ContinuousConvMode = DISABLE;
  25.   hadc1.Init.NbrOfConversion = 4;
  26.   hadc1.Init.DiscontinuousConvMode = DISABLE;
  27.   hadc1.Init.NbrOfDiscConversion = 1;
  28.   hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  29.   hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  30.   hadc1.Init.DMAContinuousRequests = DISABLE;
  31.   hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  32.   hadc1.Init.OversamplingMode = DISABLE;
  33.   if (HAL_ADC_Init(&hadc1) != HAL_OK)
  34.   {
  35.     _Error_Handler(__FILE__, __LINE__);
  36.   }

  37.     /**Configure the ADC multi-mode
  38.     */
  39.   multimode.Mode = ADC_MODE_INDEPENDENT;
  40.   if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  41.   {
  42.     _Error_Handler(__FILE__, __LINE__);
  43.   }

  44.     /**Configure Regular Channel
  45.     */
  46.   sConfig.Channel = ADC_CHANNEL_5;
  47.   sConfig.Rank = 1;
  48.   sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5;
  49.   sConfig.SingleDiff = ADC_SINGLE_ENDED;
  50.   sConfig.OffsetNumber = ADC_OFFSET_NONE;
  51.   sConfig.Offset = 255;
  52.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  53.   {
  54.     _Error_Handler(__FILE__, __LINE__);
  55.   }

  56.     /**Configure Regular Channel
  57.     */
  58.   sConfig.Channel = ADC_CHANNEL_6;
  59.   sConfig.Rank = 2;
  60.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  61.   {
  62.     _Error_Handler(__FILE__, __LINE__);
  63.   }

  64.     /**Configure Regular Channel
  65.     */
  66.   sConfig.Channel = ADC_CHANNEL_7;
  67.   sConfig.Rank = 3;
  68.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  69.   {
  70.     _Error_Handler(__FILE__, __LINE__);
  71.   }

  72.     /**Configure Regular Channel
  73.     */
  74.   sConfig.Channel = ADC_CHANNEL_8;
  75.   sConfig.Rank = 4;
  76.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  77.   {
  78.     _Error_Handler(__FILE__, __LINE__);
  79.   }

  80. }
  81. /* ADC2 init function */
  82. void MX_ADC2_Init(void)
  83. {
  84.   ADC_ChannelConfTypeDef sConfig;

  85.     /**Common config
  86.     */
  87.   hadc2.Instance = ADC2;
  88.   hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
  89.   hadc2.Init.Resolution = ADC_RESOLUTION_12B;
  90.   hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  91.   hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;
  92.   hadc2.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  93.   hadc2.Init.LowPowerAutoWait = DISABLE;
  94.   hadc2.Init.ContinuousConvMode = DISABLE;
  95.   hadc2.Init.NbrOfConversion = 3;
  96.   hadc2.Init.DiscontinuousConvMode = DISABLE;
  97.   hadc2.Init.NbrOfDiscConversion = 1;
  98.   hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  99.   hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  100.   hadc2.Init.DMAContinuousRequests = DISABLE;
  101.   hadc2.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  102.   hadc2.Init.OversamplingMode = DISABLE;
  103.   if (HAL_ADC_Init(&hadc2) != HAL_OK)
  104.   {
  105.     _Error_Handler(__FILE__, __LINE__);
  106.   }

  107.     /**Configure Regular Channel
  108.     */
  109.   sConfig.Channel = ADC_CHANNEL_1;
  110.   sConfig.Rank = 1;
  111.   sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
  112.   sConfig.SingleDiff = ADC_SINGLE_ENDED;
  113.   sConfig.OffsetNumber = ADC_OFFSET_NONE;
  114.   sConfig.Offset = 0;
  115.   if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
  116.   {
  117.     _Error_Handler(__FILE__, __LINE__);
  118.   }

  119.     /**Configure Regular Channel
  120.     */
  121.   sConfig.Channel = ADC_CHANNEL_2;
  122.   sConfig.Rank = 2;
  123.   if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
  124.   {
  125.     _Error_Handler(__FILE__, __LINE__);
  126.   }

  127.     /**Configure Regular Channel
  128.     */
  129.   sConfig.Channel = ADC_CHANNEL_3;
  130.   sConfig.Rank = 3;
  131.   sConfig.SamplingTime = ADC_SAMPLETIME_24CYCLES_5;
  132.   if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
  133.   {
  134.     _Error_Handler(__FILE__, __LINE__);
  135.   }

  136. }

  137. static uint32_t HAL_RCC_ADC_CLK_ENABLED=0;

  138. void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
  139. {

  140.   GPIO_InitTypeDef GPIO_InitStruct;
  141.   if(adcHandle->Instance==ADC1)
  142.   {
  143.   /* USER CODE BEGIN ADC1_MspInit 0 */

  144.   /* USER CODE END ADC1_MspInit 0 */
  145.     /* ADC1 clock enable */
  146.     HAL_RCC_ADC_CLK_ENABLED++;
  147.     if(HAL_RCC_ADC_CLK_ENABLED==1){
  148.       __HAL_RCC_ADC_CLK_ENABLE();
  149.     }
  150.   
  151.     /**ADC1 GPIO Configuration   
  152.     PA0     ------> ADC1_IN5
  153.     PA1     ------> ADC1_IN6
  154.     PA2     ------> ADC1_IN7
  155.     PA3     ------> ADC1_IN8
  156.     */
  157.     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
  158.     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
  159.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  160.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  161.     /* ADC1 DMA Init */
  162.     /* ADC1 Init */
  163.     hdma_adc1.Instance = DMA1_Channel1;
  164.     hdma_adc1.Init.Request = DMA_REQUEST_0;
  165.     hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
  166.     hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
  167.     hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
  168.     hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  169.     hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  170.     hdma_adc1.Init.Mode = DMA_CIRCULAR;
  171.     hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;
  172.     if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
  173.     {
  174.       _Error_Handler(__FILE__, __LINE__);
  175.     }

  176.     __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);

  177.     /* ADC1 interrupt Init */
  178.     HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);
  179.     HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
  180.   /* USER CODE BEGIN ADC1_MspInit 1 */

  181.   /* USER CODE END ADC1_MspInit 1 */
  182.   }
  183.   else if(adcHandle->Instance==ADC2)
  184.   {
  185.   /* USER CODE BEGIN ADC2_MspInit 0 */

  186.   /* USER CODE END ADC2_MspInit 0 */
  187.     /* ADC2 clock enable */
  188.     HAL_RCC_ADC_CLK_ENABLED++;
  189.     if(HAL_RCC_ADC_CLK_ENABLED==1){
  190.       __HAL_RCC_ADC_CLK_ENABLE();
  191.     }
  192.   
  193.     /**ADC2 GPIO Configuration   
  194.     PC0     ------> ADC2_IN1
  195.     PC1     ------> ADC2_IN2
  196.     PC2     ------> ADC2_IN3
  197.     */
  198.     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
  199.     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
  200.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  201.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  202.     /* ADC2 DMA Init */
  203.     /* ADC2 Init */
  204.     hdma_adc2.Instance = DMA1_Channel2;
  205.     hdma_adc2.Init.Request = DMA_REQUEST_0;
  206.     hdma_adc2.Init.Direction = DMA_PERIPH_TO_MEMORY;
  207.     hdma_adc2.Init.PeriphInc = DMA_PINC_DISABLE;
  208.     hdma_adc2.Init.MemInc = DMA_MINC_ENABLE;
  209.     hdma_adc2.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  210.     hdma_adc2.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  211.     hdma_adc2.Init.Mode = DMA_CIRCULAR;
  212.     hdma_adc2.Init.Priority = DMA_PRIORITY_HIGH;
  213.     if (HAL_DMA_Init(&hdma_adc2) != HAL_OK)
  214.     {
  215.       _Error_Handler(__FILE__, __LINE__);
  216.     }

  217.     __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc2);

  218.     /* ADC2 interrupt Init */
  219.     HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);
  220.     HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
  221.   /* USER CODE BEGIN ADC2_MspInit 1 */

  222.   /* USER CODE END ADC2_MspInit 1 */
  223.   }
  224. }

  225. void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
  226. {

  227.   if(adcHandle->Instance==ADC1)
  228.   {
  229.   /* USER CODE BEGIN ADC1_MspDeInit 0 */

  230.   /* USER CODE END ADC1_MspDeInit 0 */
  231.     /* Peripheral clock disable */
  232.     /* Be sure that all peripheral instances that share the same clock need to be disabled */
  233.     /**  HAL_RCC_ADC_CLK_ENABLED--;
  234.     *  if(HAL_RCC_ADC_CLK_ENABLED==0){
  235.     *    __HAL_RCC_ADC_CLK_DISABLE();
  236.     **/
  237.   
  238.     /**ADC1 GPIO Configuration   
  239.     PA0     ------> ADC1_IN5
  240.     PA1     ------> ADC1_IN6
  241.     PA2     ------> ADC1_IN7
  242.     PA3     ------> ADC1_IN8
  243.     */
  244.     HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

  245.     /* ADC1 DMA DeInit */
  246.     HAL_DMA_DeInit(adcHandle->DMA_Handle);

  247.     /* ADC1 interrupt Deinit */
  248.   /* USER CODE BEGIN ADC1:ADC1_2_IRQn disable */
  249.     /**
  250.     * Uncomment the line below to disable the "ADC1_2_IRQn" interrupt
  251.     * Be aware, disabling shared interrupt may affect other IPs
  252.     */
  253.     /* HAL_NVIC_DisableIRQ(ADC1_2_IRQn); */
  254.   /* USER CODE END ADC1:ADC1_2_IRQn disable */

  255.   /* USER CODE BEGIN ADC1_MspDeInit 1 */

  256.   /* USER CODE END ADC1_MspDeInit 1 */
  257.   }
  258.   else if(adcHandle->Instance==ADC2)
  259.   {
  260.   /* USER CODE BEGIN ADC2_MspDeInit 0 */

  261.   /* USER CODE END ADC2_MspDeInit 0 */
  262.     /* Peripheral clock disable */
  263.     /* Be sure that all peripheral instances that share the same clock need to be disabled */
  264.     /**  HAL_RCC_ADC_CLK_ENABLED--;
  265.     *  if(HAL_RCC_ADC_CLK_ENABLED==0){
  266.     *    __HAL_RCC_ADC_CLK_DISABLE();
  267.     **/
  268.   
  269.     /**ADC2 GPIO Configuration   
  270.     PC0     ------> ADC2_IN1
  271.     PC1     ------> ADC2_IN2
  272.     PC2     ------> ADC2_IN3
  273.     */
  274.     HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2);

  275.     /* ADC2 DMA DeInit */
  276.     HAL_DMA_DeInit(adcHandle->DMA_Handle);

  277.     /* ADC2 interrupt Deinit */
  278.   /* USER CODE BEGIN ADC2:ADC1_2_IRQn disable */
  279.     /**
  280.     * Uncomment the line below to disable the "ADC1_2_IRQn" interrupt
  281.     * Be aware, disabling shared interrupt may affect other IPs
  282.     */
  283.     /* HAL_NVIC_DisableIRQ(ADC1_2_IRQn); */
  284.   /* USER CODE END ADC2:ADC1_2_IRQn disable */

  285.   /* USER CODE BEGIN ADC2_MspDeInit 1 */

  286.   /* USER CODE END ADC2_MspDeInit 1 */
  287.   }
  288. }

  289. /* USER CODE BEGIN 1 */

  290. /* USER CODE END 1 */

  291. /**
  292.   * @}
  293.   */

  294. /**
  295.   * @}
  296.   */
复制代码
千棵树 回答时间:2018-4-2 14:55:17
上楼程序和CubeMx中配置了ADC1和ADC2,时钟为12M经过了2分频。不管使用哪路ADC,均存在误差。main函数无他,直接DMA处理AD转换,间隔时间比较长。
千棵树 回答时间:2018-4-2 14:59:00
相关硬件原理图如下:
4.png
6.png
千棵树 回答时间:2018-4-2 15:04:26
问题如下:
1、使用12位的AD,误差接近50mV;
2、用示波器测试基准为3.28V(虽然没有3.3V但是3.28V还是比较稳,无干扰征兆);
3、示波器检测VDD,VSS均很稳定,无干扰现象;
4、测试单片机的AD输入端,TEMP1,也很平稳,没发现干扰;
5、用VSS直接并到TEMP1,AD转换结果为0x000;
6、用VDD并到TEMP1,测试的结果并不为OxFFF,而是0xFBE附近;
千棵树 回答时间:2018-4-2 15:10:47
自己的一些疑问:
一、STM32F103系列的AD转换,存在一个校准的过程,也就是在程序刚开始必须进行自校准,然后开启AD转换。但是STM32L476用CubeMx生成的库函数,仔细查看后没有留下相关的校准函数,目前还有待思考该过程?
二、外围电路,包括基准和跟随还有阻抗匹配,没有发现不良现象,不知道有没有大神提供一下思路?
三、目前不清楚是硬件原因还是软件原因导致12位AD误差接近50mV.希望大神伸出援助之手!
千棵树 回答时间:2018-4-2 16:42:29
千棵树 发表于 2018-4-2 15:10
自己的一些疑问:
一、STM32F103系列的AD转换,存在一个校准的过程,也就是在程序刚开始必须进行自校准,然 ...

我也是刚解决这个问题,上来一看,发现还是有校准过程。也就是这个函数。
另外可以直接看系统自带的库函数:
  1. HAL_StatusTypeDef       HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc, uint32_t SingleDiff);
  2. uint32_t                HAL_ADCEx_Calibration_GetValue(ADC_HandleTypeDef *hadc, uint32_t SingleDiff);
  3. HAL_StatusTypeDef       HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef *hadc, uint32_t SingleDiff, uint32_t CalibrationFactor);
复制代码

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2 结帖奖励

查看全部评分

wenyangzeng 回答时间:2018-4-2 16:46:45
本帖最后由 wenyangzeng 于 2018-4-2 16:49 编辑
千棵树 发表于 2018-4-2 14:50
生成后的代码如下:

ADC_SAMPLETIME_6CYCLES_5
采样时间好像太短了,就4个输入ADC,统一使用ADC1设置4个不同通道就够了,

评分

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

查看全部评分

bargagebaobei 回答时间:2018-4-2 16:49:01
((TIME) == ADC_SAMPLETIME_28CYCLES)
((TIME) == ADC_SAMPLETIME_56CYCLES)  
((TIME) == ADC_SAMPLETIME_84CYCLES)  
((TIME) == ADC_SAMPLETIME_112CYCLES)
((TIME) == ADC_SAMPLETIME_144CYCLES)
((TIME) == ADC_SAMPLETIME_480CYCLES)
可以放到最大

评分

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

查看全部评分

所属标签

相似问题

官网相关资源

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