当前位置:   article > 正文

定时器(PWM输出)触发ADC采样(DMA)——STM32CubeMX_怎么用定时器采样

怎么用定时器采样

一、(单通道)使用定时器触发的ADC单通道转换

我用的单片机是STM32F103CBTX

  • 定时器:使用PWM输出的模式
  • ADC:使用DMA的模式(在不使用DMA的情况下,定时器控制ADC进行数据采集只能是单通道!如果开启了多通道,读取到的ADC采集值只会是最后一个通道的值!所以,要想使用定时器控制ADC采集多通道必须使用DMA!)

定时器中cubemx配置:

 看STM32F103数据手册可以知道定时器TIM1是挂在APB1总线上

c52adb17eb414ceb98da4346055d37a2.png

我使用的是TIM1的通道2的上升沿(即PWM输出)触发ADC采样 

4eaa649c71984633b73200b4164d7c5c.png

PWM模式1和模式2区别:

以下是使用逻辑分析仪观察到的PWM输出情况

c665e23e417947b4a7376cd3a067a2f8.png

137b6339728a4e51b11a9c8b6a2d94fe.png

ADC中cubemx配置: 

注意:此时不再需要ADC进行转换,把连续转换模式设为关闭!!!

(我自己踩的坑,我试过开启的时候程序死掉了)

a2554d931b4f447e994f58c0fad6cd46.png

DMA模式选择: 

Circular模式:

就是ADC连续采样的意思,也就是HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC_Value, 4)这句代码在程序中开启一次即可,不需要每次都重新打开。

Normal模式:

HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC_Value, 4)执行完一次之后,如果想进行下一轮ADC采样,必须要重新开启,所以每一轮采样都要用一次这句代码,采样一次开启一次采样一次开启一次。

参考别人的试了用了Circular模式,完全没问题,可以成功测出电压值。

我自己也试了Normal模式,不行,只能测一次,后面没反应了。

a8d2ba26f6304b67b830a6bc98196a48.png

 代码:

  1. uint8_t AdcConvEnd=0;
  2. int main()
  3. {
  4. uint16_t ADC_Value[4]= 0;
  5. HAL_TIM_Base_Start(&htim1);
  6. HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
  7. HAL_ADCEx_Calibration_Start(&hadc1);//自动校准
  8. HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC_Value, 4);
  9. while(1)
  10. {
  11. if(AdcConvEnd)
  12. {
  13. uint16_t averageValue = 0;
  14. for(int i = 0; i < 4; i++)
  15. {
  16. averageValue += ADC_Value[i];
  17. printf("ADC_Value[%d]:%.3f\r\n",i,(float)ADC_Value[i]*3.3f/4096);
  18. }
  19. AdcConvEnd=0;
  20. averageValue/=4;
  21. printf("averageValue:%d\r\n",averageValue);
  22. }
  23. }
  24. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
  25. {
  26. if(hadc==&hadc1)
  27. {
  28. AdcConvEnd=1;
  29. }
  30. }

结果:

b14f3b94fe984e4cb342b1e8ca014931.png

二、(双通道)使用定时器触发的ADC通道转换 

注意:因为我们设置的是 2 个通道的采集,所以应该使能 ADC 的扫描模式,另一方面,我们采用的是 TIM 产生 pwm 触发 adc 进行采集,所以要禁止 ADC 的连续转换模式,这就是两个需要注意的地方。

ADC中cubemx配置: 

2bbbb2326c00463286845cbe99cb6a6c.png

三、关于PWM的频率或周期的计算

ef4c8d32cb554af9918b6697581516ac.png

*注 :* ARR和PSC都是16位的寄存器, 数值一定要在0~65535这个范围。

当我们设置了当前机器设置的是 72MHZ和 72分频,定时器输入时钟频率是72MHz / 72 = 1MHz:

  • 1MHZ ,即1秒计数 1M 次=1000000 次(1s产生1000000个脉冲方波)。
  • 1MHZ ,也就是1us产生1个脉冲方波。

若重装载值 (Period 或 ARR)设置为 500。也就是0.1us*500=500us,对于当前 PWM 周期为 500us,也就是500us发生一次中断。

当重装载值(Period 或 ARR)设置为 500 时,意味着定时器需要计数 500 个时钟周期才会触发中断。因此,中断发生的周期是 500us(即500 * 1us

若Pulse设为250,即占空比=Pulse/ARR=250/500=50%

四、寄存器TIMx_ARR、TIMx_CCRx 、TIMx_CNT

向上计数为例,重载值为ARR,比较值为CRRx

8e27aba90c9a4ff18d20c25dda041fb2.png

上图可以看出:

  • 0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平
  • t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平

TIMx_CNT值达到ARR时,定时器溢出,重新向上计数...循环此过程至此一个PWM周期完成

上图更加形象的说明了

信号频率由 TIMx_ARR 寄存器值决定。

占空比则由 TIMx_CCRx 寄存器值决定。

参考:

STM32 HAL库:ADC+DMA应用(连续采样、触发采样)_hal adc dma-CSDN博客

【STM32】定时器TIM触发ADC采样,DMA搬运到内存(超详细讲解)-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/601996
推荐阅读
相关标签
  

闽ICP备14008679号