Квадратурный энкодер STM32 HAL Nucleo F446RE

У меня проблема с режимом квадратурного энкодера на tim3.

1) tim3 рассчитывает на каждый передний фронт первого сигнала. регистр CNT считает, и я читаю значение с 1 Гц, а затем я устанавливаю регистр в 0.

Все выглядит хорошо, но...

Когда я смотрю на осциллограф, частота вдвое меньше значения на выходе регистра CNT (1 Гц).

Зачем?

2) Tim3 рассчитывает по обоим краям на первый сигнал. выход регистра CNT (1 Гц) полностью неверен

мой конфиг:

GPIO_InitTypeDef sInitEncoderPin1;
sInitEncoderPin1.Pin                    = pin1Encoder.pin;  // A GPIO_PIN_6
sInitEncoderPin1.Mode                   = GPIO_MODE_AF_PP;
sInitEncoderPin1.Pull                   = GPIO_PULLUP;
sInitEncoderPin1.Speed                  = GPIO_SPEED_HIGH;
sInitEncoderPin1.Alternate              = altFunctionEncoder; // GPIO_AF2_TIM3

GPIO_InitTypeDef sInitEncoderPin2;
sInitEncoderPin2.Pin                    = pin2Encoder.pin; // A GPIO_PIN_7
sInitEncoderPin2.Mode                   = GPIO_MODE_AF_PP;
sInitEncoderPin2.Pull                   = GPIO_PULLUP;
sInitEncoderPin2.Speed                  = GPIO_SPEED_HIGH;
sInitEncoderPin2.Alternate              = altFunctionEncoder; // GPIO_AF2_TIM3


HAL_GPIO_Init(GPIOA, &sInitEncoderPin1);
HAL_GPIO_Init(GPIOA, &sInitEncoderPin2);

encoderTimer.Init.Period                        = 0xffff;
encoderTimer.Init.Prescaler                     = 0;
encoderTimer.Init.CounterMode                   = TIM_COUNTERMODE_UP;
encoderTimer.Init.ClockDivision                 = TIM_CLOCKDIVISION_DIV1;
encoderTimer.Init.RepetitionCounter             = 0;

HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 1);

encoder.EncoderMode                             = TIM_ENCODERMODE_TI1;
encoder.IC1Filter                               = 0x0f;
encoder.IC1Polarity                             = TIM_INPUTCHANNELPOLARITY_RISING; // TIM_INPUTCHANNELPOLARITY_BOTHEDGE
encoder.IC1Prescaler                            = TIM_ICPSC_DIV1;
encoder.IC1Selection                            = TIM_ICSELECTION_DIRECTTI;

encoder.IC2Filter                               = 0x0f;
encoder.IC2Polarity                             = TIM_INPUTCHANNELPOLARITY_RISING;
encoder.IC2Prescaler                            = TIM_ICPSC_DIV1;
encoder.IC2Selection                            = TIM_ICSELECTION_DIRECTTI;

HAL_TIM_Encoder_Init(&encoderTimer, &encoder);

HAL_TIM_Encoder_Start_IT(&encoderTimer, TIM_CHANNEL_ALL);

0 ответов

На скриншоте осциллографа показана частота около 416 Гц.

  1. Значения, показанные в первом выводе оболочки(очень грубо!), Вдвое выше (как уже указывает вопрос). Мне это кажется (почти...) правильным, поскольку показанная конфигурация

    encoder.EncoderMode = TIM_ENCODERMODE_TI1;
    

    выбирает " режим датчикаразрешения X2 ", который считает 2CNTприращения за период сигнала. В примечании к применению, посвященном обзору таймера(разд. 4.3.4 / рис. 7), есть иллюстративная диаграмма, как работает режим кодировщика в деталях.

  2. На втором скриншоте результатов от неправильной конфигурации TIM3: Режим датчика (TIM_ENCODERMODE_TI1) предполагает, что оба канала поочередно запускаются только по направленным флангам (см. ссылку AN выше).

    Если один из двух каналов вызывает в два раза больше событий из-за конфигурации

    encoder.IC1Polarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE,
    

    счетчик отсчитывает только одну позицию и затем "распознает" событие "разворота" (= изменение направления). Имея в виду, что

    65535u = 0xFFFF = -1
    

    второй снимок экрана показывает только значения -1, 0, +1, что идеально соответствует этому объяснению.


Остается вопрос, почему на первом снимке экрана показаны (воспроизводимые) измерения между 800 а также 822. Я предполагаю что

  • физический источник сигнала энкодера работает с постоянной скоростью
  • таймер 1 Гц, запускающий вывод оболочки, не зависит от TIM3, и
  • он был запущен до таймера кодировщика (т. е. над показанным образцом кода).

Это может объяснить, почему первые два значения выглядят бессмысленно (0: TIM3 еще не запускался. 545: TIM3 был запущен во время периода таймера вывода оболочки). Если отбросить первые две выборки измерения, среднее и стандартное отклонение, соответственно, частоты измеренного сигнала равны

808,9091 +/- 0,5950 [X2 шага в секунду]

404,4545 +/- 0,2975 [Гц]

что соответствует периоду

2,4331 +/- 0,003 [мс].

Следовательно, измеренная частота слишком низкая примерно на 11 Гц, т. Е. Измеренный период слишком высок примерно на 30 мкс, и эта ошибка явно выходит за рамки статистического шума.

Вопрос дает подсказку, откуда могла взяться эта ошибка:

Регистр CNT считает, и я считываю значение с частотой 1 Гц, а затем устанавливаю регистр на 0.

  1. Каждый раз, когда истекает "таймер опроса" с частотой 1 Гц, он запускает прерывание (или логическое событие в программном обеспечении опроса).
  2. Обработка этого прерывания / события может быть немного отложена в зависимости от другого программного обеспечения (IRQ: время деактивации в другом месте в программном обеспечении, опрос: продолжительность цикла до момента опроса события).
  3. Программное обеспечение читает CNT ценность.
  4. Программный сброс CNT значение до нуля, отбрасывая дальнейшие приращения, так как CNT значение было прочитано.
  5. TIM3 продолжает отсчет (с нуля).

Это намекает на то, что программному обеспечению требуется 30 мкс между (3.) и (4.), что было бы довольно много времени для STM32F4.

Изменить: я только что перепроверил снимок экрана осциллографа. Ошибка видна, но я считаю, что она меньше, чем я предполагал изначально (из подсчета флангов на картинке).

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