AnsweredAssumed Answered

PWM Feedback STM32F103ZE

Question asked by livianamj on Feb 3, 2014
Latest reply on Feb 4, 2014 by Clive One
Hello.

I've got problem here. I want to get PWM Input then show the reading result in PWM mode too. First, the PWM source is from analog input, and I can generate the PWM from that. But when I try to connect PIN output from analog to PWM input doesn't work. The register of TIM3 can't show that PWM has been captured. I am using CoOS for Operating System. So, what's wrong with my code? Can anyone help me? Thanks for your attention and help. 

Here is the code :

#include "stm32f10x.h"
#include "config.h"
#include "CoOS.h"


/* Mendefine Task Stack */
OS_STK taskA_stk[128];
OS_STK taskB_stk[128];
OS_STK taskC_stk[128];


/* Create Mutex and flag */
OS_MutexID      usart_mutx; 
OS_FlagID          taskA_flag;
OS_FlagID          taskB_flag;
OS_FlagID          taskC_flag;
volatile unsigned int Ctr = 0;


/* Private define */
#define ADC1_DR_Address     0x4001244C
#define TIM1_CCR1_Address   0x40012C34
#define TIM3_CCR2_Address          0x40010438
#define TIM3_CCR1_Address          0x40010434
#define TIM2_CCR1_Address          0x40010034
/* Private variables ---------------------------------------------------------*/
__IO uint16_t IC2Value = 0;
__IO uint16_t DutyCycle = 0;
__IO uint32_t Frequency = 0;




/* deklarasi prosedur */
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void analog_PWM (void);
void PWM_PWM (void);
void TIM3_IRQHandler(void);
void PWM_Feedback(void *pdata);


int main (void)
{


     
     
     CoInitOS();
     
     CoCreateTask(PWM_Feedback,0,1,&taskA_stk[128-1],128);
     
//      CoCreateTask(analog_PWM,0,1,&taskA_stk[128-1],128);
//      CoCreateTask(PWM_PWM,0,2,&taskB_stk[128-1],128);
     
     CoStartOS();
     
     while (1)
     {     
     }
}


void PWM_Feedback (void *pdata)
{
          
          analog_PWM();
          CoTickDelay(10);
          PWM_PWM();
          TIM3_IRQHandler();
          CoTickDelay(10);
}


void analog_PWM (void)
{
     
     
     /*Deklarasi Variabel*/
     ADC_InitTypeDef           ADC_InitStructure;
     TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
     TIM_OCInitTypeDef         TIM_OCInitStructure;
     DMA_InitTypeDef           DMA_InitStructure;
     
          /* System Clocks Configuration */
     RCC_Configuration();
     
     /* NVIC configuration */
     NVIC_Configuration();


     /* Configure the GPIO ports */
     GPIO_Configuration();
     
     /* DMA1 Channel5 configuration ----------------------------------------------*/
     DMA_DeInit(DMA1_Channel5);
     DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR1_Address;
     DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC1_DR_Address;
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
     DMA_InitStructure.DMA_BufferSize = 1;
     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
     DMA_Init(DMA1_Channel5, &DMA_InitStructure);
     
     /* Enable DMA1 Channel5 */
     DMA_Cmd(DMA1_Channel5, ENABLE);
     
     /* ADC1 configuration ------------------------------------------------------*/
     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
     ADC_InitStructure.ADC_ScanConvMode = DISABLE;
     ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
     ADC_InitStructure.ADC_NbrOfChannel = 1;
     ADC_Init(ADC1, &ADC_InitStructure);


     /* ADC1 RegularChannelConfig Test */ 
     ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 1, ADC_SampleTime_55Cycles5);




     /* TIM1 configuration ------------------------------------------------------*/
     
     /* Time Base configuration */
     TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); 
     TIM_TimeBaseStructure.TIM_Period = 0xFF0;
     TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
     TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
     
     /* Channel1 Configuration in PWM mode */
     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
     TIM_OC1Init(TIM1, &TIM_OCInitStructure);


     /* Enable TIM1 */  
     TIM_Cmd(TIM1, ENABLE);
     
     /* Enable TIM1 outputs */
     TIM_CtrlPWMOutputs(TIM1, ENABLE);


     /* Enable TIM1 DMA interface */
     TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);


     /* Enable ADC1 */
     ADC_Cmd(ADC1, ENABLE);
     
     /*Enable ADC1 DMA interface */
     ADC_DMACmd(ADC1, ENABLE);


     /* Enable ADC1 reset calibration register */
     ADC_ResetCalibration(ADC1);
     /* Check the end of ADC1 reset calibration register */
     while(ADC_GetResetCalibrationStatus(ADC1));


     /* Start ADC1 calibration */
     ADC_StartCalibration(ADC1);
     /* Check the end of ADC1 calibration */
     while(ADC_GetCalibrationStatus(ADC1));


     /* Start ADC1 conversion */ 
     ADC_SoftwareStartConvCmd(ADC1, ENABLE);
     
          //CoTickDelay(50);
}




