PWM Capture [0%] and [100%] Values

Status
Not open for further replies.

Knife

Member level 2
Joined
Apr 26, 2009
Messages
43
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Visit site
Activity points
1,593
Hi Everybody

I want to measure 3 different PWM signal and using STM8S. PWM signal duty is changing between 0% and 100%. System start 0%, 100% or any value between 0% and 100%. I am using an optocoupler and I'm getting reversed of input PWM. Also I reversed again when I calculate duty and I get real duty.

I'm catching 0% and 100% values an 6ms timeout timer in main program. I'm using TIM2 for this. I can catch all values when I apply a input PWM. If I apply second or third channel or all of them, I can not catch 2-3% PWM each channel. I read random variables.

I think that is cause from resetting TIM1 counter (TIM1_SetCounter(0x00) but I didn't handle.

Code:
void Initialize(void)
{
	CLK_DeInit();
	CLK_HSICmd(ENABLE);
	CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
	
	TIM1_DeInit();
	TIM1_TimeBaseInit(63, TIM1_COUNTERMODE_UP, 0xFFFF, 0);
	TIM1_ICInit( TIM1_CHANNEL_1, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI,
               TIM1_ICPSC_DIV1, 0x0);
	TIM1_ICInit( TIM1_CHANNEL_2, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI,
               TIM1_ICPSC_DIV1, 0x0);
	TIM1_ICInit( TIM1_CHANNEL_3, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI,
               TIM1_ICPSC_DIV1, 0x0);								 
							 
	TIM1_Cmd(ENABLE);
	
	TIM1_ITConfig(TIM1_IT_CC1, ENABLE);
	TIM1_ITConfig(TIM1_IT_CC2, ENABLE);
	TIM1_ITConfig(TIM1_IT_CC3, ENABLE);
	
	TIM2_DeInit();
	TIM2_TimeBaseInit(TIM2_PRESCALER_1, 32000);  //4ms period
	TIM2_PrescalerConfig(TIM2_PRESCALER_1, TIM2_PSCRELOADMODE_IMMEDIATE);
	
	TIM2_Cmd(ENABLE);
	
	TIM2_ITConfig(TIM2_IT_UPDATE, ENABLE);
		
	enableInterrupts();
}

void main(void)
{
	Initialize();

  while (1)
  {
	if (wPWM1_Capture_Tick > 2)//6ms timeout
	{
		if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_1) != 0)
		{
			wPWM1_PWM = 0x00;
		}
		else
		{
			wPWM1_PWM = 0xFF;
		}			
		wPWM1_Capture_Tick = 0;
	}
	
	if (wPWM2_Capture_Tick > 2)
	{
		if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_2) != 0)
		{
			wPWM2_PWM = 0x00;
		}
		else
		{
			wPWM2_PWM = 0xFF;
		}			
		wPWM2_Capture_Tick = 0;
	}
	
	if (wPWM3_Capture_Tick > 2)
	{
		if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_2) != 0)
		{
			wPWM3_PWM = 0x00;
		}
		else
		{
			wPWM3_PWM = 0xFF;
		}			
		wPWM3_Capture_Tick = 0;
	}	
  }
 
}

 INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)
{
	if(bPWM1_Capture_Tick_Enable == TRUE)
		wPWM1_Capture_Tick++;
	
	if(bPWM2_Capture_Tick_Enable == TRUE)
		wPWM2_Capture_Tick++;
	
	if(bPWM3_Capture_Tick_Enable == TRUE)
		wPWM3_Capture_Tick++;
		
	TIM2_ClearITPendingBit(TIM2_IT_UPDATE);
}

