以TIMER为主要观察源,使用TIMER触发ADC,透过DMA结合,同时观察ADC中断副程序,进而延伸不同领域应用。
STM32G4系列ADC支援多样的触发取样方式,可以利用Timer和GPIO做触发。
以STM32G431为例,除了软件触发外还支援下列来源的触发。
这个范例,采用TIMER3 CC4作为ADC触发讯号观察。
在STM32CubeMX中,首先对ADC做设置如下。
先建立ADC通道,再开启DMA通道,透过DMA可使ADC完全触发於被动状态。
设定ADC相关功能(另外说明),与开启DMA。
以TIMER3 CC4作为ADC触发讯号观察,设定对应选项。
ADC与DMA结合设定完成,接下来只需将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支持~
本文参考
>>: 【从零开始的 C 语言笔记】第三篇-基本的程序结构介绍 & 列印三角形
首先把之见前建立的 表staff 加入【密码栏位】。 (为了方便,密码都设个位数XD) (以下凭我印...
Spotify 打开时是黑屏的怎麽办?明明老版本还是可以正常使用的,为什麽更新後Spotify会出现...
(10/11更)私下有一些朋友反应手机不太能玩,我才想起这个问题,所以有对此demo在长版进行微调...
前面提到了一些 Router 连网所需的设定,有 PPPoE、DHCP 以及 Static 这几种类...
昨天介绍完DBSCAN程序,今天要来研究神经网路: (来源: http://programmerma...