Генерация двух противоположных сигналов ШИМ с помощью таймеров и смены контактов GPIO / AF - PullRequest
2 голосов
/ 02 июля 2019

Мне нужно сгенерировать два противоположных сигнала ШИМ (когда один высокий, а другой низкий) с использованием таймеров в STM32. Я прочитал несколько примеров, и вот код, который я придумал:

void TM_PINS_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    /* Alternating functions for pins */
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);

    /* Set pins */
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOD, &GPIO_InitStruct);
}

void TM_TIMER_Init(void) {
    TIM_TimeBaseInitTypeDef TIM_BaseStruct;

    /* Enable clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    uint16_t Period;
    Period = 1000000 / 200000; // 200 KHz from 1MHz

    TIM_BaseStruct.TIM_Prescaler = (SystemCoreClock / 1000000) - 1; // 1MHz
    TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_BaseStruct.TIM_Period = Period - 1; 
    TIM_BaseStruct.TIM_ClockDivision = 0;
    TIM_BaseStruct.TIM_RepetitionCounter = 0;
    /* Initialize TIM4 */
    TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
    /* Start count on TIM4 */
    TIM_Cmd(TIM4, ENABLE);
}

void TM_PWM_Init(void) {
    TIM_OCInitTypeDef TIM_OCStruct;

    /* PWM mode 2 = Clear on compare match */
    /* PWM mode 1 = Set on compare match */
    TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OC1Init(TIM4, &TIM_OCStruct);
    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);

    TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OC2Init(TIM4, &TIM_OCStruct);
    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);

    TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
    TIM_OCStruct.TIM_Pulse = Period/2; /* 50% duty cycle */
}

У меня есть несколько вопросов:

  1. Поскольку мне нужны частоты в десятках кГц, нужно ли устанавливать частоту 100 МГц для скорости GPIO? Есть ли какая-нибудь выгода, чтобы сделать это медленнее?

  2. Будет ли моя функция ШИМ генерировать то, что мне нужно? Я думаю, что противоположные ШИМ-сигналы на самом деле достигаются с использованием режимов ШИМ 1 и 2, но я боюсь, что я что-то там упускаю.

  3. Я хочу иметь возможность останавливать таймеры и устанавливать состояние высокого / низкого уровня на те же контакты. Будет ли работать следующий код?

GPIOD-> MODER |= (5 << 24); //set pin 12 and 13 to GPIO, 5 gives us 101, shifted 23 bits so that '1's are in pos. 24 and 26

GPIOD->regs->BSRR = (3<<12); // 3 gives us 11 pattern, shifted 12 bits so that pins 12 and 13 are set to high

GPIOD-> MODER |= (5 << 24); //set pin 12 and 13 to AF, 5 gives us 101, shifted 24 bits so that '1's are in pos. 25 and 27
  1. Когда АФ восстанавливается, предыдущие настройки ШИМ восстановлены или должны быть установлены заново.

  2. Было бы лучше использовать MODER, как указано выше, чтобы изменить контакты на GPIO, а затем установить на высокий / низкий уровень, или я могу использовать 100% рабочий цикл для высокого и 0% рабочий цикл для низкого?

1 Ответ

2 голосов
/ 02 июля 2019

Q1: нет, вам не нужно. Более быстрые настройки означают больше энергии, потребляемой периферийными и более острыми краями генерируемого сигнала, что вызывает больше электромагнитных помех. Если вам плевать на то и другое - это неважно.

Q2: Вам нужно проверить это самостоятельно, если вы используете какие-то «магические» числа.

Q3: То же, что и выше. Почему бы вам не использовать понятные человеку определения CMSIS только «магические» функции. Если вы правильно установите значения регистра, он будет работать

Q4: Если вы остановили таймер, вам нужно запустить / настроить его снова. Если нет, это должно работать.

Q5: Неважно. Но таймер запуска будет генерировать шум и потреблять немного энергии.

...