cancel
Showing results for 
Search instead for 
Did you mean: 

Regarding Delay

saiteja
Associate II

Hi..... i am a masters student from india. I have developed a code for RGBW now i want to include strobe effect for that i have give a hal_delay it is working fine now i want to change the PWM of RGBW when it is in strobe effect both has to work simultaneously but it is getting hanged i think this is due to Hal_delay i think this problem will be reduced if i give timer delay or i want to do something if it will solved with timer how to give timer delay in STM Controller.. I am using STM32F407VG controller.. Can someone help me out in this....... Thanks in Advance

13 REPLIES 13

The HAL_Delay is rather course you could use a 32-bit timer like TIM2 or TIM5 to count microseconds or faster, and delta the TIM->CNT as it advances or use the cores DWT_CYCCNT

The HAL method is also dependent on a interrupt so can be a problem if interrupt priorities are wrong and used in callback routines.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
saiteja
Associate II

I am giving interrupt priority to 0. could you please give me a sample code for better understanding

saiteja
Associate II

i think timer handler will work out but iam didn't understand how to give it

T J
Lead

first you would have to initialise the timer... are you using the cube ?

void start_Timer4(void) {
		HAL_TIMEx_OCN_Start(&htim4,TIM_CHANNEL_1);
		HAL_TIM_Base_Start(&htim4);
}

T J
Lead
void resetTim2ChannelCounter(TIM_HandleTypeDef *htim, uint32_t channel) {
  uint32_t tmp;
 
  tmp = htim->Instance->CNT;
 
	htim->Instance->CCR1 = tmp;
	htim->Instance->SR   =  ! TIM_SR_CC1IF;  // clear the flag				
}
void waitTim2ChannelComplete(TIM_HandleTypeDef *htim) {
 
  uint32_t tmp;
		
  tmp = 0;
  while( ! tmp ){
      checkBackgroundServices(); // OS services
      tmp = htim->Instance->SR & TIM_SR_CC1IF;
    }
    htim->Instance->SR   =  ! TIM_SR_CC1IF;  // clear the flag				
}

saiteja
Associate II

void MX_TIM5_Init(void)

{

 TIM_ClockConfigTypeDef sClockSourceConfig;

 TIM_MasterConfigTypeDef sMasterConfig;

 htim5.Instance = TIM5;

 htim5.Init.Prescaler = 84;

 htim5.Init.CounterMode = TIM_COUNTERMODE_UP;

 htim5.Init.Period = 99; //interrupt in 100 micro sec

// htim5.Init.Period = 50; //interrupt in 50 micro sec

 htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 if (HAL_TIM_Base_Init(&htim5) != HAL_OK)

 {

  Error_Handler();

 }

 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

 if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

 if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)

 {

  Error_Handler();

 }

}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)

{

 if(tim_baseHandle->Instance==TIM5)

 {

 /* USER CODE BEGIN TIM5_MspInit 0 */

 /* USER CODE END TIM5_MspInit 0 */

  /* Peripheral clock enable */

  __HAL_RCC_TIM5_CLK_ENABLE();

  /* Peripheral interrupt init */

  HAL_NVIC_SetPriority(TIM5_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(TIM5_IRQn);

 /* USER CODE BEGIN TIM5_MspInit 1 */

 /* USER CODE END TIM5_MspInit 1 */

 }

}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)

