Генерация квадратурного сигнала с битовой манипуляцией

Я пытаюсь генерировать квадратурный сигнал, но с минимально возможной операцией. Для отправки сигнала я использую контакты B8 и B9 STM32 и GPIO. пара выводов 8 и 9 имеет четыре возможных варианта по часовой стрелке: 0/0 1/0 1/1 и 0/1 и против часовой стрелки 0/0 0/1 1/1 1/0 Я не могу найти с помощью побитового, чтобы иметь возможность быстро установить или сбросить бит для выбранного контакта. Более того, я должен быть в состоянии идти по часовой стрелке или против часовой стрелки и менять смысл всякий раз, когда захочу, если это был роторный или линейный энкодер.

Спасибо за помощь

1 ответ

Решение

Бит-Стук

Побитовое мышление, B9 получает предыдущее значение B8, а B8 получает обратное значение B9 или наоборот при обратном отсчете. Вы меняете два бита, и эксклюзив или 0x100 или же 0x200 в зависимости от направления.

inline void incB89(int down) {
    uint32_t temp;

    /* read the current output state */
    temp = GPIOB->ODR;

    /* modifying the significant bit-pair
       don't care about overflow */
    temp = (((temp & 0x100) << 1) | ((temp & 0x200) >> 1)) ^ (0x100 << down);

    /* Setting the reset bits BR8 and BR9. This has the effect that
       bits 8 and 9 will be copied into the ODR, and the rest will
       be left alone */
    temp |= ((1 << 24) | (1 << 25));

    GPIOB->BSRR = temp;
}

Используя таймер (или два)

На большинстве контроллеров серии STM32, TIM4 выходы каналов 3 и 4 могут быть сопоставлены с PB8 и PB9. Если у вас есть один из них, этот таймер может управлять выходами автономно, независимо от кода, памяти или задержки прерывания.

  • Установите режим GPIO и регистры альтернативных функций в соответствии со справочным руководством вашего контроллера.
  • Настройте оба канала 3 и 4 на режим переключения, установите OC1M а также OC2M биты в TIM4->CCMR1 в 0b011,
  • Установить входные часы, прескалер PSC и перезагрузите ARR чтобы достичь двойной желаемой частоты, потому что каждый выход будет переключаться один раз в каждом цикле таймера.
  • Задавать TIM4->CCR3=0 а также TIM4->CCR4=(TIM4->ARR+1)/2 для подсчета в одном направлении. Поменяйте их местами (пока счетчик остановлен) в обратном направлении.
  • Включить выходы в TIM4->CCER,
  • Вы можете начать и остановить подсчет, установив или сбросив CEN немного TIM4->CR1,
  • Для подсчета циклов вы можете настроить прерывание для переключения или обновления событий в TIM4->DIERили используйте другой таймер в качестве раба для TIM4.

Использовать например TIM3 считать:

  • Установить MMS биты в TIM4->CR2 в 0b010 вывести триггерный импульс при каждом переполнении.
  • конфигурировать TIM3->SMCR в Режим внешних часов 1 и выберите внутренний триггер TIM4.
  • Задавать TIM3->ARR до необходимого количества полупериодов - 1.
  • Настройте прерывание при обновлении.
  • Запустите счетчик.

С таймерами возможны и другие приемы, например, использование пакетов DMA, запускаемых ведомым, для обновления ARR а также CCR регистры главного таймера из таблицы значений "wawelength".

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