这里写目录标题
-
- 0. 声明
- 1.定时器时钟树
- 2.定时器中结构体分析
-
- 2.1TIM时基初始化结构定义
- 2.2TIM输出比较初始化结构定义
- 2.3TIM输入捕获初始化结构定义
- 2.4BDTR结构定义
- 3.定时器溢出中断
- 4.定时器PWM输出分析
- 5.定时器比较输出分析
0. 声明
需要先学习的基础内容:
1.请在时钟树的基础上进行定时器的学习,不然会知其然不知其所以然。
2.GPIO配置基础
3.NVIC中断优先级配置基础
4.串口通信基础(可有可无,主要用于查看调试信息)
5.可以先进行基本定时器和通用定时器的学习
1.定时器时钟树
2.定时器中结构体分析
2.1TIM时基初始化结构定义
/**
* @brief TIM Time Base Init structure definition
* @note This structure is used with all TIMx except for TIM6 and TIM7.
*/
typedef struct
{
uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock.
This parameter can be a number between 0x0000 and 0xFFFF */
uint16_t TIM_CounterMode; /*!< Specifies the counter mode.
This parameter can be a value of @ref TIM_Counter_Mode */
uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active
Auto-Reload Register at the next update event.
This parameter must be a number between 0x0000 and 0xFFFF. */
uint16_t TIM_ClockDivision; /*!< Specifies the clock division.
This parameter can be a value of @ref TIM_Clock_Division_CKD */
uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter
reaches zero, an update event is generated and counting restarts
from the RCR value (N).
This means in PWM mode that (N+1) corresponds to:
- the number of PWM periods in edge-aligned mode
- the number of half PWM period in center-aligned mode
This parameter must be a number between 0x00 and 0xFF.
@note This parameter is valid only for TIM1 and TIM8. */
} TIM_TimeBaseInitTypeDef;
2.2TIM输出比较初始化结构定义
/**
* @brief TIM Output Compare Init structure definition
*/
typedef struct
{
uint16_t TIM_OCMode; /*!< Specifies the TIM mode.
This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */
uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state.
This parameter can be a value of @ref TIM_Output_Compare_State */
uint16_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state.
This parameter can be a value of @ref TIM_Output_Compare_N_State
@note This parameter is valid only for TIM1 and TIM8. */
uint32_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
This parameter can be a number between 0x0000 and 0xFFFF */
uint16_t TIM_OCPolarity; /*!< Specifies the output polarity.
This parameter can be a value of @ref TIM_Output_Compare_Polarity */
uint16_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity.
This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
@note This parameter is valid only for TIM1 and TIM8. */
uint16_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
This parameter can be a value of @ref TIM_Output_Compare_Idle_State
@note This parameter is valid only for TIM1 and TIM8. */
uint16_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
@note This parameter is valid only for TIM1 and TIM8. */
} TIM_OCInitTypeDef;
2.3TIM输入捕获初始化结构定义
/**
* @brief TIM Input Capture Init structure definition
*/
typedef struct
{
uint16_t TIM_Channel; /*!< Specifies the TIM channel.
This parameter can be a value of @ref TIM_Channel */
uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal.
This parameter can be a value of @ref TIM_Input_Capture_Polarity */
uint16_t TIM_ICSelection; /*!< Specifies the input.
This parameter can be a value of @ref TIM_Input_Capture_Selection */
uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler.
This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
uint16_t TIM_ICFilter; /*!< Specifies the input capture filter.
This parameter can be a number between 0x0 and 0xF */
} TIM_ICInitTypeDef;
2.4BDTR结构定义
(此结构仅与TIM1和TIM8一起使用。)
/**
* @brief BDTR structure definition
* @note This structure is used only with TIM1 and TIM8.
*/
typedef struct
{
uint16_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode.
This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */
uint16_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state.
This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */
uint16_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters.
This parameter can be a value of @ref TIM_Lock_level */
uint16_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and the
switching-on of the outputs.
This parameter can be a number between 0x00 and 0xFF */
uint16_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not.
This parameter can be a value of @ref TIM_Break_Input_enable_disable */
uint16_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity.
This parameter can be a value of @ref TIM_Break_Polarity */
uint16_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not.
This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */
} TIM_BDTRInitTypeDef;
3.定时器溢出中断
/*函数名:void Timer1_Init(u16 arr,u16 psc)
函数功能: TIM1定时器溢出中断初始化
传入参数:
arr:计数值
psc:预分频数值
*/
void Timer1_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrecture; //定时器时基初始化结构体
NVIC_InitTypeDef NVIC_InitStructure; //中断优先级配置结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); /*使能定时器1的时钟*/
TIM_TimeBaseInitStrecture.TIM_Period = arr; /*重装载寄存器数值*/
TIM_TimeBaseInitStrecture.TIM_Prescaler = psc-1; /*预分配数值*/
TIM_TimeBaseInitStrecture.TIM_ClockDivision = TIM_CKD_DIV1; /*时钟分频*/
TIM_TimeBaseInitStrecture.TIM_CounterMode = TIM_CounterMode_Up; /*向上计数*/
TIM_TimeBaseInitStrecture.TIM_RepetitionCounter = 0; /*重复计数寄存器*/
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStrecture); /*初始化*/
TIM_ClearFlag(TIM1,TIM_FLAG_Update); /*清更新标志位*/
TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE); /*使能中断*/
TIM_Cmd(TIM1,ENABLE); /*使能计数*/
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;/*定时器1的中断通道使能*/
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;/*定时器1的中断通道使能*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;/*抢占优先级*/
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;/*响应优先级*/
NVIC_Init(&NVIC_InitStructure);/*配置中断分组,并使能中断*/
}
//函数名: void TIM1_UP_TIM10_IRQHandler(void)
//函数功能: TIM1定时器溢出中断,中断服务函数。
void TIM1_UP_TIM10_IRQHandler(void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)//检查指定的TIM中断发生与否:TIM 中断源
{
LED1=~LED1;
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清除TIMx的中断待处理位:TIM 中断源
}
}
4.定时器PWM输出分析
5.定时器比较输出分析
目前遇到一个小的BUG ,就是在自动重装载值,比较小的时候,反转输出会出现各种问题哟!!!
目前先理解到这里,先不向后面继续理解了!!!
// 第一步: 进行引脚的配置--> 把TIM1高级定时器的通道1, 复用到GPIOE_9上面。
void STEPMOTOR_TIM1_Init_GPIO()
{
GPIO_InitTypeDef GPIO_InitStructure; //基本定时器结构体
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE); //引脚时钟结构体初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //引脚 PE9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用到TIM1 通道1上面。
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //翻转速度100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化GPIO
GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_TIM1); //复用配置
}
//第二步 :进行定时器的基本时基部分的配置 比较输出使能的配置 还有关于中断的优先级配置
void STEPMOTOR_TIM1_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定时器基本结构体
TIM_OCInitTypeDef TIM_OCInitStructure; //定时器比较输出结构体
NVIC_InitTypeDef NVIC_InitStructure; //中断配置结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //开定时器时钟(高速时钟)
STEPMOTOR_TIM1_Init_GPIO(); //调用引脚函数。
TIM_TimeBaseStructure.TIM_Period = 0XFFFF; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =168-1; //设置用来作为TIMx时钟频率除数的预分频值 不分频 168M
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; // 比较输出模式:反转输出
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OutputNState=TIM_OutputNState_Disable; //互补比较使能
TIM_OCInitStructure.TIM_Pulse=1000; //指定要加载到捕获/比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; //输出极性为高
TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Set; //指定空闲状态下的TIM输出比较pin状态
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC1FastConfig(TIM1,TIM_OCFast_Enable);
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Disable); //禁止TIM1在CCR上的预装载寄存器,这里很重要不要使能啊
TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Enable);
TIM_ITConfig(TIM1, TIM_IT_CC1,ENABLE); //中断使能
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ClearFlag(TIM1, TIM_FLAG_CC1);
TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);
TIM_CtrlPWMOutputs(TIM1,ENABLE);
TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
int tim_count = 0;
void TIM1_CC_IRQHandler(void)
{
if( TIM_GetITStatus( TIM1 , TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);
LED1=~LED1;
tim_count=TIM_GetCapture1(TIM1); //得到通道1的计数数值。
TIM_SetCompare1(TIM1,tim_count+1000); //设置新的CCR 值,新的比较数值。
}
}