完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
高级时钟控制定时器TIM1&TIM8简介:
STM32F4的高级控制定时器包含一个自动重装载计数器,计数器的输入是一个被预分频的系统时钟。 这个定时器有多种用途,包括车辆输入信号长度(输入捕获模式)或者产生波形输出(输出捕获,PWM,带死区插入的互补PWM输出等) 脉冲长度和波形周期可在通过定时器的预分频器或者RCC的预分频器在几个微秒时钟内调整。 高级控制定时器和通用定时器完全独立,不共享任何资源。 高级时钟控制定时器TIM1&TIM8的主要特性: 1、16位向上、向下、双向自动重装载计数器2、16位预分频器,分频值从1打655353、4个独立通道4、带死去输出的互补输出5、控制外部信号的同步电路6、刹车输入7、产生中断和DMA强求8、可外部触发 等等。。 TIM定时器确实很强大。至于怎么用,ST的手册不出奇的难看,完全没有条理可言。昨天看一天,都没明白是在说什么。配套的固件库也是,各种函数的介绍,函数名结构体定义完全没有逻辑可言。于是只能参照网友的介绍,从最基础的部分弄起。 【实验1、TIM1的计时功能】 【实验描述】 利用TIM1的技术功能,产生2Hz的中断每次中断LED1反转,LED1反转频率为1Hz。 根据时钟配置,系统时钟为168MHz,APB2时钟为84MHz。TIM1挂接在APB2上,所以APB2 时钟为84MHz。 因此预分频系数设置成了10000即0x2710,自动重装载计数器ARR(TIM_Period)设置成了4200即0x1068。每次计数满产生中断。 中断频率f= 84MHz /4200 / 10000 = 2Hz 【代码实现】 1、首先开启TIM1的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); 2、时基单元的初始化 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 0x1068; TIM_TimeBaseInitStructure.TIM_Prescaler = 0x2710; TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00; TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure); TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure); TIM_ClearFlag(TIM1,TIM_FLAG_Update); //必须先清除配置时候产生的更新标志 TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE); //使能中断,中断事件为定时器工薪事件 TIM_Cmd(TIM1,ENABLE); //使能定时器 3、中断处理函数 没什么可说的,反转LED灯而已。每次中断反转一次,2Hz的中断产生1Hz的闪烁。 中断名字是库里边定义的,跟TIM10全局中断公用。 void TIM1_UP_TIM10_IRQHandler(void) { TIM_ClearFlag(TIM1,TIM_FLAG_Update);//进入中断先清除更新标志 LEDTog(LED1); } 之后我们就可以看到LED以大约1Hz的频率在闪烁了。 【实验2、强制输出模式实验】 百度来的强制输出模式的定义:在程序编程中,IO口一般都可以作为输入输出的。而有些数据要在让其执行时候必须执行,所以让其强制性的输出。这是IO口只能做一件事。 看完之后还是一头雾水。 简单 点说,就是不管当时IO输出的是什么,都能强制将其设为0或者为1. 【实验描述】 为了实验方便,这个实验使用TIM4的强制输出功能,点亮与GPIOD Pin13引脚相连的LED3。对于强制输出功能,高级定时器和通用定时器是完全一样的。 TIM4的CH2被复用在GPIOD 的Pin13。所以可以将这个输出强制为高,将LED点亮。 【代码实现】 1、首先将GPIO初始化为AF复用功能。 CM4的引脚复用功能和CM3的实现方法不同,要特别注意。按照CM3的写法将不会有输出 void TIM4_GPIO_Config(void) { GPIO_InitTypeDef GPIO_initStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); GPIO_initStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_initStructure.GPIO_OType = GPIO_OType_PP; GPIO_initStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_initStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_initStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOD,&GPIO_initStructure); GPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD,GPIO_PinSource13,GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_TIM4); } 2、TIM4的初始化 这里的时钟我没有计算,因为这个实验不太关注这个。 void TIM4_Config1(void) { TIM4_GPIO_Config(); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period =0x1068; TIM_TimeBaseInitStructure.TIM_Prescaler = 0x2710; TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00; TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure); TIM_ARRPreloadConfig(TIM4,ENABLE); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Active;; //设置成什么模式都行。 TIM_OCInitStructure.TIM_Pulse= 1000; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OC2Init(TIM4,&TIM_OCInitStructure); TIM_Cmd(TIM4,ENABLE); } 3、在主函数中强制输出。 初始化完成之后,在任何时候都能强制引脚电平,只需要一个函数即可: TIM_ForcedOC2Config(TIM4,TIM_ForcedAction_Active); 这个函数设置TIM的CCMR1的OCxM位为101或者100实现输出的拉高或拉低 【实验三、比较输出】 一直不理解这里的比较是哪两个东西在进行比较。今天翻ST参考手册 reference manual发现这么句话: 当OCxM位为000时:The comparison between the output compare register TIMx_CCR1 and the counter TIMx_CNT has no effect on the outputs. 即这里的“比较”是TIMx_CCR1和TIMx_CNT的比较。两个相等时,触发事件。这个事件发生时,TIm根据CCMRx寄存器的OCxM位进行输出。 结合库中的定义,可以很方便地改变输出方式: #define TIM_OCMode_Timing ((uint16_t)0x0000) #define TIM_OCMode_Active ((uint16_t)0x0010) #define TIM_OCMode_Inactive ((uint16_t)0x0020) #define TIM_OCMode_Toggle ((uint16_t)0x0030) #define TIM_OCMode_PWM1 ((uint16_t)0x0060) #define TIM_OCMode_PWM2 ((uint16_t)0x0070) 【实验现象】 LED周期闪烁 【代码实现】 只需要将上边的代码中的TIM_OCMode改成PWM即可。 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; 参数TIM_Pulse对这种模式没影响,TIM_OCPolarity只影响先输出的是低电平还是高电平。 【实验4、PWM输出】 这是输出部分的传统了。所有的开发板的TIM例子都是一个PWM输出。 时基单元好了,设置一下输出模式,反转时机(TIM_Pulse)。然后开启哥哥通道的OC即可。对于每个Tim的所有通道,由于时基配置是一样的所以只能改变各个通道的占空比。 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM2也行 TIM_OCInitStructure.TIM_Pulse= 2000;//CCR,设置占空比。反转模式时候无效 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_ClearFlag(TIM4,TIM_FLAG_CC2); TIM_OC2Init(TIM4,&TIM_OCInitStructure); 当然,引脚初始化不能少的。 【实验5、单脉冲方式】 只需要在上边的代码之后加一句: TIM_SelectOnePulseMode(TIM4,TIM_OPMode_Single); 这样讲产生一个负脉冲,效果是LED灭一下之后保持常亮。如果要要让LED亮一下,输出正脉冲还需要改下输出的极性: TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; 到这里,TIM控制输出的实验基本就做完了。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1936浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
729浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
569浏览 3评论
594浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
552浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 20:26 , Processed in 0.936544 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号