[STM32H7] ADC单通道采集

[复制链接]
1583|7
 楼主| 李清波10 发表于 2025-4-15 23:10 | 显示全部楼层 |阅读模式
AD, ADC, dc, AN, ni
本帖最后由 李清波10 于 2025-4-15 23:12 编辑

adc.c
  1. ADC_HandleTypeDef g_adc_handle;   /* ADC句柄 */
  2. /**
  3. * [url=home.php?mod=space&uid=247401]@brief[/url]       ADC初始化函数
  4. *   [url=home.php?mod=space&uid=536309]@NOTE[/url]      本函数支持ADC1/ADC2任意通道,但是不支持ADC3
  5. *              我们使用16位精度, ADC采样时钟=32M, 转换时间为:采样周期 + 8.5个ADC周期
  6. *              设置最大采样周期: 810.5, 则转换时间 = 819个ADC周期 = 25.6us
  7. * @param       无
  8. * @retval      无
  9. */
  10. void ADC_Init(void)
  11. {
  12.     g_adc_handle.Instance = ADC_ADCX;                                               /* 选择哪个ADC */
  13.     g_adc_handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;                        /* 输入时钟2分频,即adc_ker_ck=per_ck/2=32Mhz */
  14.     g_adc_handle.Init.Resolution = ADC_RESOLUTION_12B;                              /* 16位模式  */
  15.     g_adc_handle.Init.ScanConvMode = ADC_SCAN_DISABLE;                              /* 非扫描模式,仅用到一个通道 */
  16.     g_adc_handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;                           /* 关闭EOC中断 */
  17.     g_adc_handle.Init.LowPowerAutoWait = DISABLE;                                   /* 自动低功耗关闭 */
  18.     g_adc_handle.Init.ContinuousConvMode = DISABLE;                                 /* 关闭连续转换模式 */
  19.     g_adc_handle.Init.NbrOfConversion = 1;                                          /* 赋值范围是1~16,本实验用到1个常规通道 */
  20.     g_adc_handle.Init.DiscontinuousConvMode = DISABLE;                              /* 禁止常规转换组不连续采样模式 */
  21.     g_adc_handle.Init.NbrOfDiscConversion = 0;                                      /* 配置不连续采样模式的通道数,禁止常规转换组不连续采样模式后,此参数忽略 */
  22.     g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;                        /* 软件触发 */
  23.     g_adc_handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;         /* 采用软件触发的话,此位忽略 */
  24.     g_adc_handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;             /* 常规通道的数据仅仅保存在DR寄存器里面 */
  25.     g_adc_handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;                           /* 有新的数据后直接覆盖掉旧数据 */
  26.     g_adc_handle.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;                         /* 设置ADC转换结果的左移位数 */
  27.     g_adc_handle.Init.OversamplingMode = DISABLE;                                   /* 关闭过采样 */
  28.     HAL_ADC_Init(&g_adc_handle);                                                    /* 初始化 */

  29.     HAL_ADCEx_Calibration_Start(&g_adc_handle, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED); /* ADC校准 */
  30. }

  31. /**
  32. * [url=home.php?mod=space&uid=247401]@brief[/url]       ADC底层驱动,引脚配置,时钟使能
  33.                 此函数会被HAL_ADC_Init()调用
  34. * @param       hadc:ADC句柄
  35. * @retval      无
  36. */
  37. void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
  38. {
  39.     if(hadc->Instance == ADC_ADCX)
  40.     {
  41.         GPIO_InitTypeDef gpio_init_struct;

  42.         ADC_ADCX_CHY_CLK_ENABLE();                      /* 使能ADC1/2时钟 */
  43.         ADC_ADCX_CHY_GPIO_CLK_ENABLE();                 /* 开启ADC通道IO引脚时钟 */

  44.         __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);    /* ADC外设时钟选择 */

  45.         gpio_init_struct.Pin = ADC_ADCX_CHY_GPIO_PIN;   /* ADC通道IO引脚 */
  46.         gpio_init_struct.Mode = GPIO_MODE_ANALOG;       /* 模拟 */
  47.         HAL_GPIO_Init(ADC_ADCX_CHY_GPIO_PORT, &gpio_init_struct);
  48.     }
  49. }

  50. /**
  51. * [url=home.php?mod=space&uid=247401]@brief[/url]       获得ADC转换后的结果
  52. * @param       ch: 通道值 0~19,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_19
  53. * @retval      返回值:转换结果
  54. */
  55. uint32_t ADC1_get_result(uint32_t ch)
  56. {
  57.     ADC_ChannelConfTypeDef adc_ch_conf = {0};

  58.     adc_ch_conf.Channel = ch;                              /* 通道 */
  59.     adc_ch_conf.Rank = ADC_REGULAR_RANK_1;                 /* 序列 */
  60.     adc_ch_conf.SamplingTime = ADC_SAMPLETIME_810CYCLES_5; /* 采样时间,设置最大采样周期: 810.5个ADC周期 */
  61.     adc_ch_conf.SingleDiff = ADC_SINGLE_ENDED;             /* 单边采集 */
  62.     adc_ch_conf.OffsetNumber = ADC_OFFSET_NONE;            /* 不使用偏移量的通道 */
  63.     adc_ch_conf.Offset = 0;                                /* 偏移量为0 */

  64.     HAL_ADC_ConfigChannel(&g_adc_handle, &adc_ch_conf);    /* 通道配置 */
  65.     HAL_ADC_Start(&g_adc_handle);                          /* 开启ADC */
  66.     HAL_ADC_PollForConversion(&g_adc_handle, 10);          /* 轮询转换 */
  67.     return HAL_ADC_GetValue(&g_adc_handle);                /* 返回最近一次ADC1常规组的转换结果 */
  68. }

