cancel
Showing results for 
Search instead for 
Did you mean: 

Program flow gets stuck. Why doesn't CC1IF Capture/compare interupt flag gets set, while debugging the next program on my STM32F723E-DISCOVERY?

Zeron
Associate III

A while ago I received an STM32 discoveryboard as a gift, after I told some people on a fair that I'm a software engineer. Because I'm allready experienced in C/C++ but new to embedded software engineering, I ordered a course. Now I get stuck on the chapter on Timers, because the software I wrote just isn't working as it should. Here's my source file, I'm working with Atollic Truestudio.

#include "stm32f7xx.h"

int period;

float freq;

int main(void)

{

int last_value   = 0;

int current_value = 0;

RCC->AHB1ENR   |= 0x109; // GPIOA for PA5 blue led, GPIOD for TIM4, GPIOI for TIM5

GPIOD->MODER   |= 0x2000000; // Select alternate function for PD12

GPIOD->AFR[1]   |= 0x20000; // Alternate function 2 (TIM4_CH1) for PD12

RCC->APB1ENR   |= 0x4; // Enable clock for TIM4

// This sets up a 1Hz Timer, TIM4_CH1 in output compare mode

TIM4->PSC     = 1600-1; // Set the value for the prescaler

TIM4->ARR     = 10000-1; // Set the value for the autoreloadregister

// Set the output to toggle on match

TIM4->CCMR1    |= 0x30; // Set the output to toggle on match

TIM4->CCR1    |= 0x0; // Set the match value

TIM4->CCER    |= 0x1; // Set OC1 signal as output on PD12

TIM4->CNT     = 0x0;

TIM4->CR1     = 0x1; // Counter Enable

// This sets up TIM5_CH4 in input capture mode

GPIOI->MODER   |= 0x2; // Set alternate function for PI0

GPIOI->AFR[0]   |= 0x2; // Alternate function 2 (TIM5_CH4) for PI0

RCC->APB1ENR   |= 0x8; // Enable clock for TIM5

TIM5->PSC     |= 16000-1;

TIM5->CCMR2    |= 0x4100; // Channel 4 is input, sampling every 6 ocurrences

TIM5->CCER    |= 0xB000; // Enable capture, Capture rising and falling edge

TIM5->CR1     |= 0x1; // Counter enable

while (1)

{

while(!(TIM5->SR & 0x10)){} // Wait until edge is captured. HERE PROGRAM FLOW GETS STUCK

// The part below this comment never gets executed,

// except when I disconnect and reconnect the jumper wire between PD12 and PI0,

// then the while loop condition gets matched once.

current_value = TIM5->CCR4;

period = current_value - last_value;

last_value = current_value;

freq = 1000.0f / period;

}

}

According to what I learned from the course and what I found in the reference manual, https://www.st.com/content/ccc/resource/technical/document/reference_manual/group0/c8/6b/6e/ce/dd/f7/4b/97/DM00305990/files/DM00305990.pdf/jcr:content/translations/en.DM00305990.pdf , this should work.

However, I noticed something remarkable in the manual. In chapter '19.4.7 TIMx capture/compare mode register 1 (TIMx_CCMR1)(x = 2 to 5)', 'Bits 6:4 OC1M: Output compare 1 mode.'

OC1M is a three bit field in the register diagram, however the options provided in this chapter for setting up this register all consist out of four bits. This doesn't make sense to me. Anyways, following the instructions from chapter '19.3.8 Output compare mode' I set OC1M to '011' to toggle on match.

If I understood everything right, this should set the output on PD12 to high when it's low and to low when it's high, when the value in CNT matches the value in CR1. This should be the signal that goes trough the jumper wire and should get captured by TIM5 that I assume to be running in input capture mode.

I suppose that TIM5 indeed is capturing input, due to the fact that the while loop condition that I have marked in the source file's comments gets matched when I unplug and then replug the jumperwire.

I also have a different version of this program, where I commented out the part on setting up and enabling TIM4 and decided to use plain GPIO output from PD12, by setting up GPIOD in General purpose output mode and replacing the while (1) statement with the following code.

GPIOD->MODER = 0x100000;

GPIOD->ODR = 0;

while (1)

{

while(!(TIM5->SR & 0x10))

{

//GPIOI->BSRR = (GPIOI->BSRR & 0x1) ? 0x10000 : 0x1;

if(GPIOD->ODR&0x1000)

{

GPIOD->ODR=0;

}

else

{

GPIOD->ODR=0x1000;

}

delayMs(25);

} // Wait until edge is captured

current_value = TIM5->CCR4;

period = current_value - last_value;

last_value = current_value;

freq = 1000.0f / period;

}

If I'm right this should work more or less the same as the blinking led example that I got to work earlier in the same course, but now on the timer input.

I would appreciate it if anyone with more experience than me or with better equipment available as I got could take a closer look on this issue.

Thanks in advance, Ronnie van Aarle.

15 REPLIES 15
Zeron
Associate III

I suspect maybe setting GPIOx_OTYPER and GPIO_PUPDR in a non-reset state might be the fix, however, I'm not sure what the different features are and what they do.

Does the respective GPIOB_IDR bit change?

JW

Nothing changes in GPIOB_IDR. The port is in alternate function mode, so nothing will change in here also.

IDR always reflects the input pin's state, except when it is set to Analog - i.e. also in Alternafe Function mode.

If you can't see change there, it means, the input does not change (or changes too rapidly). Use an oscilloscope/LA to observe the pin; try to connect it to high/low directly (or, maybe better, through some current limiting resistor).

JW

Indeed, I checked IDR in the debugger and its toggling on and off. I took a whole bunch of screenshots of all different debug steps to eventually come to discover that my final version of this program happens to be working afterall.

I think I should have taken a break a bit earlier. Maybe I didn't put the jumperwire in the connectors the right way, It barely fits. Or some other fysical earthly circumstance that skipped my notice.

Anyways, its working now. Thank you for your effort, I can continue to the next chapter of my course.

Zeron
Associate III

Oh no, it wasn't working. My final change of yesterday, the one that I didn't test yet made the difference.

TIM3->CCER        |= 0xB0;

should be

TIM3->CCER        |= 0xB00;

Good, I can close chapter timers now and proceed with interrupt service routines.