{

 if(tim_baseHandle->Instance==TIM5)

 {

 /* USER CODE BEGIN TIM5_MspDeInit 0 */

 /* USER CODE END TIM5_MspDeInit 0 */

  /* Peripheral clock disable */

  __HAL_RCC_TIM5_CLK_DISABLE();

  /* Peripheral interrupt Deinit*/

  HAL_NVIC_DisableIRQ(TIM5_IRQn);

 }

 /* USER CODE BEGIN TIM5_MspDeInit 1 */

 /* USER CODE END TIM5_MspDeInit 1 */

 void start_Timer4(void) {

HAL_TIMEx_OCN_Start(&htim5,TIM_CHANNEL_1);

HAL_TIM_Base_Start(&htim5);

}

void resetTim5ChannelCounter(TIM_HandleTypeDef *htim, uint32_t channel) {

uint32_t tmp;

tmp = htim5->Instance->CNT;

htim5->Instance->CCR1 = tmp;

htim5->Instance->SR = ! TIM_SR_CC1IF; // clear the flag

}

void waitTim2ChannelComplete(TIM_HandleTypeDef *htim) {

uint32_t tmp;

tmp = 0;

while( ! tmp ){

checkBackgroundServices(); // OS services

tmp = htim->Instance->SR & TIM_SR_CC1IF;

}

htim->Instance->SR = ! TIM_SR_CC1IF; // clear the flag

}

SetPWM(x,dutycycle);

SetPWM(y,dutycycle);

SetPWM(z,dutycycle);

start_Timer5(void);

SetPWM(x,0);

SetPWM(y,0);

SetPWM(z,0);

start_Timer5(void);

is this is what you are asking me to do or some thing else... if any mistake just correct me

T J
Lead

at some stage you have started your timer...

start_Timer5();
while(1){  ....... }
can you add these functions ?
 
extern "C" void wait_us(int uS) {
    resetTimChanneluSCounter(&htim5, 1, uS);
    waitTimChannelComplete(&htim5, 1);
}
 
void resetTimChanneluSCounter(TIM_HandleTypeDef *htim, uint32_t channel, int16_t uS) {  // tuned to F767 
    uint32_t uS_Counts;  
    if (uS < 8)
        uS_Counts = ((int32_t) 13480 *8) / 1000;
    else
        uS_Counts = ((int32_t) 13480 *(uS-4)) / 1000;
        
    switch (channel) { // used to have &=
    case 1: {
        htim->Instance->CCR1 = htim->Instance->CNT + uS_Counts;
            htim->Instance->SR   =  !TIM_SR_CC1IF;  // clear the flag    
            break;
        }
    case 2: {
        htim->Instance->CCR2 = htim->Instance->CNT + uS_Counts;
            htim->Instance->SR   =  !TIM_SR_CC2IF;  // clear the flag
            break;
        }
    case 3: {
        htim->Instance->CCR3 = htim->Instance->CNT + uS_Counts;
            htim->Instance->SR   =  !TIM_SR_CC3IF;  // clear the flag
            break;
        }
    case 4: {
        htim->Instance->CCR4 = htim->Instance->CNT + uS_Counts;
            htim->Instance->SR   =  !TIM_SR_CC4IF;  // clear the flag
            break;
        }
    }    
}
 
void waitTimChannelComplete(TIM_HandleTypeDef *htim, uint32_t channel) {
 
  uint32_t tmp;
  
 tmp = 0;
 while( ! tmp ){
 
  checkBackgroundServices(); // OS services
    
  switch (channel){
   case 1: 
       tmp = htim->Instance->SR & TIM_SR_CC1IF;
       break;
   case 2:
       tmp = htim->Instance->SR & TIM_SR_CC2IF;
       break;
   case 3:
       tmp = htim->Instance->SR & TIM_SR_CC3IF;
       break;
   case 4:
       tmp = htim->Instance->SR & TIM_SR_CC4IF;
       break;   
  } 
 }
 switch (channel){  // used to have &=
  case 1:{
      htim->Instance->SR   =  ! TIM_SR_CC1IF;  // clear the flag    
      break;
  }
  case 2:{
      htim->Instance->SR   =  ! TIM_SR_CC2IF;  // clear the flag
      break;
  }
  case 3:{
      htim->Instance->SR   =  ! TIM_SR_CC3IF;  // clear the flag
      break;
  }
  case 4:{
      htim->Instance->SR   =  ! TIM_SR_CC4IF;  // clear the flag
      break;
  }
 }
}
//******************
 
 
start_Timer5();
while(1){  ....... }
 
 
in your code:
SetPWM(x,dutycycle);
SetPWM(y,dutycycle);
SetPWM(z,dutycycle);
wait_us(10);   // blocking code
SetPWM(x,dutycycle);
SetPWM(y,dutycycle);
SetPWM(z,dutycycle);
 
 
 
// non blocking code:
if ( htim->Instance->SR & TIM_SR_CC1IF){ process next PWM }

saiteja
Associate II

is really CCR1,2,3,4 are required i think ccr1 is enough.... ok i'll try this method and get back to you...

Thank You :)

saiteja
Associate II

checkBackgroundServices();?

What the above line indicates