2015-01-23 2 views
2

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

UM0360 Reference Manual (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 
} 
+0

Вы пытаетесь избежать использования прерываний? – bunkerdive

+0

Также у вас есть эквивалент 'RCC-> APB2ENR | = RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN; 'для включения вашего соответствующего порта и альтернативного функционального блока? – bunkerdive

+0

Да, это в регистре AHBENR на этом MCU, и хотя бит все еще IOPxEN, вместо этого компилятор принимает GPIOxEN. У них одинаковое число. –

ответ

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.

+0

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

Смежные вопросы