void PWM_PWM (void)
{
     /*Deklarasi variabel*/
     TIM_ICInitTypeDef  TIM_ICInitStructure;
     TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
     TIM_OCInitTypeDef         TIM_OCInitStructure;
     DMA_InitTypeDef           DMA_InitStructure;
     
     
     /* TIM3 Channel2 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(TIM3, &TIM_ICInitStructure);
     
     /* Select the TIM3 Input Trigger: TI2FP2 */
     TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);


     /* Select the slave Mode: Reset Mode */
     TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);


     /* Enable the Master/Slave Mode */
     TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);


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


     /* Enable the CC2 Interrupt Request */
     TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
     
          /* Clear TIM3 Capture compare interrupt pending bit */
     TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);


     /* Get the Input Capture value */
     TIM_GetCapture2(TIM3);
     
     /* Enable TIM3 DMA interface */
     TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE);
     
     
     /* DMA1 Channel2 configuration ----------------------------------------------*/
     DMA_DeInit(DMA1_Channel2);
     DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM2_CCR1_Address;
     DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TIM3_CCR2_Address;
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
     DMA_InitStructure.DMA_BufferSize = 1;
     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
     DMA_Init(DMA1_Channel2, &DMA_InitStructure);
     
     /* Enable DMA1 Channel5 */
     DMA_Cmd(DMA1_Channel2, ENABLE);
     




     /* TIM2 Channnel2 configuration ------------------------------------------------------*/
     
     /* Time Base configuration */
     TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); 
     TIM_TimeBaseStructure.TIM_Period = 0xFF0;
     TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
     TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
     
     /* Channel1 Configuration in PWM mode */
     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
     TIM_OCInitStructure.TIM_Pulse = TIM_GetCapture2(TIM3);
     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
     TIM_OC2Init(TIM2, &TIM_OCInitStructure);


     /* Enable TIM2 */  
     TIM_Cmd(TIM2, ENABLE);
     
     /* Enable TIM2 outputs */
     TIM_CtrlPWMOutputs(TIM2, ENABLE);


     /* Enable TIM2 DMA interface */
     TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);
     
     /* Enable the CC2 Interrupt Request */
     TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
     
     //CoTickDelay(50);


}




void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;


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


void RCC_Configuration(void)
{


  /* ADCCLK = PCLK2/8 */
  RCC_ADCCLKConfig(RCC_PCLK2_Div8);
  
  /* Enable DMA1 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  
  /* Enable ADC1 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  
  /* TIM clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);


  /* GPIO clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOF , ENABLE);
}


void GPIO_Configuration(void)
{
     GPIO_InitTypeDef GPIO_InitStructure;
     
     /* ADC Channel 14 sebgai analog input*/
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3  ;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
     GPIO_Init(GPIOC, &GPIO_InitStructure);
     
     /*      TIM3 channel 2 pin (PA.07) configuration 
          Sebagai input PWM feedback */
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOA, &GPIO_InitStructure);
     
     /*     
          TIM1 channel 1 untuk output PWM dari analog input
          TIM2 channel 2 untuk output PWM dari PWM input
     */
     GPIO_InitStructure.GPIO_Pin      = GPIO_Pin_8 | GPIO_Pin_1 ;
     GPIO_InitStructure.GPIO_Mode      = GPIO_Mode_AF_PP;
     GPIO_InitStructure.GPIO_Speed     = GPIO_Speed_50MHz;
     GPIO_Init (GPIOA, &GPIO_InitStructure);
     
//      GPIO_InitStructure.GPIO_Pin      = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 ;
//      GPIO_InitStructure.GPIO_Mode      = GPIO_Mode_Out_PP;
//      GPIO_InitStructure.GPIO_Speed     = GPIO_Speed_50MHz;
//      GPIO_Init (GPIOF, &GPIO_InitStructure);
}


void TIM3_IRQHandler(void)
{
//      /* Clear TIM3 Capture compare interrupt pending bit */
//      TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);


//      /* Get the Input Capture value */
//      IC2Value = TIM_GetCapture2(TIM3);


     if (IC2Value != 0)
     {
          /* Duty cycle computation */
          DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;


          /* Frequency computation */
          Frequency = SystemCoreClock / IC2Value;
          
          GPIO_ResetBits (GPIOF, GPIO_Pin_8);
     }
     else
     {
          DutyCycle = 0;
          Frequency = 0;
          GPIO_SetBits (GPIOF, GPIO_Pin_8);
     }
}


Thank You very much

Outcomes