[ACM32G103RCT6 development board review] tobudOS implements a multi-task encoder
[Copy link]
[Purpose] Use the timer compiler interface to drive the rotary encoder
【experiment equipment】
1. ACM32G103RCT6 development board
2. Rotary encoder
【develop software】
1. MDK5.37
2. TobudOs multi-tasking real-time operating system
【Implementation steps】
1. Copy a tobudos project template.
2. Turn on the TIM switch:
Add timer.c and hal_timer_ex.c back to the project group
Add the initial code of TIM15 back to APP.C, initialize it to channels 1 and 2, and configure it to encoder mode
/************************************************************************
* 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);
}
Finally, add the function to read the encoded value:
int16_t Read_Encoder(void)
{
int16_t Encoder_TIM;
Encoder_TIM = (int16_t) TIM15->CNT-65536;
TIM15->CNT = 65536;
return Encoder_TIM;
}
Add a task cycle to read the compilation status:
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);
}
Experimental results:
|