2014-12-13 2 views
0

저는 stm32f407 발견 보드가 새로 추가되었으며 위상 변이 및 듀티 사이클을 제어 할 수있는 4 개의 신호를 만들려고합니다. 문제는 PWM 모드에서 타이머를 설정할 때 channel_1과 channel_2 사이의 위상 이동을 제어 할 수 없다는 것입니다. 나는 인터럽트를 사용해야한다는 것을 알고 있지만, 그 안에 코드가 무엇인지 알아 내지 못한다. 네가 나를 도울 수 있다면 정말 고마워.STM32F407 PWM 제어 위상 변이, 듀티 사이클

여기 내 코드입니다. 한 시간에 한 번씩 LED를 켜고 끄는 인터럽트를 사용합니다 (지연은 아직 잘 동기화되지 않았습니다).

/* Includes ------------------------------------------------------------------*/ 
#include "stm32f4xx.h" 
#include "stm32f4xx_gpio.h" 
#include "stm32f4xx_rcc.h" 
#include "misc.h" 
#include "stm32f4xx_tim.h" 
#include "stm32f4xx_usart.h" 
#include "delay.h" 

/* Private typedef -----------------------------------------------------------*/ 
GPIO_InitTypeDef GPIO_InitStructure; 
USART_InitTypeDef USART_InitStructure; 
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
TIM_OCInitTypeDef TIM_OCInitStructure; 

/* Private define ------------------------------------------------------------*/ 
#define frequency 42500 

/* Private macro -------------------------------------------------------------*/ 

/* Private variables ---------------------------------------------------------*/ 
int Prescaler = 0; 
int Period = 84000000/frequency; // ~42.5KHz 
int pulse_width; 

/* Private function prototypes -----------------------------------------------*/ 
void GPIO_Config(void); 
void PWM_Config(void); 
void PWM_SetDC(int channel,int dutycycle); 
void Delay(__IO int nCount); 
void LED_Config(void); 

/* Private functions ---------------------------------------------------------*/ 
void TIM2_IRQHandler(void) 
{ 
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) 
{ 

    Delay(10000000); 

    GPIO_ToggleBits(GPIOD, GPIO_Pin_15); 

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); 
} 
} 
/** 
    * Main program 
    */ 
int main(void) 
{ 


    /* GPIO Configuration */ 
    GPIO_Config(); 

    LED_Config(); 

    /* PWM Configuration */ 
    PWM_Config(); 

    PWM_SetDC(1,80); 
    PWM_SetDC(2,40); 
    PWM_SetDC(3,0); 
    PWM_SetDC(4,0); 

    while (1) 
    { 

    } 
} 

/** 
    * Configure the TIM2 Output Channels. 
    */ 
void GPIO_Config(void) 
{ 

    NVIC_InitTypeDef NVIC_InitStructure; 
    /* Enable the TIM2 global Interrupt */ 
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure); 

    /* TIM2 clock enable */ 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 

    /* GPIOA clock enable */ 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE); 

    GPIO_InitTypeDef GPIO_InitStructure; 
    /* GPIOC Configuration: TIM2 CH1 (PA0), TIM2 CH2 (PA1), TIM2 CH3 (PA2), TIM2 CH4 (PA3) */ 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; 
    GPIO_Init(GPIOA, &GPIO_InitStructure); 

    /* Connect TIM2 pins to AF2 */ 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2); 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2); 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2); 

} 

void PWM_Config(void) 
{ 

    /* Time base configuration */ 
    TIM_TimeBaseStructure.TIM_Period = Period - 1; 
    TIM_TimeBaseStructure.TIM_Prescaler = 0; 
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 

    TIM_ARRPreloadConfig(TIM2, ENABLE); 

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 

    /* PWM1 Mode configuration: Channel1 */ 
    TIM_OCInitStructure.TIM_Pulse = 0; 
    TIM_OC1Init(TIM2, &TIM_OCInitStructure); 
    TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); 

    ////////////////////////* TIM INTERRUPT enable *//////////////////////////// 
    TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE); 
    //////////////////////////////////////////////////////////////////////////// 

    /* PWM1 Mode configuration: Channel2 */ 
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
    TIM_OCInitStructure.TIM_Pulse = 0; 
    TIM_OC2Init(TIM2, &TIM_OCInitStructure); 
    TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); 

    /* PWM1 Mode configuration: Channel3 */ 
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
    TIM_OCInitStructure.TIM_Pulse = 0; 
    TIM_OC3Init(TIM2, &TIM_OCInitStructure); 
    TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); 

    /* PWM1 Mode configuration: Channel4 */ 
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
    TIM_OCInitStructure.TIM_Pulse = 0; 
    TIM_OC4Init(TIM2, &TIM_OCInitStructure); 
    TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); 

    /* TIM2 enable counter */ 
    TIM_Cmd(TIM2, ENABLE); 
} 

void PWM_SetDC(int channel,int dutycycle) 
{ 
    if (dutycycle <= 100 && dutycycle >= 0) 
    { 
     pulse_width=(Period*dutycycle)/100; 
      if (channel == 1) 
      { 
      TIM2->CCR1 = pulse_width; 

      } 
      else if (channel == 2) 
      { 

      TIM2->CCR2 = pulse_width; 
      } 
      else if (channel == 3) 
      { 
      TIM2->CCR3 = pulse_width; 
      } 
      else 
      { 
      TIM2->CCR4 = pulse_width; 
      } 
    } 
} 

void LED_Config(void) 
{ 
    /* GPIOD Peripheral clock enable */ 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); 

    /* Configure PD12, PD13, PD14 and PD15 in output push-pull mode */ 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
    GPIO_Init(GPIOD, &GPIO_InitStructure); 

} 

/* Delay Function. 
* nCount:specifies the Delay time length. 
*/ 
void Delay(__IO int nCount) 
{ 
    while(nCount--) 
    { 
    } 
} 

답변

0

난 당신이 내가 당신의 질문을 이해할 수에 관해서 ... 당신이 조금 명확 질문 을하면 내가 당신을 도울 수 있다고 생각 -> 당신이 단계 2 PWM 년대는 이동하려는 생각? 두 개의 PWM 사이에서 간단한 위상 이동을 원할 경우 간단히 말해서 1ms의 지연을 원한다고 가정 해 봅시다. -> 다음 두 개의 다른 타이머를 사용해야합니다.

TIM_Cmd (TIM2, ENABLE);

지연 (1000);

TIM_Cmd (TIM3, ENABLE);

+0

우물은 1 개 이상의 타이머를 사용하고 싶지 않습니다. 원하는 모든 것이 하나의 타이머이고, 토글 모드는 PWM이 아니며, 4 개의 출력 신호가있어 서로의 위상을 제어 할 수 있습니다. 나는 그것이 인터럽트를 사용하여 할 수 있다고 생각하지만, 인터럽트 내부의 코드를 모른다. – co2ark5