前言
以TIMER为主要观察源,使用TIMER触发ADC,透过DMA结合,同时观察ADC中断副程式,进而延伸不同领域应用。
内容
STM32G4系列ADC支援多样的触发取样方式,可以利用Timer和GPIO做触发。
以STM32G431为例,除了软体触发外还支援下列来源的触发。
_ / CubeMX设定ADC \
这个範例,採用TIMER3 CC4作为ADC触发讯号观察。
在STM32CubeMX中,首先对ADC做设置如下。
先建立ADC通道,再开启DMA通道,透过DMA可使ADC完全触发于被动状态。
设定ADC相关功能(另外说明),与开启DMA。
以TIMER3 CC4作为ADC触发讯号观察,设定对应选项。
外部触发来源更改为Timer 3 Capture Compare 4 event并选择上下缘触发ADC与DMA结合设定完成,接下来只需将TIMER完成设定即可完成此次实验与观察目的。
__ / CubeMX设定TIMER \
设定Timer 3 Channel 4为PWM,因为不需要从硬体pin脚输出波形。
只需要产生对应的事件event,所以设置为PWM Generation No Output。
若需要观察TIME3 CH4对应波形,也可选择PWM Generation CH4,观察后再关闭即可。
此次範例设计1KHz PWM输出,对应主频170MHz,TIMER基础设定如下。
完成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已依照设定的取样率工作。
若将Value_PWMDuty持续修改参数,亦可得到对应的duty设定。
为了确认此GPIO所对应PWM是否正确,将由CubeMX增加设定TIMER3 CH2 为PWM output,以实际脚位pin12观察两个PWM关係。
由上视窗可以看见,两PWM波形几乎是同步运作。
但实际放大后发现,两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