【实验目的】使用定时器的编译器接口驱动旋转编码器
【实验器材】
1、ACM32G103RCT6开发板
2、旋转编码器
【开发软件】
1、MDK5.37
2、TobudOs多任务实时操作系统
【实现步骤】
1、复制一份tobudos工程模版。
2、打开TIM的开关:
添回timer.c、hal_timer_ex.c到工程分组中
在APP.C中添回TIM15的初始代码,初始化为通道1、2,并配置为编码器模式
/************************************************************************
* function : TIM6_IRQHandler
* Description: TIM6 Interrupt Handler
************************************************************************/
void TIM15_IRQHandler(void)
{
if (TIM15->SR & TIMER_SR_UIF)
{
Timer_Update_Flag = 1;
}
TIM15->SR = 0; //write 0 to clear hardware flag
}
void TIM15_MSP_Pre_Init(TIM_HandleTypeDef * htim)
{
HAL_TIMER_MSP_Init(&TIM15_Handler);
}
void TIM15_MSP_Post_Init(void)
{
GPIO_InitTypeDef gpio_init;
__HAL_RCC_GPIOC_CLK_ENABLE();
gpio_init.Pin = GPIO_PIN_1 | GPIO_PIN_2; //TIM15_CH1 and TIM15_CH2
gpio_init.Mode = GPIO_MODE_AF_PP;
gpio_init.Pull = GPIO_PULLUP;
gpio_init.Alternate = GPIO_FUNCTION_1;
gpio_init.Drive = GPIO_DRIVE_LEVEL3;
HAL_GPIO_Init(GPIOC, &gpio_init);
}
void TIM15_Init(void)
{
uint32_t timer_clock;
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
timer_clock = HAL_RCC_GetPCLK2Freq();
if (HAL_RCC_GetHCLKFreq() != timer_clock ) // if hclk/pclk != 1, then timer clk = pclk * 2
{
timer_clock = timer_clock << 1;
}
TIM15_Handler.Instance = TIM15;
TIM15_Handler.Init.ARRPreLoadEn = TIM_ARR_PRELOAD_ENABLE;
TIM15_Handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
TIM15_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;
TIM15_Handler.Init.RepetitionCounter = 0;
TIM15_Handler.Init.Prescaler = 0;
TIM15_Handler.Init.Period = 0xFFFF;
TIM15_MSP_Pre_Init(&TIM15_Handler);
HAL_TIMER_Base_Init(&TIM15_Handler);
HAL_TIM_ENABLE_IT(&TIM15_Handler, TIMER_INT_EN_UPD);
TIM15_MSP_Post_Init();
sSlaveConfig.SlaveMode = TIM_SLAVE_MODE_ENC1;
sSlaveConfig.InputTrigger = TIM_TRIGGER_SOURCE_TI1FP1;
sSlaveConfig.TriggerPolarity = TIM_SLAVE_CAPTURE_ACTIVE_RISING;
sSlaveConfig.TriggerFilter = TIM_TI1_FILTER_LVL(0); // no filter
HAL_TIMER_Slave_Mode_Config(&TIM15_Handler, &sSlaveConfig);
}
最后添加读取编码值函数:
int16_t Read_Encoder(void)
{
int16_t Encoder_TIM;
Encoder_TIM = (int16_t) TIM15->CNT-65536;
TIM15->CNT = 65536;
return Encoder_TIM;
}
添加任务周期读取编译状态:
int16_t encoder;
Timer_Update_Flag = 0;
TIM15_Init();
printfS("Timer_Update_Test\r\n");
HAL_TIMER_Base_Start(TIM15_Handler.Instance);
while(1)
{
encoder = Read_Encoder();
if(encoder > 0)
{
printfS("编码器正转:%d \r\n", encoder);
}
else if(encoder < 0)
{
printfS("编码器反转:%d \r\n", encoder);
}
HAL_DelayMs(10);
}
实验效果: