STM32F407野火霸天虎系列笔记(六)高级定时器

STM32F407野⽕霸天虎系列笔记(六)⾼级定时器
⼀、前⾔
我在学习的过程中,经历过毫⽆头绪,到⼀堆学习资料却不知从何开始的痛苦。我希望我整理的笔记,不光可以⽅便⾃⼰在以后的项⽬中拿来即⽤,也希望能够对那些喜欢玩硬件、爱折腾的⼩伙伴有所帮助。如果你们觉得我的⽂章对你们有⽤,欢迎⼤家点赞+收藏,让我知道,我的⼯作是有价值的。
这篇笔记,综合参考了野⽕、正点原⼦、st官⽅以及⽹络上的⼀些资料,然后经过我⾃⼰的思考、尝试与实践,从⽽整理出来的。感谢那些愿意在学习的路上分享⾃⼰知识与经验的前辈。
⼆、代码和理论
(⼀)、PWM输出编程思路
1.定时器GPIO初始化
选⽤三个引脚,输出引脚,互补输出引脚,断路输⼊引脚,配置好引脚相关参数,选择复⽤功能,再连接好各个引脚的复⽤功能。
/*定义⼀个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/*开启定时器相关的GPIO外设时钟*/
RCC_AHB1PeriphClockCmd (ADVANCE_OCPWM_GPIO_CLK | ADVANCE_OCNPWM_GPIO_CLK| ADVANCE_BKIN_GPIO_CLK, ENABLE);
/* 指定引脚复⽤功能 */
GPIO_PinAFConfig(ADVANCE_OCPWM_GPIO_PORT,ADVANCE_OCPWM_PINSOURCE, ADVANCE_OCPWM_AF);
GPIO_PinAFConfig(ADVANCE_OCNPWM_GPIO_PORT,ADVANCE_OCNPWM_PINSOURCE,ADVANCE_OCNPWM_AF);
GPIO_PinAFConfig(ADVANCE_BKIN_GPIO_PORT,ADVANCE_BKIN_PINSOURCE,ADVANCE_BKIN_AF);
/* 定时器功能引脚初始化 */
GPIO_InitStructure.GPIO_Pin = ADVANCE_OCPWM_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(ADVANCE_OCPWM_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = ADVANCE_OCNPWM_PIN;
GPIO_Init(ADVANCE_OCNPWM_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = ADVANCE_BKIN_PIN;
GPIO_Init(ADVANCE_BKIN_GPIO_PORT, &GPIO_InitStructure);
2.定时器时基结构体TIM_TimeBaseInitTypeDef初始化
⾼级定时器属于APB2,内部时钟是168MHZ,在时基结构体中我们设置定时器周期参数为1000,频率为1MHz,使⽤向上计数⽅式。因为我们使⽤的是内部时钟,所以外部时钟采样分频成员不需要设置,重复计数器我们没⽤到,也不需要设置。
Period(定时器周期)范围是0~65535
ClockDivision(时钟分频)设置定时器时钟CK_INT频率与死区发⽣器以及数字滤波器采样时钟频率分频⽐。可以选择1、2、4分频。
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
// 开启TIMx_CLK,x[1,8]
RCC_APB2PeriphClockCmd(ADVANCE_TIM_CLK, ENABLE);
/* 累计 TIM_Period个后产⽣⼀个更新或者中断*/
氧空位//当定时器从0计数到1023,即为1024次,为⼀个定时周期,可以⾃⼰定义  TIM_TimeBaseStructure.TIM_Period = 1024-1;
// ⾼级控制定时器时钟源TIMxCLK = HCLK=168MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100000Hz
TIM_TimeBaseStructure.TIM_Prescaler = 1680-1;
// 采样时钟分频,配置死区时间要⽤到
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数⽅式,向上
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 重复计数器,没⽤到不⽤管
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
// 初始化定时器TIMx, x[1,8]
王冠石TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);
3.定时器输出⽐较结构体TIM_OCInitTypeDef初始化ChannelPulse是调节占空⽐的⼤⼩可以⾃⼰定义
配置完成后要使能通道,和使能定时器
TIM_OCInitTypeDef  TIM_OCInitStructure;
/
*PWM模式配置*/
//配置为PWM模式1,常⽤的为PWM1/PWM2
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //脉冲宽度,范围为0⾄65535
TIM_OCInitStructure.TIM_Pulse = ChannelPulse;
//可选择⾼电平还是低电平有效,决定着定时器通道有效电平
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;  //使能通道1
TIM_OC1Init(ADVANCE_TIM, &TIM_OCInitStructure);
/* 使能通道1重载 */
TIM_OC1PreloadConfig(ADVANCE_TIM, TIM_OCPreload_Enable);
4.定时器刹车和死区结构体TIM_BDTRInitTypeDef初始化
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
/* ⾃动输出使能,断路、死区时间和锁定配置 */
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 11;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(ADVANCE_TIM, &TIM_BDTRInitStructure);
// 使能定时器
TIM_Cmd(ADVANCE_TIM, ENABLE);
/* 主动输出使能 */
TIM_CtrlPWMOutputs(ADVANCE_TIM, ENABLE);
(⼆)、PWM输⼊编程思路
1.初始化相关GPOI⼝(连接通⽤定时器和⾼级定时器的)
/*定义⼀个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/
*开启LED相关的GPIO外设时钟*/
RCC_AHB1PeriphClockCmd (GENERAL_OCPWM_GPIO_CLK, ENABLE);
RCC_AHB1PeriphClockCmd (ADVANCE_ICPWM_GPIO_CLK, ENABLE);
/* 定时器复⽤引脚 */
GPIO_PinAFConfig(GENERAL_OCPWM_GPIO_PORT,GENERAL_OCPWM_PINSOURCE,GENERAL_OCPWM_AF);  GPIO_PinAFConfig(ADVANCE_ICPWM_GPIO_PORT,ADVANCE_ICPWM_PINSOURCE,ADVANCE_ICPWM_AF);
/* 通⽤定时器PWM输出引脚 */
GPIO_InitStructure.GPIO_Pin = GENERAL_OCPWM_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GENERAL_OCPWM_GPIO_PORT, &GPIO_InitStructure);
太极图解/* ⾼级控制定时器PWM输⼊捕获引脚 */
GPIO_InitStructure.GPIO_Pin = ADVANCE_ICPWM_PIN;
GPIO_Init(ADVANCE_ICPWM_GPIO_PORT, &GPIO_InitStructure);
2.通⽤定时器产⽣PWM配置
再通⽤定时器中配置时基结构体和输出结构体初始化
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
// 开启TIMx_CLK,x[2,3,4,5,12,13,14]
RCC_APB1PeriphClockCmd(GENERAL_TIM_CLK, ENABLE);
/* 累计 TIM_Period个后产⽣⼀个更新或者中断*/
/
/当定时器从0计数到9999,即为10000次,为⼀个定时周期
TIM_TimeBaseStructure.TIM_Period = 10000-1;
// 通⽤定时器2时钟源TIMxCLK = HCLK/2=84MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
TIM_TimeBaseStructure.TIM_Prescaler = 840-1;
// 采样时钟分频
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数⽅式
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 初始化定时器TIMx, x[1,8]
TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure);
/
* PWM输出模式配置 */
/* 配置为PWM模式1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
/* PWM脉冲宽度 */
TIM_OCInitStructure.TIM_Pulse = 3000-1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* 使能通道1 */
TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure);
/*使能通道1重载*/
TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);
/
内部错误
/ 使能定时器
TIM_Cmd(GENERAL_TIM, ENABLE);
}
3.⾼级定时器PWM输⼊配置
再⾼级定时器中配置时基结构体,输⼊捕获结构体,从模式结构体初始化
先选定捕获通道IC1和IC2通道1,捕获周期,通道2,捕获占空⽐
I2C作为间接输⼊模式,我们需要配置他的从模式,即从模式复位模式,定时器触发源为TIM_TS_TI1FP1,最后使⽤函数HAL_TIM_SlaveConfigSynchronization进⾏配置。
static void TIM_PWMINPUT_Config(void)
{
//初始化三个结构体,时基结构体,输⼊捕获结构体,模式结构体
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_ICInitTypeDef  TIM_ICInitStructure;
一倍体// 开启TIMx_CLK,x[1,8]
RCC_APB2PeriphClockCmd(ADVANCE_TIM_CLK, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF-1;
// ⾼级控制定时器时钟源TIMxCLK = HCLK=168MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
TIM_TimeBaseStructure.TIM_Prescaler = 1680-1;
// 计数⽅式
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 初始化定时器TIMx, x[1,8]
TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);
/
* IC1捕获:上升沿触发 TI1FP1 */
TIM_ICInitStructure.TIM_Channel = ADVANCE_IC1PWM_CHANNEL;peek
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(ADVANCE_TIM, &TIM_ICInitStructure);
/* IC2捕获:下降沿触发 TI1FP2 */
TIM_ICInitStructure.TIM_Channel = ADVANCE_IC2PWM_CHANNEL;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(ADVANCE_TIM, &TIM_ICInitStructure);
//当⼯作在PWM输⼊模式时,只需要设置触发信号的那⼀路即可(⽤于测量周期)//另⼀路(⽤于测量占空⽐)会有硬件⾃动设置,不需要再配置
/* 选择定时器输⼊触发: TI1FP1 */
TIM_SelectInputTrigger(ADVANCE_TIM, TIM_TS_TI1FP1);
/* 选择从模式: 复位模式 */
TIM_SelectSlaveMode(ADVANCE_TIM, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(ADVANCE_TIM,TIM_MasterSlaveMode_Enable);
/* 使能⾼级控制定时器 */
TIM_Cmd(ADVANCE_TIM, ENABLE);
/* 使能捕获/⽐较2中断请求 */
TIM_ITConfig(ADVANCE_TIM, TIM_IT_CC1, ENABLE);
4.计算测量的频率和占空⽐,打印出来⽐较

本文发布于:2024-09-20 20:35:46,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/357020.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:模式   引脚   时钟   配置   结构   学习   输出
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议