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

STM32H采集ADC经验分享

[复制链接]
STMCU小助手 发布时间:2023-3-11 19:00
注意,在CubeMX中,void SystemClock_Config(void)多了如下代码:
  1.   RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  2.   PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC|RCC_PERIPHCLK_CKPER;
  3.   PeriphClkInitStruct.CkperClockSelection = RCC_CLKPSOURCE_HSE;
  4.   PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_CLKP;
  5.   if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  6.   {
  7.     Error_Handler();
  8.   }
复制代码

查看HAL_RCCEx_PeriphCLKConfig函数中关于adc的部分:
  1. /*---------------------------- ADC configuration -------------------------------*/
  2.   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
  3.   {
  4.     switch(PeriphClkInit->AdcClockSelection)
  5.     {

  6.     case RCC_ADCCLKSOURCE_PLL2: /* PLL2 is used as clock source for ADC*/

  7.       ret = RCCEx_PLL2_Config(&(PeriphClkInit->PLL2),DIVIDER_P_UPDATE);

  8.       /* ADC clock source configuration done later after clock selection check */
  9.       break;

  10.     case RCC_ADCCLKSOURCE_PLL3:  /* PLL3 is used as clock source for ADC*/
  11.       ret = RCCEx_PLL3_Config(&(PeriphClkInit->PLL3),DIVIDER_R_UPDATE);

  12.       /* ADC clock source configuration done later after clock selection check */
  13.       break;

  14.     case RCC_ADCCLKSOURCE_CLKP:
  15.       /* HSI, HSE, or CSI oscillator is used as source of ADC clock */
  16.       /* ADC clock source configuration done later after clock selection check */
  17.       break;

  18.     default:
  19.       ret = HAL_ERROR;
  20.       break;
  21.     }

  22.     if(ret == HAL_OK)
  23.     {
  24.       /* Set the source of ADC clock*/
  25.       __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
  26.     }
  27.     else
  28.     {
  29.       /* set overall return value */
  30.       status = ret;
  31.     }
  32.   }
复制代码

而实际上我们只需要在生成HAL_ADC_MspInit中添加一句核心的__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);//ADC外设时钟选择就可以了。
ADC的时钟源有三个选项:
  1. /** @defgroup RCCEx_ADC_Clock_Source  RCCEx ADC Clock Source
  2.   * @{
  3.   */
  4. #define RCC_ADCCLKSOURCE_PLL2       ((uint32_t)0x00000000)
  5. #define RCC_ADCCLKSOURCE_PLL3       RCC_D3CCIPR_ADCSEL_0
  6. #define RCC_ADCCLKSOURCE_CLKP       RCC_D3CCIPR_ADCSEL_1
复制代码

默认将采用RCC_ADCCLKSOURCE_PLL2,即400M的输入时钟,时钟太快,所以会导致ADC采集出来的数据不会有变化。

20200426081752112.png


