STM32配置ADC问题

        最近在学习蓝桥杯的stm32G431芯片时,发现同一段ADC转换代码,转换有时成功有时不成功,偶然间发现加上延迟函数LL_mDelay(50);就可以转换成功了,非常疑惑。因为加入延迟的解决方法与时间有关,是时域问题,我猜测可能是ADC的时钟频率出问题了。故尝试寻找了一个从根本上解决ADC转换的方法。

        核心方法:降低ADC的时钟频率

        具体方法1 ,降低ADC时钟频率的方法有很多,最简单的一种就是使用异步时钟,并增加ADC时钟的分频系数。如图1,在ADC_Settings里的Clock Prescaler选择 “32分频后的异步时钟”。这是因为使用异步时钟后分频系数更多。

图1 使用异步时钟,增加分频系数

        具体方法2,降低AHB的时钟频率。AHB的时钟来自SYSCLK,可以增加SYSCLK到AHB的分频系数或者降低SYSCLK频率。如图2,是通过增加SYSCLK到AHB的分频系数来降低AHB时钟频率,从而降低ADC时钟频率。      同时,还要在ADC设置界面选择ADC的时钟来源“同步时钟”,如图3

图2 使用同步时钟,降低AHB时钟频率 

图3 选择同步时钟

          

          至于为什么降低ADC的时钟频率就可以转换正常,我推测是和ADC的输入时钟频率有关,ADC的输入时钟频率不可以太高,否则转换结果会异常。我之前配置的AHB频率是170Mhz,同步时钟2分频后输入给ADC,85Mhz远高于ADC允许的输入时钟频率,所以导致了ADC转化不成功的问题。

          关于ADC时钟的“异步时钟”(Synchronous clock)和“同步时钟”(Asynchronous clock)有什么区别,可以参考这个博主的这篇文章:STM32配置ADC时钟分频因子问题小结

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用STM32CubeMX配置ADC的步骤: 1. 打开STM32CubeMX软件,并选择要使用的MCU型号。 2. 在Pinout & Configuration选项卡中,将需要使用的ADC引脚设置为ADC模式。 3. 在Configuration选项卡中,选择ADC模块,并启用需要使用的ADC通道。同时,您可以设置ADC分辨率、采样时间和触发方式等参数。 4. 在Clock Configuration选项卡中,启用ADC时钟,并将其设置为所需的速率。 5. 生成代码并导入到您的IDE中,然后在代码中调用HAL_ADC_Start()函数启动ADC转换。 下面是一个示例代码片段: ```c /* 配置并启动ADC */ ADC_HandleTypeDef hadc1; void MX_ADC1_Init(void) { /* 启用ADC时钟 */ __HAL_RCC_ADC1_CLK_ENABLE(); /* 配置ADC通道 */ hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.NbrOfDiscConversion = 0; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } /* 配置ADC通道1 */ ADC_ChannelConfTypeDef sConfig; sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = 1; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } } /* 启动ADC转换 */ void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if (hadc->Instance == ADC1) { /* 启用ADC时钟 */ __HAL_RCC_ADC1_CLK_ENABLE(); /* 配置ADC引脚 */ __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } } int main(void) { /* 初始化ADC */ MX_ADC1_Init(); /* 启动ADC转换 */ if (HAL_ADC_Start(&hadc1) != HAL_OK) { Error_Handler(); } /* 循环读取ADC值 */ while (1) { if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK) { uint32_t adc_value = HAL_ADC_GetValue(&hadc1); printf("ADC value: %d\r\n", adc_value); } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值