Проблемы с настройкой ШИМ STM32F030

Я пытаюсь заставить ШИМ работать на двух контактах моего STM32030R8T6, он находится на плате разработки Nucleo, и я использую Keil. Для обучения я в основном слежу за материалами на этом веб-сайте, но с такими адаптациями сайт использует другой MCU. На самом деле не так уж много настроек ШИМ, поэтому я не совсем уверен, что я сделал не так, я знаю, что таймер работает, потому что встроенный светодиод мигает 1,5 раза в секунду, но когда я контролирую Ch1 и Выводы Ch2 с моим прицелом я ничего не получаю. Я почти уверен, что контакты правильно установлены в альтернативной функции Push-Pull, потому что они установлены так же, как и контакт MCO, который работает и показывает 24 МГц (хотя у моего дешевого прицела есть некоторые проблемы с определением этого ...). Я приложил весь свой относящийся к делу и, возможно, даже отдаленно относящийся к делу код. И для вашего удобства:

Справочное руководство UM0360 (STM32F030 ...)

Я бы разместил ссылки на Руководство пользователя Nucleo и Техническое описание устройства, но я не могу разместить больше двух ссылок, так как это мой первый вопрос, а моя репутация меньше десяти.

Приветствуется любая помощь в том, что я делаю неправильно, я уверен, что это что-то глупое.

#include "stm32f0xx.h"

void Initializations(void);

int main(void)
{
    Initializations();

    while(1)
    {
        /*  Toggle onboard LED whenever timer overflows */
        if((TIM3->SR & TIM_SR_UIF))
        {
            TIM3->SR &= ~TIM_SR_UIF;
            GPIOA->ODR ^= GPIO_ODR_5;
        }           
    }
}

void Initializations(void)
{ 
    /*  CLK CONFIG  */
    RCC->CFGR |= RCC_CFGR_HPRE_DIV2  |
                 RCC_CFGR_PPRE_DIV16 |
                 RCC_CFGR_MCO_SYSCLK |
                 RCC_CFGR_PLLMUL6; 

    /*  Activate PLL, wait  */
    RCC->CR |= RCC_CR_PLLON;
    while(!(RCC->CR & RCC_CR_PLLRDY));
    RCC->CFGR |= RCC_CFGR_SW_PLL;

    /*  Enable IO CLKs  */
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
    RCC->AHBENR |= RCC_AHBENR_GPIOCEN;

    /*  Enable peripheral CLKs  */
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN;

    /*  PIN INITIALIZATIONS */
    GPIOA->MODER |= GPIO_MODER_MODER5_0 |       // Onboard LED (General output)
                    GPIO_MODER_MODER2_1 |       // USART2 TX (Alternate function)
                    GPIO_MODER_MODER3_1 |       // USART2 RX (Alternate function)
                    GPIO_MODER_MODER6_1 |       // TIM3 CH1 (Alternate function)
                    GPIO_MODER_MODER7_1 |       // TIM3 CH2 (Alternate function)
                    GPIO_MODER_MODER8_1 |       // MCO (Alternate function)
                    GPIO_MODER_MODER9_1 |       // USART1 TX (Alternate function)
                    GPIO_MODER_MODER10_1;       // USART1 RX (Alternate function)

    /*  TIMER INITS */
    TIM3->PSC = 7;
    TIM3->ARR = 59999;

    /*  CCM1    */
    TIM3->CCMR1 |= TIM_CCMR1_OC1M_0 | 
                   TIM_CCMR1_OC1M_1;

    TIM3->CCR1 |= 4499;
    TIM3->CCER |= TIM_CCER_CC1E;                // Enable Ch1

    /*  CCM2    */
    TIM3->CCMR1 |= TIM_CCMR1_OC2M_0 | 
                   TIM_CCMR1_OC2M_1;

    TIM3->CCR2 |= 29999;
    TIM3->CCER |= TIM_CCER_CC2E;                // Enable Ch2

    TIM3->CR1 |= TIM_CR1_CEN;                   // Enable TIM3

    /*  USART INITS */
    RCC->CFGR3 |= RCC_CFGR3_USART1SW_0;         // Clock USART1 from SYSCLK
}

person Unit_One    schedule 23.01.2015    source источник
comment
Вы пытаетесь избежать использования прерываний?   -  person bunkerdive    schedule 24.01.2015
comment
Кроме того, есть ли у вас эквивалент RCC->APB2ENR |= RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN; для включения соответствующего порта и альтернативного функционального блока?   -  person bunkerdive    schedule 24.01.2015
comment
Да, он находится в регистре AHBENR на этом MCU, и хотя бит все еще имеет значение IOPxEN, вместо этого компилятор принимает GPIOxEN. У них одно и то же число.   -  person Unit_One    schedule 26.01.2015


Ответы (1)


Помимо настройки вывода на использование альтернативной функции, вы также должны указать, какую альтернативную функцию использовать.

Это описано в разделе 8.3.2 (pdf стр. 128) связанного вами документа.

Это регистры AFRL (для контактов 0-7) и AFRH (для контактов 8-15) порта.

Например, на основе вашего кода, и если TIM3 использует альтернативную функцию 2 и находится на контактах 6 и 7 (и при условии, что альтернативный код в настоящее время равен 0), вы бы сделали

GPIOA->AFRL |= (2 << (6 * 4)) | (2 << (7 * 4));

Если это не 0 или вы хотите быть уверены, сначала замаскируйте биты (каждый вывод получает 4 бита).

(Обратите внимание, что ваш заголовок может называть регистры иначе, чем мой, и ваши альтернативные функции также могут отличаться; я обычно работаю с STM32F407 или STM32F334. Чтобы найти таблицу альтернативных функций, чтобы увидеть, какая из них вам нужна, вам нужно посмотреть, что вверху в таблице данных для конкретного чипа, который вы используете, в отличие от справочного руководства по семейству, которое вы связали выше)

Более общая форма

mode << (pin * 4)

для AFRL и

mode << ((pin - 8) * 4)

для AFRH.

person John O'M.    schedule 30.01.2015
comment
Не могу поверить, что пропустил этот регистр, большое спасибо и за идеальное время, я как раз собирался сдаться и использовать беспорядочную и неудобную схему прерывания. - person Unit_One; 31.01.2015