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?
#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); } }