完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
高级定时器功能简介
高级定时器对应为 TIM1/8 比基本定时器多了外部引脚,可以实现输入捕获,输出比较和互补输出,其有16为位计数器,可上下,两边计数,拥有重复计数器RCR。时钟来自 PCLK2 , 为72M. 功能框图 整个框图非常大,分为6个部分逐步讲解。 1.时钟源 内部时钟源 CK_INT 内部时钟源由RCC引入,挂载在 APB2 总线上,为72M,具体可见RCC时钟树。 外部时钟1,2 外部时钟的时钟信号来自第四部分的外部引脚,外部时钟1的具体框图如下: 外部的信号经过滤波器,边沿检测器和两个数据选择器后,直接作为CK_PSC驱动定时器,这些元件下面就是控制它的寄存器及其对应位。使用较少。 2.控制器 控制器用来控制,发送命令,主要对应了 CR1,CR2,SMCR,CCER. 3.时基 时基和基本定时器一致,具体参考基本定时器。 相较基本定时器,高级定时器多了一个重复寄存器。在计数器计到ARR的值时,计数器清零,但不产生中断,重复寄存器会根据计数器的模式自动加一或减一,当重复寄存器达到设定值时,产生中断。 4.输入捕获 输入捕获可以捕获输入信号的边沿,进而可测量输入信号的脉宽,频率和占空比。 大致原理为:当检测到第一个上升沿时,CNT开始计数;检测到下降沿,产生中断,CNT的值被锁存到CCR寄存器中;CCR寄存器的值就是高电平时间。 输入通道 当被测信号从定时器外部引脚输入 TIMx_CH1/2/3/4 时,把这些引脚记为 TI1/2/3/4. 输入滤波和边沿检测 滤波用于滤去高频干扰或用于降频;边沿检测用于指定边沿有效性,如:设置上升沿有效的意思为当输入为上升沿时,边沿检测器输出高电平。 捕获通道 捕获通道实际上是一个数据选择器;框图中可以看到,一个输入通道可以同时输入给两个捕获通道,这种使用方式就可以捕获PWM。当使用PWM捕获时,只能使用TI1/2. 预分频器 ICx的输出信号会经过预分频器,用于决定发生多少次事件进行一次捕获。若希望每个边沿都捕获则不分频。 捕获寄存器 最终捕获到的信号,当发生捕获时,计数器CNT的值会被锁存到CCR中,还会产生CCxI中断,相应CCxIF标志位置位。当软件读取CCR值时,标志位清零。 若未清零,又一次发生捕获,则溢出标志位CCxOF会置位,CCxOF只能软件清零。 5.输出捕获 输出PWM波,同样用到CNT,CCR,ARR寄存器。CNT从0开始计数,当计到CCR的值时,输出捕获寄存器输出电平发生一次跳变,计到ARR时,再次跳变。 由此输出PWM波,ARR决定周期,CCR决定占空比。事实上,输出和输入捕获寄存器是同一个。 由输出寄存器输出的信号需要经过死区寄存器输出。死区寄存器会使得输出的信号有一定的延时,这是为了照顾外部MOS管开启和关闭的延时。死区的延时时间可以在 TIMx_CR1 寄存器中配置。 经过死区后,通过输出控制部分输出信号。 捕获的应用 如图:为通道1的输入捕获框图,标出蓝色的为其对应的寄存器和其对应位。 输入捕获 测量频率 当TIx出现上升沿,发生第一次捕获,CNT的值锁存在CCR,在中断中记录这次中断,记录CCR的值。出现第二次上升沿,重复上述过程,把两次的值相减即为周期,取倒数得到频率。 对应寄存器的操作为: 配置滤波器带宽,配置 TIMx_CCER 的 IC1F=0011 。(按实际需要配置) 配置边沿检测器,配置 TIMx_CCER 的 CC1P=1 ,表示上升沿有效。 选择输入有效端,配置TIMx_CCMR1寄存器的CC1S=01,表示CC1通道被设置为输入,且IC1映射到TI1上(即通道捕获器选取TI1作为输入) 配置输入预分频器,配置 TIMx_CCMR1 的 IC1PS=00,表示不分频。 测量脉宽 和测量频率一致,只是第二次中断由下降沿产生。 PWM输入模式 这个模式只能使用通道1或2。一个输入通道占用两个捕获通道。 信号从TI1进入后,被分为两路,分别进入两个捕获通道。设置触发极性即可设置某路代表的数值是周期或占空比;当设置一路的极性时,另一路极性和其相反,即设置一路为周期时,另一路就是占空比。 用一个时序图说明: 当输入信号第一次上升沿时,IC1和IC2同时捕获,计数器清零。第一个下降沿来临时,IC2捕获,计数器的值被锁存在CCR2;第二个上升沿来到时,IC1捕获,计数器的值被锁存在CCR1;此时,CCR2+1是高电平脉宽,CCR1+1为周期。(因计数器从0计数,+1是必要的) 当使用PWM输入模式时,启动触发信号开始捕获时,要把计数器CNT复位清零,这一点可以由SMCR寄存器的SMS位完成。 固件库编程 stm32f10x_tim.h 中定义的四种初始化结构体,分别为时基,输出比较,输入捕获和断路死区结构体。其中基本定时器只用了时基,通用定时器不能用断路死区结构体。由此,我们开始介绍。 时基初始化结构体 typedef struct { uint16_t TIM_Prescaler; //预分频器 uint16_t TIM_CounterMode; //计数模式 uint16_t TIM_Period; //ARR uint16_t TIM_ClockDivision; //时钟分频 uint8_t TIM_RepetitionCounter; //重复计数器 } TIM_TimeBaseInitTypeDef; TIM_ClockDivision用于控制死区时间,滤波器采样时钟分频。重复计数器只有8位。 输出比较结构体 typedef struct { uint16_t TIM_OCMode; //输出模式 uint16_t TIM_OutputState; //输出使能 uint16_t TIM_OutputNState; //互补输出使能 uint16_t TIM_Pulse; //脉冲宽度 uint16_t TIM_OCPolarity; //输出极性 uint16_t TIM_OCNPolarity; //互补输出极性 uint16_t TIM_OCIdleState; //空闲下的输出状态 uint16_t TIM_OCNIdleState; //空闲下互补输出状态 } TIM_OCInitTypeDef; 输出共有8中模式,最常用的是PWM1/2. 输入捕获结构体 typedef struct { uint16_t TIM_Channel; //输入通道选择 uint16_t TIM_ICPolarity; //边沿检测器 uint16_t TIM_ICSelection; //输入捕获选择 uint16_t TIM_ICPrescaler; //输入捕获预分频器 uint16_t TIM_ICFilter; //输入捕获滤波器 } TIM_ICInitTypeDef; TIM_Channel 用于选择ICx,可选择的通道有 TI1/2/3/4.若为PWM模式,只能使用TI1或TI2。 TIM_ICSelection 用于选择ICx的输入通道,有三条通道可选。 开始编程 高级定时器互补输出,带有死区和刹车功能。输出频率为1M,占空比为50%的pwm波。 硬件设计 高级和通用定时器的引脚总结如下表: 要注意的是,使用高级定时器的输入引脚时,一定要保证引脚的“洁净”,就是输入引脚不要连接其他设备,只是用作输入,这样可以最大限度保证输入检测的准确。 这里我们使用TIM1,使用PA8,PB13作为CH1(输出)和CH1N(互补),PB12作为 BKIN (刹车)。 初始化GPIO void ADVANCE_TIM_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitSturct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); //CH1 GPIO_InitSturct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitSturct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitSturct.GPIO_Pin = GPIO_Pin_8; GPIO_Init(GPIOA,&GPIO_InitSturct); //CH1N GPIO_InitSturct.GPIO_Pin = GPIO_Pin_13; GPIO_Init(GPIOB,&GPIO_InitSturct); //BKIN GPIO_InitSturct.GPIO_Pin = GPIO_Pin_12; GPIO_Init(GPIOB,&GPIO_InitSturct); //让BKIN输出低电平 GPIO_ResetBits(GPIOB,GPIO_Pin_12); } 输出和刹车引脚为复用推挽输出,最后让刹车引脚输出低电平。 定时器模式配置 定时器需要配置时基,输入捕获和刹车。 时基配置 static void ADVANCE_TIM_Mode_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); /*********************TIM_BASE*********************************/ TIM_TimeBaseStruct.TIM_Period = 7; //ARR TIM_TimeBaseStruct.TIM_Prescaler = 8; //PSC TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStruct); } 配置ARR = 7,PSC = 8.当使用内部时钟频率,由频率计算公式,可知配置的频率为1M. TIM_ClockDivision 是用来配置死区时间的,先配置为1分频。这里不使用重复计数器,因此配置为0. 配置输出捕获 TIM_OCInitTypeDef TIM_OCInitStruct; /***********************TIM_OC**********************************/ TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStruct.TIM_Pulse = 4; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC1Init(TIM1,&TIM_OCInitStruct); TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);//使能自动重装载 配置输出模式为PWM1,使能输出和互补输出。 配置脉宽为4,这一位配置的是CCR寄存器的值,根据配置的不同可以控制占空比,上面配置了ARR为7,则现在占空比为。 配置输出和互补高电平有效,空闲时,输出为高电平有效,互补电平低电平。 最后初始化输出配置,互补输出不用初始化。使能自动重装载。 死区刹车 /***********************TIM_BD**********************************/ TIM_BDTRInitStruct.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStruct.TIM_DeadTime = 11; TIM_BDTRInitStruct.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStruct.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStruct.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStruct); 前两条语句设置运行或空闲时,启动刹车后引脚对应输出效果。TIM_LOCKLevel设置写保护级别。 TIM_DeadTime 配置死区时间为152ns,TIM_Break 使能刹车。TIM_BreakPolarity 配置什么事件导致刹车,配置为高电平导致刹车(即PB12高电平时,刹车)。 完整代码 static void ADVANCE_TIM_Mode_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_OCInitTypeDef TIM_OCInitStruct; TIM_BDTRInitTypeDef TIM_BDTRInitStruct; RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); /*********************TIM_BASE*********************************/ TIM_TimeBaseStruct.TIM_Period = 7; //ARR TIM_TimeBaseStruct.TIM_Prescaler = 8; //PSC TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStruct); /***********************TIM_OC**********************************/ TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStruct.TIM_Pulse = 4; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC1Init(TIM1,&TIM_OCInitStruct); TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);//自动重装载 /***********************TIM_BD**********************************/ TIM_BDTRInitStruct.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStruct.TIM_DeadTime = 11; TIM_BDTRInitStruct.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStruct.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStruct.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStruct); TIM_Cmd(TIM1,ENABLE); TIM_CtrlPWMOutputs(TIM1,ENABLE);//主使能 } 最后使能定时器,高级定时器需要主输出使能。 封装 void ADVANCE_TIM_Init(void) { ADVANCE_TIM_GPIO_Config(); ADVANCE_TIM_Mode_Config(); } main函数 int main(void) { ADVANCE_TIM_Init(); while(1) { } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1817 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1631 浏览 1 评论
1103 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
739 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1692 浏览 2 评论
1951浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
754浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
585浏览 3评论
605浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
568浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-30 09:24 , Processed in 1.014326 second(s), Total 77, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号