时基单元部分
其他部分
时钟源选择部分
重复计数器:可以实现若干个计数周期才触发一次更新事件或更新中断,延长了最大定时时间。
对输出比较模块的升级:对输出比较模块的前三个通道加了额外的死区生成和互补输出功能,用于三相电机,略。
'1. 开启RCC时钟'
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2的时钟(位于APB1总线上)
'2. 选择时基单元的时钟源'
TIM_InternalClockConfig(TIM2); // 选择内部时钟作为时钟源(内部时钟是定时器初始化后的默认时钟源,所以可以不写)
'3. 配置时基单元'
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstruct; // 结构体初始化,然后填入结构体
TIM_TimeBaseInitstruct.TIM_ClockDivision = TIM_DIV1; // 选择滤波器频率分频值
TIM_TimeBaseInitstruct.TIM_CounterMode = TIM_CounterMode_Up; // 选择计数器模式
TIM_TimeBaseInitstruct.TIM_Period =10000 - 1; // 选择ARR自动重装器的值(0-65535)
TIM_TimeBaseInitstruct.TIM_Prescaler = 7200 - 1; // 选择PSC预分频器的值(0-65535)
TIM_TimeBaseInitstruct.TIM_RepetitionCounter = 0; // 选择重复计数器的值(高级定时器才有,配置通用定时器时写0即可)
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitstruct);
'4. 配置输出中断控制'
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
'5. 配置NVIC'
//见EXTI外设
'6. 运行控制'
TIM_Cmd(TIM2, ENABLE);
'7. 定时中断的初始化已完成,编写对应中断函数'
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
'中断需要执行的代码'
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
void TIM_DeInit(TIM_TypeDef* TIMx)
// 重置配置
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitstruct);
// 时基单元初始化(对应----3. 配置时基单元)
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitstruct);
// 初始化结构体变量
xvoid TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct);
xvoid TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitstruct);
void TIM_Cmd(TIM_TypeDef* TIMx, Functionalstate NewState);
// 计数器使能/失能(对应----6. 运行控制)
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, Functionalstate Newstate);
// 中断输出信号使能/失能(对应----4.配置输出中断控制)
xvoid TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_Eventsource);
xvoid TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16 t_TIM_DMABurstlength);
xvoid TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, Functionalstate Newstate);
// 以下6个函数对应----2. 选择时基单元的时钟源
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
// 选择内部时钟
void TIM_ITRxExternalclockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
// 选择ITRx其他定时器的时钟
void TIM_TIxExternalclockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIXExternalciksource,uint16_t TIM_ICPolarity,uint16_t ICFilter);
// 选择TIX捕获通道的时钟
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
// 选择ETR通过外部时钟模式1输入的时钟
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
// 选择ETR通过外部时钟模式2输入的时钟
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolar, uint16_t ExtTRGFilter);
// 配置ETR引脚的预分频器、极性、滤波器等参数
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
// 单独写入预分频值
void TIM_CounterModeConfig(TIM_TypeDef* TIMx,uint16_t TIM_CounterMode);
// 单独改变计数器的计数模式
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
// 计数器预装功能使能/失能
xvoid TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState);
xvoid TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState);
xvoid TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
xvoid TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
xvoid TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
xvoid TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource);
xvoid TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState);
xvoid TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode);
xvoid TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
// 给计数器写入一个值
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
// 给自动重装器写入一个值
xvoid TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD);
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
// 获取当前计数器的值
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);
// 获取当前预分频器的值
// 以下四个函数为获取/清除标志位函数,各外设的库函数形式一致,可参考EXTI模块
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
'1. 开启RCC时钟'
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2的时钟(位于APB1总线上)
'2. 选择时基单元的时钟源'
TIM_InternalClockConfig(TIM2); // 选择内部时钟作为时钟源(内部时钟是定时器初始化后的默认时钟源,所以可以不写)
'3. 配置时基单元'
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstruct; // 结构体初始化,然后填入结构体
TIM_TimeBaseInitstruct.TIM_ClockDivision = TIM_DIV1; // 选择滤波器频率分频值
TIM_TimeBaseInitstruct.TIM_CounterMode = TIM_CounterMode_Up; // 选择计数器模式
TIM_TimeBaseInitstruct.TIM_Period =10000 - 1; // 选择ARR自动重装器的值(0-65535)
TIM_TimeBaseInitstruct.TIM_Prescaler = 7200 - 1; // 选择PSC预分频器的值(0-65535)
TIM_TimeBaseInitstruct.TIM_RepetitionCounter = 0; // 选择重复计数器的值(高级定时器才有,配置通用定时器时写0即可)
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitstruct);
'4. 配置输出比较单元'
TIM_OCInitTypeDef TIM_OCInitStructure; // 定义结构体变量,然后填入结构体
TIM_OCStructInit(TIM_OCInitStructure); // 结构体初始化,防止一些参数没赋值导致问题
TIM_OCInitStructure.OCMode = TIM_OCMode_PWM1; // 设置输出模式
TIM_OCInitStructure.OCPolarity = TIM_OCPolarity_High; //设置输出比较极性
TIM_OCInitStructure.OutputState = ENABLE; // 设置使能
TIM_OCInitStructure.Pulse = ; // 设置CCR寄存器的值(0-0xffff)
TIM_OC1Init(TIM2, &TIM_OCInitStructure)
'5. 开启GPIO时钟以及配置GPIO'
// 见GPIO // 需要选用复用推挽输出模式
'6. 运行控制'
TIM_Cmd(TIM2, ENABLE);
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitstruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitstruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitstruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitstruct);
// 四个输出比较通道的输出比较单元初始化函数
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitstruct);
// 结构体初始化函数
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
// 四个通道配置强制输出模式
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
// 四个通道配置CCR寄存器的预装功能(影子寄存器)
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
// 四个通道配置快速使能
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
// 四个通道清除REF信号
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
// 四个通道修改输出极性,(第四个通道没有互补通道)
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
// 修改输出使能参数
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
// 修改输出比较模式
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
// 四个通道修改CCR寄存器的值(用来改变PWM的占空比)
'1. 开启RCC时钟'
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2的时钟(位于APB1总线上)
'2. 选择时基单元的时钟源'
TIM_InternalClockConfig(TIM2); // 选择内部时钟作为时钟源(内部时钟是定时器初始化后的默认时钟源,所以可以不写)
'3. 配置时基单元'
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstruct; // 结构体初始化,然后填入结构体
TIM_TimeBaseInitstruct.TIM_ClockDivision = TIM_DIV1; // 选择滤波器频率分频值
TIM_TimeBaseInitstruct.TIM_CounterMode = TIM_CounterMode_Up; // 选择计数器模式
TIM_TimeBaseInitstruct.TIM_Period =10000 - 1; // 选择ARR自动重装器的值(0-65535)
TIM_TimeBaseInitstruct.TIM_Prescaler = 7200 - 1; // 选择PSC预分频器的值(0-65535)
TIM_TimeBaseInitstruct.TIM_RepetitionCounter = 0; // 选择重复计数器的值(高级定时器才有,配置通用定时器时写0即可)
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitstruct);
'4. 配置输入捕获单元'
TIM_ICInitTypeDef TIM_ICInitStructure; // 结构体初始化,然后填入结构体
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; // 选择输入捕获电路的通道(1~4)
TIM_ICInitStructure.TIM_ICFilter = 0xf; // 配置输入捕获滤波器(0x0~0xf)
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 配置极性选择(边沿检测),上升沿触发
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPrescaler_DIV1; // 配置分频器
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // 配置数据选择器(直连通道or交叉通道)
TIM_ICInit(TIM2, &TIM_ICInitStructure)
'5. 选择从模式触发源、选择从模式的操作模式'
TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
'6. 开启GPIO时钟以及配置GPIO'
// 见GPIO // 需要选用上拉输入模式
'7. 运行控制'
TIM_Cmd(TIM2, ENABLE);
'8. 用库函数获取CCR寄存器的值进行运算,就能得到信号频率了'
'9. 如果使用PWMI模式'
'将4中的TIM_ICInit改为TIM_PWMIConfig即可'
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure)
// 该函数会自动将结构体变量中没选择的另一个通道设置为交叉通道反向触发
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitstruct);
// 输入捕获功能初始化函数
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitstruct);
// 输入捕获功能初始化函数(配置为PWMI模式)
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitstruct);
// 初始化结构体
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
// 选择从模式输入的触发源
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
// 选择主模式输出的触发源
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
// 从模式选择
void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
// 四个通道配置分频器
uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);
// 四个通道读取CCR寄存器的值
'1. 开启RCC时钟'
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2的时钟(位于APB1总线上)
'2. 配置时基单元(一般PSC选择不分频,ARR选择最大值)'
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstruct; // 结构体初始化,然后填入结构体
TIM_TimeBaseStructInit(&TIM_TimeBaseInitstruct); // 初始化结构体,防止有参数未赋值
TIM_TimeBaseInitstruct.TIM_ClockDivision = TIM_DIV1; // 选择滤波器频率分频值
// 参数TIM_CounterMode // 选择计数器模式,此处不需要配置,因为计数器被编码器接口控制
TIM_TimeBaseInitstruct.TIM_Period =65536 - 1; // 选择ARR自动重装器的值,编码器接口功能一般选择最大值65535
TIM_TimeBaseInitstruct.TIM_Prescaler = 1 - 1; // 选择PSC预分频器的值,编码器接口功能一般选择不分频0
TIM_TimeBaseInitstruct.TIM_RepetitionCounter = 0; // 选择重复计数器的值(高级定时器才有,配置通用定时器时写0即可)
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitstruct);
'3. 配置输入捕获单元(滤波器、极性选择)'
TIM_ICInitTypeDef TIM_ICInitStructure; // 结构体初始化,然后填入结构体
TIM_ICStructInit(&TIM_ICInitStructure); // 初始化结构体,防止有参数未赋值
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; // 选择输入捕获电路的通道(1~4)
TIM_ICInitStructure.TIM_ICFilter = 0xf; // 配置输入捕获滤波器(0x0~0xf)
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 配置极性选择(边沿检测),此处上升沿代表高低电平极性不反转,若为下降沿则代表极性反转
// 参数TIM_ICPrescaler // 配置分频器,此处不需要配置,没有使用到
// 参数TIM_ICSelection // 配置数据选择器,此处不需要配置,没有使用到
TIM_ICInit(TIM2, &TIM_ICInitStructure); // 配置通道1完成
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; // 选择输入捕获电路的通道(1~4)
TIM_ICInitStructure.TIM_ICFilter = 0xf; // 配置输入捕获滤波器(0x0~0xf)
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 配置极性选择,此处上升沿代表高低电平极性不反转,若为下降沿则代表极性反转
TIM_ICInit(TIM2, &TIM_ICInitStructure) // 改变结构体的通道号,配置通道2完成
'4. 配置编码器接口模式'
TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
// 配置编码器接口;工作模式选择TI1、2都计数;IC12极性选择
'5. 配置GPIO'
// 略,需要配置为输入模式,上拉/下拉需要跟外部电路保持一致
'6. 配置运行控制'
TIM_Cmd(TIM2, ENABLE);
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
// 编码器接口配置函数
// 参数:选择定时器;选择编码器接口工作模式;选择IC1的极性;选择IC2的极性
TIM_ClearFlag(TIM2, TIM_FLAG_Upadate);
Reference
STM32入门教程-2023版(江科大)