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

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

[复制链接]
huxudong1012 提问时间: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

查看全部评分

huxudong1012 回答时间: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.   */
复制代码
huxudong1012 回答时间:2018-4-2 14:55:17
上楼程序和CubeMx中配置了ADC1和ADC2,时钟为12M经过了2分频。不管使用哪路ADC,均存在误差。main函数无他,直接DMA处理AD转换,间隔时间比较长。
huxudong1012 回答时间:2018-4-2 14:59:00
相关硬件原理图如下:
4.png
6.png
huxudong1012 回答时间: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附近;
huxudong1012 回答时间:2018-4-2 15:10:47
自己的一些疑问:
一、STM32F103系列的AD转换,存在一个校准的过程,也就是在程序刚开始必须进行自校准,然后开启AD转换。但是STM32L476用CubeMx生成的库函数,仔细查看后没有留下相关的校准函数,目前还有待思考该过程?
二、外围电路,包括基准和跟随还有阻抗匹配,没有发现不良现象,不知道有没有大神提供一下思路?
三、目前不清楚是硬件原因还是软件原因导致12位AD误差接近50mV.希望大神伸出援助之手!
huxudong1012 回答时间: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

查看全部评分

琦子 回答时间: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管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版