STM32 Input Capture Mode Not Working - Page 1
Forum section: electronics / general

author: Etesla
author_rank: Regular Contributor
timestamp: July 29, 2022, 03:41:43 am
content: Hi All. I'm just trying to get the most basic functionality of input capture mode to do anything. I can do so with the pin PB9, but I cannot seem to do so with pin PA7. I want to use PA7.STM32F072 MCUI'm trying to capture a rising edge and lock in a timers value when I do so.I'm trying to use TIM17 for no specific reason.I see that TIM17_CH1 is mapped as alternate function 5 on PA7. I want to use PA7. (It's also mapped to PB9. If I use PB9 it works great, but it does not seem to work with PA7???)So far I have:int main(void){RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // enable GPIO Port A clockRCC->APB2ENR |= RCC_APB2ENR_TIM17EN; // enable the clock for TIM17GPIOA->MODER |= GPIO_MODER_MODER7_1; // set PA7 into alternate function modeGPIOA->AFR |= 0x50000000; // select AF5 for PA7// If I try to use PB9 instead of PA7 then it works fine. Why can't I use PA7 though???//RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // enable GPIO Port B clock//GPIOB->MODER |= GPIO_MODER_MODER9_1; // set PB9 into alternate function mode//GPIOA->AFR |= 0x20; // select AF2 for PB9TIM17->CCMR1 |= TIM_CCMR1_CC1S_0; // input on TI1TIM17->CCER |= TIM_CCER_CC1E; // enable the inputTIM17->CR1 |= TIM_CR1_CEN; // turn on the timerwhile(1); // give PA7 a bunch of rising and falling edges while debugging to try to get CCR1 or CC1IF to do anything}I put rising and falling edges on PA7 expecting something to happen. While debugging I look for:The CC1IF bit to flip to a 1 when I put a rising edge on PA7The CCR1 register to change from the default value of 0.Neither of these things ever happen. Those things do happen when I use PB9.What am I doing wrong in the setup of this input capture with PA7? Is there an extra register somewhere dictating whether I can use PA7 VS PB9 as TIM17_CH1? Was there a typo in the documentation and PA7 is not actually associated with TIM17_CH1? What's going on here?

author: pcprogrammer
author_rank: Super Contributor
timestamp: July 29, 2022, 05:36:04 am
content: I did not check if it is also on the MCU you are using, but I know from the F103 and F303 that you have to enable the clock for the alternate function peripheral too.Check the RCC enable registers to see where the bit for it sits.Edit: I just downloaded the manual for your MCU and it does not use the mentioned above.It does have this section, so the question is what values you set into the registers?QuoteEdit2:Code:int main(void){RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // enable GPIO Port A clockRCC->APB2ENR |= RCC_APB2ENR_TIM17EN; // enable the clock for TIM17GPIOA->MODER |= GPIO_MODER_MODER7_1; // set PA7 into alternate function modeGPIOA->AFR |= 0x50000000; // select AF5 for PA7// If I try to use PB9 instead of PA7 then it works fine. Why can't I use PA7 though???//RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // enable GPIO Port B clock//GPIOB->MODER |= GPIO_MODER_MODER9_1; // set PB9 into alternate function mode//GPIOA->AFR |= 0x20; // select AF2 for PB9TIM17->CCMR1 |= TIM_CCMR1_CC1S_0; // input on TI1TIM17->CCER |= TIM_CCER_CC1E; // enable the inputTIM17->CR1 |= TIM_CR1_CEN; // turn on the timerwhile(1); // give PA7 a bunch of rising and falling edges while debugging to try to get CCR1 or CC1IF to do anything}You have commented it out and is for PB9, but you are addressing the wrong register for it "GPIOA->AFR" so strange that that is working.

author: AndyC_772
author_rank: Super Contributor
timestamp: July 29, 2022, 06:12:45 am
content: Is it possible that the AFR and MODER registers bits aren't zero before your code runs? Your code ORs the existing values with new data but doesnt AND with a bit mask to clear any 1s.PA7 has analogue capability, which PB9 doesn't. If it's set in analogue mode (MODER = 0b11) before this code snippet, it won't be changed back into AF mode and won't work as a digital input at all.

author: wek
author_rank: Frequent Contributor
timestamp: July 29, 2022, 09:40:10 am
content: Read out and check/post content of TIM and relevant GPIO registers.Check hardware connection by setting given pin as GPIO Out, toggling and observing.JW

author: Etesla
author_rank: Regular Contributor
timestamp: July 29, 2022, 01:28:31 pm
content: Here's the registers if I try to use PA7:I think AFRL from the datasheet is = AFR right? And AFRH is AFR? So I think my setup for PA7 is correct so far as I can tell?

author: Etesla
author_rank: Regular Contributor
timestamp: July 29, 2022, 01:31:36 pm
content: Quote from: pcprogrammer on July 29, 2022, 05:36:04 amThat's a typo. In real life when I tested it and it worked it was GPIOB->AFR. I added the comment retroactively.

author: pcprogrammer
author_rank: Super Contributor
timestamp: July 29, 2022, 02:11:12 pm
content: The values you show in, I guess, a debug session seem to be correct, but the manual also states this:QuoteQuoteSo it looks like that even when the alternate function is selected other settings on the IO pin can influence things.Edit: You can check with your debugger if the state of PA7 changes when you make the pin high or low. It should reflect in GPIOA->IDR.

author: wek
author_rank: Frequent Contributor
timestamp: July 29, 2022, 03:32:54 pm
content: Registers look good. Now second part of my post above  or what's in edit of pcprogrammer's post above JW

author: cv007
author_rank: Frequent Contributor
timestamp: July 29, 2022, 05:41:35 pm
content: Maybe you misidentified your pins.This is for a g031 nucleo board, not much different, and works for either pin-Code:#include "MyStm32.hpp"int main(){RCC->APBENR2 |= 1<<18; //TIM17 clock enableTIM17->CCMR1 = 1;//TI1, (PA7/AF5 or PB9/AF2)TIM17->CCER = 1; //capt enableTIM17->CR1 = 1; //TIM17 enableGpioPin( PINS::PA7 ).altFunc( AF5 ); // normally a pull wanted so no floating pin-> .pull( PULLDOWN )//GpioPin( PINS::PB9 ).altFunc( AF2 ); //but floating in this case means we can just touch the pin to get transitionswhile(1){uart << "TIM17 CCR1: " << TIM17->CCR1 << endl;//shows capture values ok}}The only thing happening in the pin init is rcc enable for port, and setting the afr register then changing mode to alternate.edit- Also, if both pins are set to alternate function both become an input to the timer capture.

author: Etesla
author_rank: Regular Contributor
timestamp: July 29, 2022, 10:55:31 pm
content: It works now. Turns out the dev board I was using had an open solder bridge between the MCU pin and the header pin. I thought I had beeped it out between the header pin and MCU before, but I must have had the pin tied to ground or Vcc or something while beeping it out causing me to mistakenly think they were connected. Thanks for the help.