INTERRUPT_HANDLER(TIM1_CAP_COM_IRQHandler, 12)
{
	if((TIM1->SR1 & TIM1_FLAG_CC1) == TIM1_FLAG_CC1)
	{
		TIM1_ClearFlag(TIM1_FLAG_CC1);
		switch(byPWM1_State)
		{
			case 0 :
			byPWM1_State = 1;
			bCapture_Timer_Reset = TRUE; //TIM1 Counter Reset
			TIM1_ICInit( TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI,
									 TIM1_ICPSC_DIV1, 0x0);
			bPWM1_Capture_Tick_Enable = TRUE;
			break;
			case 1 :
			byPWM1_State = 2;
			wPWM1_On_Time = TIM1_GetCapture1();
			TIM1_ICInit( TIM1_CHANNEL_1, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI,
									 TIM1_ICPSC_DIV1, 0x0);
			break;
			case 2 :
			byPWM1_State = 1;
			wPWM1_Period = TIM1_GetCapture1();
			bCapture_Timer_Reset = TRUE; //TIM1 Counter Reset
			wPWM1_PWM = ((1000 * (DWORD)wPWM1_On_Time) / wPWM1_Period) / 4; //0xFF Max. Value
			TIM1_ICInit( TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI,
									 TIM1_ICPSC_DIV1, 0x0);
			wPWM1_Capture_Tick = 0;
			break;
		}
	}

	if((TIM1->SR1 & TIM1_FLAG_CC2) == TIM1_FLAG_CC2)
	{
		TIM1_ClearFlag(TIM1_FLAG_CC2);
		switch(byPWM2_State)
		{
			case 0 :
			byPWM2_State = 1;
			bCapture_Timer_Reset = TRUE;
			TIM1_ICInit( TIM1_CHANNEL_2, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI,
									 TIM1_ICPSC_DIV1, 0x0);
			bPWM2_Capture_Tick_Enable = TRUE;
			break;
			case 1 :
			byPWM2_State = 2;
			wPWM2_On_Time = TIM1_GetCapture2();
			TIM1_ICInit( TIM1_CHANNEL_2, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI,
									 TIM1_ICPSC_DIV1, 0x0);
			break;
			case 2 :
			byPWM2_State = 1;
			wPWM2_Period = TIM1_GetCapture2();
			bCapture_Timer_Reset = TRUE;
			wPWM2_PWM = ((1000 * (DWORD)wPWM2_On_Time) / wPWM2_Period) / 4;
			TIM1_ICInit( TIM1_CHANNEL_2, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI,
									 TIM1_ICPSC_DIV1, 0x0);
			wPWM2_Capture_Tick = 0;
			break;
		}
	}		

	if((TIM1->SR1 & TIM1_FLAG_CC3) == TIM1_FLAG_CC3)
	{
		TIM1_ClearFlag(TIM1_FLAG_CC3);
		switch(byPWM3_State)
		{
			case 0 :
			byPWM3_State = 1;
			bCapture_Timer_Reset = TRUE;
			TIM1_ICInit( TIM1_CHANNEL_3, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI,
									 TIM1_ICPSC_DIV1, 0x0);
			bPWM3_Capture_Tick_Enable = TRUE;
			break;
			case 1 :
			byPWM3_State = 2;
			wPWM3_On_Time = TIM1_GetCapture3();
			TIM1_ICInit( TIM1_CHANNEL_3, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI,
									 TIM1_ICPSC_DIV1, 0x0);
			break;
			case 2 :
			byPWM3_State = 1;
			wPWM3_Period = TIM1_GetCapture3();
			bCapture_Timer_Reset = TRUE;
			wPWM3_PWM = ((1000 * (DWORD)wPWM3_On_Time) / wPWM3_Period) / 4;
			TIM1_ICInit( TIM1_CHANNEL_3, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI,
									 TIM1_ICPSC_DIV1, 0x0);
			wPWM3_Capture_Tick = 0;
			break;
		}
	}	
	
	if(bCapture_Timer_Reset == TRUE)
	{
		bCapture_Timer_Reset = FALSE;
		TIM1_SetCounter(0x00);
	}
}
 

I'm still working on that. The project almost finished but I didn't solve this problem yet. Is anyone have a suggestion ?
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…