[Q1][STM32G4系列] TIMER观察 - 使用TIMER触发ADC,透过DMA方式结合

前言

以TIMER为主要观察源,使用TIMER触发ADC,透过DMA结合,同时观察ADC中断副程序,进而延伸不同领域应用。

内容

STM32G4系列ADC支援多样的触发取样方式,可以利用Timer和GPIO做触发。
以STM32G431为例,除了软件触发外还支援下列来源的触发。

https://ithelp.ithome.com.tw/upload/images/20211018/201430211kFf9g5lDx.jpg

_ / CubeMX设定ADC \

这个范例,采用TIMER3 CC4作为ADC触发讯号观察。
在STM32CubeMX中,首先对ADC做设置如下。


先建立ADC通道,再开启DMA通道,透过DMA可使ADC完全触发於被动状态。
https://ithelp.ithome.com.tw/upload/images/20211018/20143021miC8kKlw8O.jpg
https://ithelp.ithome.com.tw/upload/images/20211018/20143021aFvxpLtJKj.jpg


设定ADC相关功能(另外说明),与开启DMA。
https://ithelp.ithome.com.tw/upload/images/20211018/20143021QV89EYGhbe.jpg

以TIMER3 CC4作为ADC触发讯号观察,设定对应选项。

  1. 外部触发来源更改为Timer 3 Capture Compare 4 event
  2. 并选择上下缘触发

https://ithelp.ithome.com.tw/upload/images/20211018/20143021Y5oROVYo0X.jpg

ADC与DMA结合设定完成,接下来只需将TIMER完成设定即可完成此次实验与观察目的。


__ / CubeMX设定TIMER \

设定Timer 3 Channel 4为PWM,因为不需要从硬体pin脚输出波形。
只需要产生对应的事件event,所以设置为PWM Generation No Output。
若需要观察TIME3 CH4对应波形,也可选择PWM Generation CH4,观察後再关闭即可。
https://ithelp.ithome.com.tw/upload/images/20211018/201430219bPAcqixBk.jpg


此次范例设计1KHz PWM输出,对应主频170MHz,TIMER基础设定如下。
https://ithelp.ithome.com.tw/upload/images/20211018/20143021a5qNqOWxZE.jpg

完成ADC与TIMER的设定後,开始 Generation code 之後回到maim.c完成最後步骤。

小记

每次使用CubeMX设定相关条件时,都认为似乎很容易,但其实基础设定就仅如此,较困难的部分是进阶用法,需要非常熟悉CubeMX里面相关设定代表意义,才能够如愿完成进阶功能与开发。难怪前辈说最好还是要全部熟悉一遍。


___ / 实现程序逻辑流程编码与实际验证 \

然後在main.c中,新增程序码如下。
暂存器设定

/* USER CODE BEGIN PV */

uint16_t Value_PWMDuty = 0;		
uint16_t Data_adc[10];
/* USER CODE END PV */

记得下指令启用ADC与TIMER。
若有另外启用中断副程序,则下面程序需要符合为中断副程序的指令。

 /* USER CODE BEGIN 2 */
 
  HAL_TIM_Base_Start(&htim3); 
  HAL_ADC_Start_DMA(&hadc1, (uint32_t *)Data_adc,1);
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);
  /* USER CODE END 2 */

另外启用GPIO,观察PWM波形与时序关系。

/* USER CODE BEGIN 4 */

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	HAL_GPIO_TogglePin(TEST_GPIO_Port, TEST_Pin);
}
/* USER CODE END 4 */

HAL_ADC_Start_DMA为启动ADC DMA传输,取样传输1次後结束。
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);为启动Timer 3 Channel 4
当Timer启动後才会触发ADC取样,因设定取样完1次後,会自动呼叫HAL_ADC_ConvCpltCallback这个callback函式,在此函数内使用GPIO High / Low动作,接到示波器量测。


在主回圈while (1)中,设定 Value_PWMDuty = 400,由先前CubeMX设定计算,应可由示波器得到PWM duty为10%的波形

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	  Value_PWMDuty = 400;
	  HAL_Delay(250);
	  TIM3->CCR4 = Value_PWMDuty;
  }
  /* USER CODE END 3 */

如main.c所设定,图中显示GPIO High / Low动作达到预期1KHz与10% duty的条件。
可得知ADC已依照设定的取样率工作。
https://ithelp.ithome.com.tw/upload/images/20211018/20143021HUKR8548DR.png

若将Value_PWMDuty持续修改参数,亦可得到对应的duty设定。


为了确认此GPIO所对应PWM是否正确,将由CubeMX增加设定TIMER3 CH2 为PWM output,以实际脚位pin12观察两个PWM关系。

由上视窗可以看见,两PWM波形几乎是同步运作。
https://ithelp.ithome.com.tw/upload/images/20211018/20143021iwLfQSlyup.png
但实际放大後发现,两PWM中间存在延迟,就是所谓TIMER触发ADC而DMA取样1次的时间。

验证後产生问题

回到CubeMX中设定ADC1的参数Sampling Time,将会影响ADC转换时间,而影响DMA後续触发延迟。

更进一步发现,当Value_PWMDuty设定为过小,则由HAL_ADC_ConvCpltCallback函数触发的GPIO将异常。
此部份认为,因为TIMER3 CH2的duty已经小於ADC转换时间,所以只能抓到一次触发。

小记

本篇目的不是在ADC部分,而是如何结合TIMER触发ADC,同时可以触发中断副程序,使得可以在中断副程序里添加要实现的功能,但发现当设定duty过小於ADC转换时间时,就会出现异常。
结论判定此方式并不完全适合目前所需用功能


若此文章对您有帮助或学习,欢迎加入likecoin赞赏公民,下方连结点击like支持~

https://button.like.co/jm-ysys18


本文参考

https://www.wpgdadatong.com/tw/blog/detail?BID=B0956


<<:  活动图教程

>>:  【从零开始的 C 语言笔记】第三篇-基本的程序结构介绍 & 列印三角形

第14天 - PHP 简易登入(1)_HTML的部分

首先把之见前建立的 表staff 加入【密码栏位】。 (为了方便,密码都设个位数XD) (以下凭我印...

四招解决Spotify 黑画面问题!--〖2022亲测有效〗

Spotify 打开时是黑屏的怎麽办?明明老版本还是可以正常使用的,为什麽更新後Spotify会出现...

Chapter5 - 不介意的话,请玩玩看这个Canvas游戏!试图拾回一片片的落叶,拯救这颗树吧

(10/11更)私下有一些朋友反应手机不太能玩,我才想起这个问题,所以有对此demo在长版进行微调...

理解网际网路协定(一):何谓 IP Address

前面提到了一些 Router 连网所需的设定,有 PPPoE、DHCP 以及 Static 这几种类...

DAY22神经网路

昨天介绍完DBSCAN程序,今天要来研究神经网路: (来源: http://programmerma...