adc.h
  1. <blockquote>#ifndef __ADC_H


  
 楼主| 李清波10 发表于 2025-4-15 23:13 | 显示全部楼层
  1. #ifndef __ADC_H
  2. #define __ADC_H

  3. #include "./SYS/Inc/sys.h"   
  4. adc.h
  5. /******************************************************************************************/
  6. /* ADC及引脚 定义 */

  7. #define ADC_ADCX_CHY_GPIO_PORT              GPIOA
  8. #define ADC_ADCX_CHY_GPIO_PIN               GPIO_PIN_5
  9. #define ADC_ADCX_CHY_GPIO_CLK_ENABLE()      do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */

  10. #define ADC_ADCX                            ADC1
  11. #define ADC_ADCX_CHY                        ADC_CHANNEL_19                                /* 通道Y,  0 <= Y <= 19 */
  12. #define ADC_ADCX_CHY_CLK_ENABLE()           do{ __HAL_RCC_ADC12_CLK_ENABLE(); }while(0)   /* ADC1 & ADC2 时钟使能 */

  13. /******************************************************************************************/

  14. void ADC_Init(void);                                           /* ADC初始化函数 */
  15. uint32_t ADC1_get_result(uint32_t ch);                          /* 获得某个通道值  */
  16. uint32_t adc_get_result_average(uint32_t ch, uint8_t times);   /* 得到某个通道给定次数采样的平均值 */


  17. #endif














 楼主| 李清波10 发表于 2025-4-15 23:14 | 显示全部楼层
测试图片
139767fe77b0905aa.jpg
zjk103 发表于 2025-4-16 15:59 | 显示全部楼层
精确度如何

评论

滤波过后能满足要求的  发表于 2025-4-16 22:43
 楼主| 李清波10 发表于 2025-4-16 22:42 | 显示全部楼层
欢乐家园 发表于 2025-4-30 23:55 | 显示全部楼层
如果 HAL_ADC_PollForConversion 返回超时(即转换未完成),增加超时时间,或者改为中断模式来触发读取。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

10

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部