全部代码如下:      
  1. #include "adc.h"
  2. #include "delay.h"       

  3. ADC_HandleTypeDef hadc1;

  4. static void Error_Handler(void)
  5. {
  6.   /* USER CODE BEGIN Error_Handler_Debug */
  7.   /* User can add his own implementation to report the HAL error return state */

  8.   /* USER CODE END Error_Handler_Debug */
  9. }

  10. //获得ADC值
  11. //ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
  12. //返回值:转换结果
  13. u16 Get_Adc(u32 ch)   
  14. {
  15.         ADC_ChannelConfTypeDef ADC1_ChanConf;
  16.        
  17.         ADC1_ChanConf.Channel=ch;                                   //通道
  18.         ADC1_ChanConf.Rank=ADC_REGULAR_RANK_1;                          //1个序列
  19.         ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_64CYCLES_5;              //采样时间      
  20.         ADC1_ChanConf.SingleDiff=ADC_SINGLE_ENDED;                                  //单边采集                         
  21.         ADC1_ChanConf.OffsetNumber=ADC_OFFSET_NONE;                    
  22.         ADC1_ChanConf.Offset=0;   
  23.         HAL_ADC_ConfigChannel(&hadc1,&ADC1_ChanConf);        //通道配置

  24.         HAL_ADC_Start(&hadc1);                               //开启ADC

  25.         HAL_ADC_PollForConversion(&hadc1,10);                //轮询转换
  26.         return (u16)HAL_ADC_GetValue(&hadc1);                    //返回最近一次ADC1规则组的转换结果
  27. }

  28. //获取指定通道的转换值,取times次,然后平均
  29. //times:获取次数
  30. //返回值:通道ch的times次转换结果平均值
  31. u16 Get_Adc_Average(u32 ch,u8 times)
  32. {
  33.         u32 temp_val=0;
  34.         u8 t;
  35.         for(t=0;t<times;t++)
  36.         {
  37.                 temp_val+=Get_Adc(ch);
  38.                 delay_ms(5);
  39.         }
  40.         return temp_val/times;
  41. }




  42. /* ADC1 init function */
  43. void MX_ADC1_Init(void)
  44. {
  45.   ADC_MultiModeTypeDef multimode = {0};
  46.   ADC_ChannelConfTypeDef sConfig = {0};

  47.   /** Common config
  48.   */
  49.   hadc1.Instance = ADC1;
  50.   hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV12;
  51.   hadc1.Init.Resolution = ADC_RESOLUTION_16B;
  52.   hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  53.   hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  54.   hadc1.Init.LowPowerAutoWait = DISABLE;
  55.   hadc1.Init.ContinuousConvMode = DISABLE;
  56.   hadc1.Init.NbrOfConversion = 1;
  57.   hadc1.Init.DiscontinuousConvMode = DISABLE;
  58.   hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  59.   hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  60.   hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  61.   hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  62.   hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  63.   hadc1.Init.OversamplingMode = DISABLE;
  64.   if (HAL_ADC_Init(&hadc1) != HAL_OK)
  65.   {
  66.     Error_Handler();
  67.   }
  68.   /** Configure the ADC multi-mode
  69.   */
  70.   multimode.Mode = ADC_MODE_INDEPENDENT;
  71.   if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  72.   {
  73.     Error_Handler();
  74.   }
  75.   /** Configure Regular Channel
  76.   */
  77.   sConfig.Channel = ADC_CHANNEL_19;
  78.   sConfig.Rank = ADC_REGULAR_RANK_1;
  79.   sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  80.   sConfig.SingleDiff = ADC_SINGLE_ENDED;
  81.   sConfig.OffsetNumber = ADC_OFFSET_NONE;
  82.   sConfig.Offset = 0;
  83.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  84.   {
  85.     Error_Handler();
  86.   }

  87. }

  88. void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
  89. {

  90.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  91.   if(adcHandle->Instance==ADC1)
  92.   {
  93.   /* USER CODE BEGIN ADC1_MspInit 0 */

  94.   /* USER CODE END ADC1_MspInit 0 */
  95.     /* ADC1 clock enable */
  96.     __HAL_RCC_ADC12_CLK_ENABLE();
  97.   
  98.     __HAL_RCC_GPIOA_CLK_ENABLE();
  99.                
  100.         __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC外设时钟选择
  101.     /**ADC1 GPIO Configuration   
  102.     PA5     ------> ADC1_INP19
  103.     */
  104.     GPIO_InitStruct.Pin = GPIO_PIN_5;
  105.     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  106.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  107.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  108.   /* USER CODE BEGIN ADC1_MspInit 1 */

  109.   /* USER CODE END ADC1_MspInit 1 */
  110.   }
  111. }

  112. void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
  113. {

  114.   if(adcHandle->Instance==ADC1)
  115.   {
  116.   /* USER CODE BEGIN ADC1_MspDeInit 0 */

  117.   /* USER CODE END ADC1_MspDeInit 0 */
  118.     /* Peripheral clock disable */
  119.     __HAL_RCC_ADC12_CLK_DISABLE();
  120.   
  121.     /**ADC1 GPIO Configuration   
  122.     PA5     ------> ADC1_INP19
  123.     */
  124.     HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5);

  125.   /* USER CODE BEGIN ADC1_MspDeInit 1 */

  126.   /* USER CODE END ADC1_MspDeInit 1 */
  127.   }
  128. }

  129. /* USER CODE BEGIN 1 */

  130. /* USER CODE END 1 */

复制代码

主程序代码:
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "adc.h"

  5. int main(void)
  6. {
  7. u16 adcx;
  8.     //Cache_Enable();                 //打开L1-Cache
  9.     HAL_Init();                           //初始化HAL库
  10.     Stm32_Clock_Init(200, 2, 2, 2); //设置时钟,400Mhz
  11.     delay_init(400);                        //延时初始化
  12.     uart_init(115200);                  //串口初始化
  13.     printf("hello\r\n");
  14.                 MX_ADC1_Init();
  15.     while (1)
  16.     {
  17.                         adcx = Get_Adc_Average(ADC_CHANNEL_19, 20); //获取通道19的转换值,20次取平均
  18.                         printf("adcx:%d\r\n",adcx);
  19.                         delay_ms(500);
  20.     }
  21. }
复制代码

————————————————
版权声明:小盼你最萌哒

收藏 评论1 发布时间:2023-3-11 19:00

举报

1个回答
Haruno 回答时间:2023-5-17 11:34:31

感谢分享,非常有用哇

所属标签

相似分享

官网相关资源

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