Конфигурация роторного энкодера STM32 на TIM4

Я пытаюсь использовать TIM4 для ввода квадратурного энкодера на моей плате STM32F4DISCOVERY. Вот мой код:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6| GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4);

/* Configure the timer */
TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

/* TIM4 counter enable */
TIM_Cmd(TIM4, ENABLE);

к сожалению, счетчик TIM4->CNT не будет двигаться, когда я поверну кодировщик. Я отлично работаю с TIM8. Вот полный код рабочего TIM8 и не рабочего TIM4: https://gist.github.com/nraynaud/5082298

Я проверяю, печатая rT2() в gdb после ручного перемещения кодера.

3 ответа

Я использовал STM32F407 для считывания количества кодировок с 3 оптических датчиков. Я использую ChibiOS RTOS, поэтому структура таймера немного отличается от структуры таймера периферийной библиотеки ST, но информация в основном та же. Вот как я настраиваю регистры фактических таймеров:

stm32_tim_t * encoderTimers[3] = {STM32_TIM8, STM32_TIM3, STM32_TIM4};
for (auto timer : encoderTimers) {
  timer->SMCR = 3;          // Encoder mode 3
  timer->CCER = 0;          // rising edge polarity
  timer->ARR = 0xFFFF;      // count from 0-ARR or ARR-0
  timer->CCMR1 = 0xC1C1;    // f_DTS/16, N=8, IC1->TI1, IC2->TI2
  timer->CNT = 0;           // Initialize counter
  timer->EGR = 1;           // Generate an update event
  timer->CR1 = 1;           // Enable the counter
}

Также убедитесь, что вы включили периферийные устройства таймера в регистрах APB1 или APB2 RCC. Что-то вроде:

RCC->APB1ENR |= ((1 <<  2)  // TIM4  --  Front wheel angle measurement
             |   (1 <<  1));// TIM3  --  Steer angle measurement

Наконец, вам необходимо убедиться, что вы правильно настроили параметры GPIO. Это означает настройку GPIO для альтернативной функции.

Возможно, вам придется использовать подтягивания для входа, если вы не используете внешние резисторы или питание энкодера. Я обычно подключаю энкодер к земле и использую внутренние подтягивания для установки состояния холостого хода.

Кодировщик со стандартным драйвером

#include "mbed.h"
#include "stm32f4xx.h"
#include "stm32f4xx_hal_tim_ex.h"

TIM_HandleTypeDef timer;
TIM_Encoder_InitTypeDef encoder;

//direction to PA_9 -- step pulse to PA_8

int main(){
     GPIO_InitTypeDef GPIO_InitStruct;
        __TIM1_CLK_ENABLE();
        __GPIOA_CLK_ENABLE();
        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    timer.Instance = TIM1;
    timer.Init.Period = 0xffff;
    timer.Init.Prescaler = 0;
    timer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    timer.Init.CounterMode = TIM_COUNTERMODE_UP;

    encoder.EncoderMode = TIM_ENCODERMODE_TI12; 
    encoder.IC1Filter = 0x0f;
    encoder.IC1Polarity = TIM_INPUTCHANNELPOLARITY_RISING; 
    encoder.IC1Prescaler = TIM_ICPSC_DIV4;
    encoder.IC1Selection = TIM_ICSELECTION_DIRECTTI;

    encoder.IC2Filter = 0x0f;
    encoder.IC2Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;    
    encoder.IC2Prescaler = TIM_ICPSC_DIV4;
    encoder.IC2Selection = TIM_ICSELECTION_DIRECTTI;

    HAL_TIM_Encoder_Init(&timer, &encoder);
    HAL_TIM_Encoder_Start(&timer,TIM_CHANNEL_1);   


    TIM1->EGR = 1;           // Generate an update event
    TIM1->CR1 = 1;           // Enable the counter


 while (1) {
        int16_t count1; 
        count1=TIM1->CNT; 

        printf("%d\r\n", count1);
        wait(1.0);

 };
}
Другие вопросы по тегам