定时器输出比较理论
- OC(Output Compare)输出比较
- 输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形
- 每个高级定时器和通用定时器都拥有4个输出比较通道
- 高级定时器的前3个通道额外拥有死区生成和互补输出的功能
输出比较功能非常重要,主要用来输出PWM波形, PWM波形是驱动电机的必要条件,可以用来做智能车,机器人等项目
定时器配置
引脚配置,步进电机的驱动、方向、脉冲
/**
* @brief 配置TIM复用输出PWM时用到的I/O
* @param 无
* @retval 无
*/
static void Stepper_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*开启Motor相关的GPIO外设时钟*/
MOTOR_DIR_GPIO_CLK_ENABLE();
MOTOR_PUL_GPIO_CLK_ENABLE();
MOTOR_EN_GPIO_CLK_ENABLE();
/*选择要控制的GPIO引脚*/
GPIO_InitStruct.Pin = MOTOR_DIR_PIN;
/*设置引脚的输出类型为推挽输出*/
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull =GPIO_PULLUP;
/*设置引脚速率为高速 */
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
/*Motor 方向引脚 初始化*/
HAL_GPIO_Init(MOTOR_DIR_GPIO_PORT, &GPIO_InitStruct);
/*Motor 使能引脚 初始化*/
GPIO_InitStruct.Pin = MOTOR_EN_PIN;
HAL_GPIO_Init(MOTOR_EN_GPIO_PORT, &GPIO_InitStruct);
/* 定时器通道1功能引脚IO初始化 */
/*设置输出类型*/
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
/*设置引脚速率 */
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
/*设置复用*/
GPIO_InitStruct.Pull =GPIO_PULLUP;
/*选择要控制的GPIO引脚*/
GPIO_InitStruct.Pin = MOTOR_PUL_PIN;
/*Motor 脉冲引脚 初始化*/
HAL_GPIO_Init(MOTOR_PUL_PORT, &GPIO_InitStruct);
}
定时器初始化和输出比较模式(翻转模式)配置
初始化
void TIM_PWMOUTPUT_Config(void)
{
TIM_OC_InitTypeDef TIM_OCInitStructure;
/*使能定时器*/
MOTOR_PUL_CLK_ENABLE();
TIM_StepperHandle.Instance = MOTOR_PUL_TIM;
/* 累计 TIM_Period个后产生一个更新或者中断*/
///当定时器从0计数到TIM_PERIOD-1,即为TIM_PERIOD次,为一个定时周期
TIM_StepperHandle.Init.Period = TIM_PERIOD-1;
//定时器时钟源TIMxCLK = 2 * PCLK1
// PCLK1 = HCLK / 2
// => TIMxCLK=HCLK/2=SystemCoreClock/2*2=72MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
TIM_StepperHandle.Init.Prescaler = TIM_PRESCALER-1;
/*计数方式*/
TIM_StepperHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
/*采样时钟分频*/
TIM_StepperHandle.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
TIM_StepperHandle.Init.RepetitionCounter = 0 ;
/*初始化定时器*/
HAL_TIM_OC_Init(&TIM_StepperHandle);
/*PWM模式配置--这里配置为输出比较模式*/
TIM_OCInitStructure.OCMode = TIM_OCMODE_TOGGLE;
/*比较输出的计数值*/
TIM_OCInitStructure.Pulse = OC_Pulse_num;
/*当定时器计数值小于CCR1_Val时为高电平*/
TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;
/*设置互补通道输出的极性*/
TIM_OCInitStructure.OCNPolarity = TIM_OCNPOLARITY_LOW;
/*快速模式设置*/
TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;
/*空闲电平*/
TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_RESET;
/*互补通道设置*/
TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;
HAL_TIM_OC_ConfigChannel(&TIM_StepperHandle, &TIM_OCInitStructure, MOTOR_PUL_CHANNEL_x);
/* 确定定时器 */
HAL_TIM_Base_Start(&TIM_StepperHandle);
/* 启动比较输出并使能中断 */
HAL_TIM_OC_Start_IT(&TIM_StepperHandle,MOTOR_PUL_CHANNEL_x);
/*使能比较通道*/
TIM_CCxChannelCmd(MOTOR_PUL_TIM,MOTOR_PUL_CHANNEL_x,TIM_CCx_ENABLE);
}
定时器_回调函数_全部如下
/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions
* @brief TIM Callbacks functions
* @{
*/
/* Callback in non blocking modes (Interrupt and DMA) *************************/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim);
void HA