Skip to main content
saiteja
Associate III
October 16, 2018
Question

Regarding Delay

  • October 16, 2018
  • 13 replies
  • 1835 views

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

    This topic has been closed for replies.

    13 replies

    Tesla DeLorean
    Guru
    October 16, 2018

    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 VenmoUp vote any posts that you find helpful, it shows what's working..
    saiteja
    saitejaAuthor
    Associate III
    October 27, 2018

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

    saiteja
    saitejaAuthor
    Associate III
    October 27, 2018

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

    T J
    Senior III
    October 27, 2018

    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
    Senior III
    October 27, 2018
    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
    saitejaAuthor
    Associate III
    October 27, 2018

    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
    Senior III
    October 27, 2018

    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
    saitejaAuthor
    Associate III
    October 27, 2018

    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
    saitejaAuthor
    Associate III
    October 27, 2018

    checkBackgroundServices();?

    What the above line indicates

    T J
    Senior III
    October 27, 2018

    that's for my OS,

    I check if DMAs are done, reissue commands in there...

    you don't need it when you use blocking code.