This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Debugger hangs on Float instruction

When I run this code on my STM32L1 board, the debugger hangs once it reaches to a Float (in this case the variable 'Distance') or Delay, I mean it seems like it's processing, however it never goes through, and I have to close it and run the debugger again, which hangs of course again. Note that the code builds without errors or warnings.
Is there's any special configuration for float ?

The following is the related part of the code:


void Delay(int x){
    //input milliseconds, delay that number of milliseconds
    int a,b;
    for(a=0; a<x; a++){
        for(b=0; b<1000; b++){
        }
    }
}
                .
                .
                .

volatile int timespan = 0;                      // Total pulse width

int main(void){

                float Distance;     // actual distance in cm
                .
                .
                .

    while(1){

        TIM4_Echo_Read();

    Distance = (timespan / 58.0);

        if (Distance <= 100){

            GPIOB->BSRRL = (1<<7);
        }
            else {
            GPIOB->BSRRH = (1<<7);

            }
                Delay(10);
        }

timespan is declared as a global int.
Note that none of this happens when I declare Distance as int instead of float.

Any idea why the debugger keeps getting stuck on float instructions?

Parents
  • #include <stdio.h>
    #include "stm32l1xx.h"                  // Keil::Device:Startup
    
            //Initialize the timers variables.
        volatile int timespan = 0;      // Total pulse width
        volatile int lastcounter = 0;   // Timer counter value of the last event
        volatile int newcounter = 0;    // Timer counter value of the current event
        volatile int overflow = 0;      // Count the number of overflows
    
        void SetHSI(void);
        void Delay(int);
        void GPIO_config(void);
        void TIM2_Trigger(void);
        void TIM4_Init(void);
        void TIM4_Echo_Read(void);
        void LED (void);
    
    
            int main(void){
    
                SetHSI();
                GPIO_config();
                TIM2_Trigger();
                TIM4_Init();
    
    
              while(1){
    
                 TIM4_Echo_Read();
                 LED();
    
                 Delay(100);
          }
       }
    
    void Delay(int x){
        //input milliseconds, delay that number of milliseconds
        int a,b;
        for(a=0; a<x; a++){
            for(b=0; b<1000; b++){
            }
        }
    }
    
      //set HSI as SystemCoreClock (HSE is not populated on STM32L-Discovery board)//
    
    void SetHSI(void) {
    
    // Turn on HSI (16MHz)
    RCC->CR |= RCC_CR_HSION;
    // Wait until HSI is ready
    while( (RCC->CR & RCC_CR_HSIRDY) == 0);
    // Select HSI as system clock
    RCC->CFGR &= ~RCC_CFGR_SW_HSI;
    RCC->CFGR |= RCC_CFGR_SW_HSI;
    while( (RCC->CFGR & RCC_CFGR_SWS)!=RCC_CFGR_SWS_HSI ); // Wait till HSI
    }
    
    // Configure GPIO Port B
    void GPIO_config(void){
    
        RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST;   // Reset GPIOB clock
        RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOBRST;  // Clear Reset
        RCC->AHBENR |= RCC_AHBENR_GPIOBEN;      // Enable GPIOB clock
    
        //PB6 Echo Pin
        GPIOB->MODER   &=   ~(0x03 << 12);    // Clear bit 12 & 13 Alternate function mode
        GPIOB->MODER   |=   (0x02 << 12);    // set as Alternate function mode
        GPIOB->OSPEEDR &=   ~(0x03<< 12);   // 40 MHz  speed
        GPIOB->OSPEEDR |=   (0x03<< 12);    // 40 MHz  speed
        GPIOB->PUPDR &=         ~(0X3<<12); // NO PULL-UP PULL-DOWN
        GPIOB->OTYPER &=        ~(1<<6);    // PUSH-PULL
        GPIOB->AFR[0] &= ~GPIO_AFRL_AFRL6;  // Clear pin 6 for alternate function
        GPIOB->AFR[0] |=        0x2 << (4*6);   // set PB pin 6 as AF2 (TIM4_CH1)
    
    //PB10 Pluse Generating Pin
        GPIOB->MODER   &=   ~(0x03 << (2*10));  // Clear bit 12 & 13 Alternate function mode
        GPIOB->MODER   |=   0x02 << (2*10);     // set as Alternate function mode
        GPIOB->OSPEEDR &=   ~(0x03<< (2*10));   // 40 MHz  speed
        GPIOB->OSPEEDR |=   0x03<< (2*10);      // 40 MHz  speed
        GPIOB->PUPDR &=         ~(1<<10);       // NO PULL-UP PULL-DOWN
        GPIOB->OTYPER &=        ~(1<<10);       // PUSH-PULL
        GPIOB->AFR[1] |=        0x1 << (4*2);   // set PB pin 10 as AF1 (TIM2_CH3)
    
    //PB7 LED ON/OFF
        GPIOB->MODER   |=   GPIO_MODER_MODER7_0;   // General purpose output mode
      GPIOB->OSPEEDR |=   GPIO_OSPEEDER_OSPEEDR7;  // Max High speed 50MHz
    
    
    }
    
    // CONFIGURE TIM2 FOR SENDING OUTPUT SIGNAL
    void TIM2_Trigger(void){
        RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // ENABLE TIM2 CLOCK
        TIM2->PSC = 159;                    // SET APPROPRAIT PRESCALER TO SLOW DOWN THE CLOCK
        TIM2->ARR = 0XFFFF;         // SET MAX PULSE WIDTH OF 65536us FOR 16-BIT TIMER
    
        TIM2->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; // 111: PWM mode 1
        TIM2->CCMR2 |= TIM_CCMR2_OC3PE;         // CH3 Output Preload Enable
        TIM2->CR1 |= TIM_CR1_ARPE;              // Auto-reload Prelaod Enable
        TIM2->CCER |= TIM_CCER_CC3E;            // Enable Output for CH3
        TIM2->EGR |= TIM_EGR_UG;                // Force Update
        TIM2->SR &= ~TIM_SR_UIF;                // Clear the Update Flag
        TIM2->DIER |= TIM_DIER_UIE;             // Enable Interrupt on Update
        TIM2->CR1 &= ~TIM_CR1_DIR;              // Set upcounting counter direction
        TIM2->CCR3 &= ~(TIM_CCR3_CCR3);         // Clear CCR3 (Channel 3)
        TIM2->CCR3 |= 0x1;                      // Load the register
        TIM2->CR1 |= TIM_CR1_CEN;               // Enable the counter
    }
    
    
    // CONFIGURE TIM4 FOR RECEIVING INPUT SIGNAL
    void TIM4_Init(void){
        RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;         // ENABLE TIM4 CLOCK
        TIM4->PSC = 15;                             // SET APPROPRAIT PRESCALER TO SLOW DOWN THE CLOCK
        TIM4->ARR = 0xFFFF;                         // SET MAX PULSE WIDTH OF 65536us FOR 16-BIT TIMER
        TIM4->CCMR1 &= ~TIM_CCMR1_CC1S;             // CLEAR CAPTURE/COMPARE REGISTER
        TIM4->CCMR1 |= 0X1;                         // SELECT CH1 INPUTE CAPTURE
        TIM4->CCMR1 &= ~TIM_CCMR1_IC1F;             // DISABLE DIGITAL FILTERING
        TIM4->CCER |= (1<<1 | 1<<3);                // SELECT BOTH RISING AND FALLING EDGE DETECTION CC1P & CC1NP
        TIM4->CCMR1 &= ~(TIM_CCMR1_IC1PSC);         // INPUT PRESCALER 0 TO CAPTURE EACH VALID EDGE
        TIM4->DIER |= TIM_DIER_UIE;                 // UPDATE INTERRUPT ENABLE
        TIM4->CCER |= TIM_CCER_CC1E;                // ENABLE COUNTER CAPTURE
        TIM4->DIER |= TIM_DIER_CC1IE;               // ENABLE CH1 CAPTURE/COMPARE INTERRUPT
        TIM4->CR1 |= TIM_CR1_CEN;                   // Enable the counter
        NVIC_SetPriority(TIM4_IRQn, 1);             // SET PRIORITY TO 1
        NVIC_EnableIRQ(TIM4_IRQn);                  //ENABLE TIM4 INTERRUPT IN NVIC
    
    
    }
    
    void TIM4_Echo_Read(void){
    
        if ((TIM4->SR & TIM_SR_UIF) != 0){          // Check the update event flag
            overflow++;                             // if UIF = 1, increment overflow counter
            TIM4->SR &= ~TIM_SR_UIF;                // clear UIF
        }
        if ((TIM4->SR & TIM_SR_CC1IF) != 0){        // Check capture event flag
        newcounter = TIM4->CCR1;                    // read capture value, store as newcounter
        timespan = (newcounter - lastcounter)+(65536 * overflow); // calculate the total pulse width
        lastcounter = newcounter;                   // save the value of newcounter as lastcounter to be used for the next cycle
        overflow = 0;                               // clear overflow counter
        }
    
    }
    
    void LED (void){
    
        float Distance;               // actual distance in cm
        Distance = (timespan / 58.0);
    
        if (Distance <= 100.0){
    
            GPIOB->BSRRL = (1<<7);
        }
            else {
            GPIOB->BSRRH = (1<<7);
    
            }
        }
    
    

Reply
  • #include <stdio.h>
    #include "stm32l1xx.h"                  // Keil::Device:Startup
    
            //Initialize the timers variables.
        volatile int timespan = 0;      // Total pulse width
        volatile int lastcounter = 0;   // Timer counter value of the last event
        volatile int newcounter = 0;    // Timer counter value of the current event
        volatile int overflow = 0;      // Count the number of overflows
    
        void SetHSI(void);
        void Delay(int);
        void GPIO_config(void);
        void TIM2_Trigger(void);
        void TIM4_Init(void);
        void TIM4_Echo_Read(void);
        void LED (void);
    
    
            int main(void){
    
                SetHSI();
                GPIO_config();
                TIM2_Trigger();
                TIM4_Init();
    
    
              while(1){
    
                 TIM4_Echo_Read();
                 LED();
    
                 Delay(100);
          }
       }
    
    void Delay(int x){
        //input milliseconds, delay that number of milliseconds
        int a,b;
        for(a=0; a<x; a++){
            for(b=0; b<1000; b++){
            }
        }
    }
    
      //set HSI as SystemCoreClock (HSE is not populated on STM32L-Discovery board)//
    
    void SetHSI(void) {
    
    // Turn on HSI (16MHz)
    RCC->CR |= RCC_CR_HSION;
    // Wait until HSI is ready
    while( (RCC->CR & RCC_CR_HSIRDY) == 0);
    // Select HSI as system clock
    RCC->CFGR &= ~RCC_CFGR_SW_HSI;
    RCC->CFGR |= RCC_CFGR_SW_HSI;
    while( (RCC->CFGR & RCC_CFGR_SWS)!=RCC_CFGR_SWS_HSI ); // Wait till HSI
    }
    
    // Configure GPIO Port B
    void GPIO_config(void){
    
        RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST;   // Reset GPIOB clock
        RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOBRST;  // Clear Reset
        RCC->AHBENR |= RCC_AHBENR_GPIOBEN;      // Enable GPIOB clock
    
        //PB6 Echo Pin
        GPIOB->MODER   &=   ~(0x03 << 12);    // Clear bit 12 & 13 Alternate function mode
        GPIOB->MODER   |=   (0x02 << 12);    // set as Alternate function mode
        GPIOB->OSPEEDR &=   ~(0x03<< 12);   // 40 MHz  speed
        GPIOB->OSPEEDR |=   (0x03<< 12);    // 40 MHz  speed
        GPIOB->PUPDR &=         ~(0X3<<12); // NO PULL-UP PULL-DOWN
        GPIOB->OTYPER &=        ~(1<<6);    // PUSH-PULL
        GPIOB->AFR[0] &= ~GPIO_AFRL_AFRL6;  // Clear pin 6 for alternate function
        GPIOB->AFR[0] |=        0x2 << (4*6);   // set PB pin 6 as AF2 (TIM4_CH1)
    
    //PB10 Pluse Generating Pin
        GPIOB->MODER   &=   ~(0x03 << (2*10));  // Clear bit 12 & 13 Alternate function mode
        GPIOB->MODER   |=   0x02 << (2*10);     // set as Alternate function mode
        GPIOB->OSPEEDR &=   ~(0x03<< (2*10));   // 40 MHz  speed
        GPIOB->OSPEEDR |=   0x03<< (2*10);      // 40 MHz  speed
        GPIOB->PUPDR &=         ~(1<<10);       // NO PULL-UP PULL-DOWN
        GPIOB->OTYPER &=        ~(1<<10);       // PUSH-PULL
        GPIOB->AFR[1] |=        0x1 << (4*2);   // set PB pin 10 as AF1 (TIM2_CH3)
    
    //PB7 LED ON/OFF
        GPIOB->MODER   |=   GPIO_MODER_MODER7_0;   // General purpose output mode
      GPIOB->OSPEEDR |=   GPIO_OSPEEDER_OSPEEDR7;  // Max High speed 50MHz
    
    
    }
    
    // CONFIGURE TIM2 FOR SENDING OUTPUT SIGNAL
    void TIM2_Trigger(void){
        RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // ENABLE TIM2 CLOCK
        TIM2->PSC = 159;                    // SET APPROPRAIT PRESCALER TO SLOW DOWN THE CLOCK
        TIM2->ARR = 0XFFFF;         // SET MAX PULSE WIDTH OF 65536us FOR 16-BIT TIMER
    
        TIM2->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; // 111: PWM mode 1
        TIM2->CCMR2 |= TIM_CCMR2_OC3PE;         // CH3 Output Preload Enable
        TIM2->CR1 |= TIM_CR1_ARPE;              // Auto-reload Prelaod Enable
        TIM2->CCER |= TIM_CCER_CC3E;            // Enable Output for CH3
        TIM2->EGR |= TIM_EGR_UG;                // Force Update
        TIM2->SR &= ~TIM_SR_UIF;                // Clear the Update Flag
        TIM2->DIER |= TIM_DIER_UIE;             // Enable Interrupt on Update
        TIM2->CR1 &= ~TIM_CR1_DIR;              // Set upcounting counter direction
        TIM2->CCR3 &= ~(TIM_CCR3_CCR3);         // Clear CCR3 (Channel 3)
        TIM2->CCR3 |= 0x1;                      // Load the register
        TIM2->CR1 |= TIM_CR1_CEN;               // Enable the counter
    }
    
    
    // CONFIGURE TIM4 FOR RECEIVING INPUT SIGNAL
    void TIM4_Init(void){
        RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;         // ENABLE TIM4 CLOCK
        TIM4->PSC = 15;                             // SET APPROPRAIT PRESCALER TO SLOW DOWN THE CLOCK
        TIM4->ARR = 0xFFFF;                         // SET MAX PULSE WIDTH OF 65536us FOR 16-BIT TIMER
        TIM4->CCMR1 &= ~TIM_CCMR1_CC1S;             // CLEAR CAPTURE/COMPARE REGISTER
        TIM4->CCMR1 |= 0X1;                         // SELECT CH1 INPUTE CAPTURE
        TIM4->CCMR1 &= ~TIM_CCMR1_IC1F;             // DISABLE DIGITAL FILTERING
        TIM4->CCER |= (1<<1 | 1<<3);                // SELECT BOTH RISING AND FALLING EDGE DETECTION CC1P & CC1NP
        TIM4->CCMR1 &= ~(TIM_CCMR1_IC1PSC);         // INPUT PRESCALER 0 TO CAPTURE EACH VALID EDGE
        TIM4->DIER |= TIM_DIER_UIE;                 // UPDATE INTERRUPT ENABLE
        TIM4->CCER |= TIM_CCER_CC1E;                // ENABLE COUNTER CAPTURE
        TIM4->DIER |= TIM_DIER_CC1IE;               // ENABLE CH1 CAPTURE/COMPARE INTERRUPT
        TIM4->CR1 |= TIM_CR1_CEN;                   // Enable the counter
        NVIC_SetPriority(TIM4_IRQn, 1);             // SET PRIORITY TO 1
        NVIC_EnableIRQ(TIM4_IRQn);                  //ENABLE TIM4 INTERRUPT IN NVIC
    
    
    }
    
    void TIM4_Echo_Read(void){
    
        if ((TIM4->SR & TIM_SR_UIF) != 0){          // Check the update event flag
            overflow++;                             // if UIF = 1, increment overflow counter
            TIM4->SR &= ~TIM_SR_UIF;                // clear UIF
        }
        if ((TIM4->SR & TIM_SR_CC1IF) != 0){        // Check capture event flag
        newcounter = TIM4->CCR1;                    // read capture value, store as newcounter
        timespan = (newcounter - lastcounter)+(65536 * overflow); // calculate the total pulse width
        lastcounter = newcounter;                   // save the value of newcounter as lastcounter to be used for the next cycle
        overflow = 0;                               // clear overflow counter
        }
    
    }
    
    void LED (void){
    
        float Distance;               // actual distance in cm
        Distance = (timespan / 58.0);
    
        if (Distance <= 100.0){
    
            GPIOB->BSRRL = (1<<7);
        }
            else {
            GPIOB->BSRRH = (1<<7);
    
            }
        }
    
    

Children
No data