完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
定时器
定时器原理 原理 本质上就是一个记录脉冲数量的计数器,当记的数达到上限时会发生“溢出”,计时器清零同时产生一个信号,这个信号可以代表很多事件,定时器中断就是其一。 定时器的功能有输出比+和输入捕获两种,输出比较就是定时和PWM功能等,输入捕获用于测量。 分频器(PSC)的原理 如果只是使用时钟信号作为基本的脉冲进行计数,虽然精度相当高,但是计数的最大时间受到了很大的限制,因此引入了分频的概念。分频,本质上就是在时钟和定时器中间再加上一个定时器,这个定时器就叫做分频器,定时器实际上记录的脉冲是分频器传递出来的脉冲。 自动重载寄存器(ARR) 如果只是使用定时器与分频器,那么为了获得非最大时间的定时,就需要在定时器开始计时的时候设置一个初始时间,ARR解决了这个问题,它相当于降低了计时器的最大时间,让计时器到指定的时间就发生溢出。 定时器PWM原理 PWM(脉宽调制)的原理:通过调节矩形脉冲的占空比,达到控制输出量大小(等效大小)的目的。如果占空比一直不变,常用来做亮度调整、电机速度调整等。如果占空比随时改变,常用来模拟正弦量等连续信号(逆变)。 定时器PWM的原理: 原理有输入捕获和输出比较两个部分。为了通过定时器实现PWM功能,指定了一个GPIO引脚为捕获/比较引脚,同时添加一个捕获/比较寄存器(CCR)。 输出比较原理:给捕获/比较寄存器一个值,这个值介于零与ARR之间。计数分频后的脉冲,当计数达到CCR的值时,捕获比较引脚的电平状态进行翻转,同时产生一个捕获比较事件(Capture Compare),脉冲计数继续进行。当脉冲计数达到ARR的值时,定时器清零,因定时器的值再次小于CCR所以捕获比较引脚状态再次翻转,同时产生一个更新事件(Updata)。 输入捕获原理:输入捕获有两种方法,T法与M法,都是用来测量外部输入的脉冲的频率的。 CubeMX的操作 定时功能的设置(对应Updata事件) 在“Pinout & Configuration”界面下,左侧选择下拉菜单“Timers”,下拉菜单中“TIM1”到“TIM8”都是定时器,选择一个定时器,中间的界面里出现对应的窗口。 第三个选项“Clock Source”选择“Internal Clock”内部时钟。内部时钟的频率在“Clock Configuration”界面下,“HCLK(MHz)”后面的“APB1”和“APB2”后面的“APB1/2 timer clocks”中设置,至于哪个定时器属于哪个APB,需要查询数据手册。 在Mode窗口下面的Configuration窗口里,第一个菜单,第一个下拉菜单里第一项PSC,这里设置PSC的值。注意, 分 频 值 = 1 + P S C 分频值=1+PSC 分频值=1+PSC,分频后的等效频率就相当于原始频率乘以分频值分之一,这里PSC的值与分频值之所以不一样,是因为PSC在最后一个脉冲到来后才会进位。 第三个选项设置ARR的值,从ARR的名字,或者点击右上角的“i”按钮后在点击ARR那一行,可以看到ARR的位数,也就相当于是定时器的位数。设置PSC和ARR的时候要综合考虑将来要设置的定时时间。同样的,要计数5000次的话,ARR应该设置4999。 举例:假设我选择定时器2(TIM2),内部时钟。考虑到我要定时500ms,那么就需要选择7199PSC,即等效时钟为10kHz,一次脉冲相当于0.1+ms。因此,我需要计数5000次,那么ARR就需要设置为4999。这样一来,ARR的值没有超过限制,PSC的值也没有超过限制(位数的限制),次设置就是合理的。而如果PSC设置为71,等效频率1MHz,那么即使ARR调到最大,计时也只有一百多ms而已。 定时器中断的设置 设定好定时器的定时功能后,它在每次定时到了归零的时候,都会产生一个Updata事件,这个时候如果开启定时器全局中断,就可以在中断服务函数里面寻找处理Updata事件的中断回调函数进行中断的处理。 NVIC Settings菜单下勾选定时器全局中断。这里其实也可以在左侧的NVIC菜单中设置,设置方式与打开外部中断的方式一致,顺便还可以设置优先级。 定时器触发外部设备(Trigger Out事件) 在Mode窗口下面的Configuration窗口里,第一个菜单,第二个下拉菜单“Trigger Output (TRGO) Parameters”就是该事件的设置菜单。 第一个选项“Master/Slave Mode(MSM bit)”是让定时器既做主机触发别人,又做从机被别人触发,一般不选。 第二个选项就是选择由说明事件触发Trigger Out事件,Trigger Out事件就是定时器向外发送的一个信号,可以用来触发别的外设。 输入捕获的设置 在定时器的配置界面中,随便选择一个通道,设置为“Input Capture direct mode”,即设置为输入捕获模式。 此时下方“Parameter Settings”窗口中出现输入捕获下拉菜单“Input Capture Channel”,第一个选项“Polarity Selection”设置的是捕获目标,默认是上升沿捕获。 第三个选项是分频“Prescaler Division Ratio”选项,一般选择不分频。 第四个选项是数字滤波器滤波次数的选择,就是连续捕获多少次才认为真的出现了目标电平,一般设为8。 对应的输入捕获引脚设置为下拉电阻(根据你要捕获的信号来设置),保证没有目标信号时输入电平的稳定。 打开定时器的全局中断,将来需要在中断里面对捕获到的值进行处理。 PWM功能的设置 与定时器的设置类似,打开定时器的设置界面。在“Mode”界面中,第四个选项(Channel)开始,开启定时器的通道,将通道选择为“PWM Generation CH1”,它是输出比较模式“Ooutput Compare CH1”的一个特例。其中,“CH1”是通道1的意思,有时候只有一个通道,不一定有多个通道。“CH1N”是CH1通道的反相。 PWM定时器定时功能设置:因为PWM功能需要用到定时器的定时功能才能完成输出比较,所以在初始化的时候也需要对定时功能进行设置,一般PWM的频率至少是200Hz,设置方面参考前面对定时功能的描述。 ARR对PWM精确度的影响:ARR的值越大,CCR可以设置的值的范围就越大,PWM就越精确。比如,ARR设置为4999(实际是计数5000次),那么PWM的精度就是五千分之一(CCR取值0到4999)。 CCR的设置:CubeMX中,在Mode窗口下面的Configuration窗口里,在你选择了PWM模式后,这个窗口中会多一个PWM模式的下拉菜单,在里面找到“Pulse”选项,它就是CCR的值。 其他设置选项:PWM的模式选项,是指选择第一个出现的是高电平该是低电平等。“CH Polarity”选项可以选择是用高电平计算的占空比还是低电平。 中断的设置:如果需要捕获比较事件或者更新事件产生中断,就需要再NVIC里面勾选响应的中断。注意,即使不申请中断,PWM也是会生成的。 指定需要的输出口:在参数都设置好了之后,还需要考虑通道的输出口是否是你需要的输出口,STM32中每个定时器的通道对应的GPIO口都是固定的,即每个定时器对应的捕获比较引脚是固定的。因此,要么选择对应的定时器,要么用线将捕获比较引脚与你想要输出的引脚连接起来。注意,连接的时候捕获比较引脚是输出模式的,所以你要用的引脚应该是输入模式的。 Keil5的操作 定时功能的使用 以上的步骤都只是初始化定时器,实际使用时还需要在函数中启用定时器,这里为了使用定时器中断,需要进行两步,即启用定时器和启用定时器中断。这两步可以通过一个函数HAL_TIM_Base_Start_IT(&htim2)解决。(如果只计时不中断可以去掉“_IT”使用另一个开始函数,比如只让定时器定时触发其他外设,不需要中断去做什么事情) 注意:使用上面说的这个函数启用定时器,定时器在定时结束后会进入中断服务函数,之后重置并继续计时,并不会定时一次后就停止。要想只进行一次中断,就需要在中断服务函数的最后关闭定时器中断(继续定时但是不中断)或者关闭定时器时基(不定时了)。 定时器中断服务函数 中断服务函数也在用户应用文件夹下的“芯片型号_it.c”文件中,关键词为TIM2,具体的名字是“TIM2_IRQHandler”。 与外部中断服务函数不同的是,每个定时器都有自己独立的中断服务函数。与外部中断类似的是,定时器的中断服务函数也处理定时器的全部事件,这里我们使用的是Updata事件,所以在函数中寻找对应的if语句,我们需要对里面的回调函数HAL_TIM_PeriodElapsedCallback();进行编辑,编辑方式同外部中断。 这个中断服务函数中写的东西只是占位用的,方式因为一个空的函数而警告用户。所以使用时直接去掉weak,在用户的其他.c文件中编写即可。需要注意的是,判断是否真的是中断,以及清空中断标志位,在之前if语句所在的那个函数里已经完成了。 PWM功能的使用 与定时功能一样,要使用定时器还需要在程序里面启用定时器。如果只使用PWM功能而不使用中断,就需要打开定时器的时基与PWM两个功能,如果还要使用中断,就是开启时基、PWM、中断三个功能,都可以通过一个库函数实现,注意,打开PWM的同时需要指定打开的是哪个通道。以定时器1为例,同时打开时基和PWM通道1的函数是HAL_TIM_PWM_Start(&htim1,CHANNEL_1);。 程序中设置定时器的值 捕获比较寄存器的值(CCR): 把定时器1通道1的CCR设置为200,_HAL_TIM_SET_COMPARE(&htim1,CHANNEL_1,200); 输入捕获功能的使用 使用函数HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);开启定时器的输入捕获模式(带中断),同定时器的其他模式一样,开启后不会自动关闭,需要进行手动关闭。 在中断的.c文件中,寻找定时器的中断服务函数,使用“Go to”功能在里面寻找捕获完成的回调函数,在里面编辑内容。 使用HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1)获取定时器3通道1捕获的值,作为该函数的返回值。注意,一般来说应该在中断中获取捕获的值,否则可能不能及时获取捕获值。 使用__HAL_TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING)设置定时器3通道1的捕获上升沿,最后一个参数就是捕获类型的设置。注意,这是一个预处理指令,因此Keil5可能不会联想出它对应的参数,不过打出最后一个参数的前几行应该就能联想出其他参数。 根据实际需要进行捕获的设置。例如要用T法测量频率,就应该先捕获一个上升沿,再捕获一个上升沿,两次捕获做差并计算频率。之后就可以关闭捕获了,总共进行两次捕获。 我测试的时候曾经半天没有搞出来,捕获到的值始终是0,如果遇到此类问题可以尝试重新创建工程,我推测是工程中的其他功能影响了采样,目前没有研究出具体原因。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1760 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1613 浏览 1 评论
1058 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1670 浏览 2 评论
1932浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
723浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
564浏览 3评论
590浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
548浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-20 12:44 , Processed in 0.924807 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号