AnsweredAssumed Answered

STM32F4 input output PWM program

Question asked by larose.louis_antoine on Aug 14, 2014
Latest reply on Aug 15, 2014 by Clive One
Hi


I'm programming this code. 
It should read a PWM input then ouputs 4 different PWM after calculation based on the input. 
I've successfully programmed 2 different code: one for the input and one for the output. 

They worked fine. 

But when I try to combine them, the program goes into infinite loop or it gives 0 as PWM input reading. 

Does this code have some kind of conflict between the input and output configuration ?

/* Includes */
#include <stdio.h>
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"


/* Private typedef */
/* Private macro */
/* Private variables */
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
GPIO_InitTypeDef  GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
TIM_ICInitTypeDef  TIM_ICInitStructure;
uint16_t CCR1_Val = 333;
uint16_t CCR2_Val = 249;
uint16_t CCR3_Val = 166;
uint16_t CCR4_Val = 83;
uint16_t PrescalerValue = 0;
/* Private function prototypes */
void TIM_Config(void);
void PWM_Config(int period);
void PWM_SetDC(uint16_t channel,uint16_t dutycycle);


/* Private functions */
int main(void)
{
     TIM_Config();
     LED_Config();
     PWM_Config(800);


     while(1)
     {
          uint32_t freq = TIM4->CCR2;
          uint32_t duty = TIM4->CCR1;
          uint32_t ratio = duty/freq;
          printf("freq : %u duty : %u\n", (unsigned int)freq, (unsigned int)duty);
          PWM_SetDC(1,ratio*0.25);      //TIM3 PC0
          PWM_SetDC(2,ratio*0.5);      //TIM3 PC1
          PWM_SetDC(3,ratio*0.75);      //TIM3 PC2
          PWM_SetDC(4,ratio*0.99);      //TIM3 PC3
     }
}


void TIM_Config(void)
{
     GPIO_InitTypeDef GPIO_InitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;


     // OUTPUT CONFIGURATION


     /* TIM3 clock enable */
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);


     /* GPIOC clock enable */
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);


     // OUPUT TIM3 CONFIGURATION
     /* GPIO Configuration: TIM3 CH1 (PC0) and TIM3 CH2 (PC1) (PC2) (PC3) */
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
     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(GPIOC, &GPIO_InitStructure);


     /* Connect TIM3 pins to AF2 */
     GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);
     GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3);
     GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM3);
     GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_TIM3);


     // INPUT CONFIGURATION
     /* TIM4 clock enable */
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);


     /* GPIOB clock enable */
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);


     /* TIM4 chennel2 configuration : PB.07 */
     GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;
     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(GPIOB, &GPIO_InitStructure);


     /* Connect TIM pin to AF2 */
     GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4);


     /* Enable the TIM4 global Interrupt */
     NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
}


void PWM_Config(int period)
{
     // OUPUT CONFIGURATION -> TIM3
     uint16_t PrescalerValue = 0;
     
     /* Compute the prescaler value */
     PrescalerValue = (uint16_t) ((SystemCoreClock/2)/28000000)-1;


     /* Time base configuration */
     TIM_TimeBaseStructure.TIM_Period = period;
     TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
     TIM_TimeBaseStructure.TIM_ClockDivision = 0;
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;


     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);


     /* PWM1 Mode configuration: Channel 1 */
     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
     TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;


     TIM_OC1Init(TIM3, &TIM_OCInitStructure);
     TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);


     /*PWM1 mode configuration : Channel 2 */
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
     TIM_OCInitStructure.TIM_Pulse = CCR2_Val;


     TIM_OC2Init(TIM3, &TIM_OCInitStructure);
     TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);


     /* PWM1 Mode configuration: Channel3 */
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
     TIM_OCInitStructure.TIM_Pulse = CCR3_Val;


     TIM_OC3Init(TIM3, &TIM_OCInitStructure);
     TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);


     /* PWM1 Mode configuration : Channel4*/
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
     TIM_OCInitStructure.TIM_Pulse = CCR4_Val;


     TIM_OC4Init(TIM3, &TIM_OCInitStructure);
     TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);


     TIM_ARRPreloadConfig(TIM3,ENABLE);


     /* TIM3 ENABLE COUNTER */
     TIM_Cmd(TIM3, ENABLE);


     // INPUT CONFIGURATION
     TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
     TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
     TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
     TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
     TIM_ICInitStructure.TIM_ICFilter = 0x0;


     TIM_PWMIConfig(TIM4, &TIM_ICInitStructure);


     /* Select the TIM4 Input Trigger: TI2FP2 */
     TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);


     /* Select the slave Mode: Reset Mode */
     TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
     TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);


     /* TIM enable counter */
     TIM_Cmd(TIM4, ENABLE);


     /* Enable the CC2 Interrupt Request */
     TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE);
}


void PWM_SetDC(uint16_t channel, uint16_t dutycycle)
{
     switch(channel)
     {
          case 1:
               TIM3->CCR1 = dutycycle;
               break;
          case 2:
               TIM3->CCR2 = dutycycle;
               break;
          case 3:
               TIM3->CCR3 = dutycycle;
               break;
          case 4:
               TIM3->CCR4 = dutycycle;
               break;
          default:
               break;
     }
}




Thank you. 
LAL. 

Outcomes