stm32duino / Arduino_Core_STM32

STM32 core support for Arduino

Home Page:https://github.com/stm32duino/Arduino_Core_STM32/wiki

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

STM32F030CCT6 InputCapture Problem

xiezhoubin opened this issue · comments

Chip:STM32F030CCT6

Core Version:2.7.1

Example:https://github.com/stm32duino/STM32Examples/blob/main/examples/Peripherals/HardwareTimer/InputCapture/InputCapture.ino

My Code:

#include <Arduino.h>
HardwareSerial mySerial(PA10, PA9);

#define pin PB15

uint32_t channel;
volatile uint32_t FrequencyMeasured, LastCapture = 0, CurrentCapture;
uint32_t input_freq = 0;
volatile uint32_t rolloverCompareCount = 0;
HardwareTimer* MyTim;

void InputCapture_IT_callback(void) {
  CurrentCapture = MyTim->getCaptureCompare(channel);
  /* frequency computation */
  if (CurrentCapture > LastCapture) {
    FrequencyMeasured = input_freq / (CurrentCapture - LastCapture);
  } else if (CurrentCapture <= LastCapture) {
    /* 0x1000 is max overflow value */
    FrequencyMeasured = input_freq / (0x10000 + CurrentCapture - LastCapture);
  }
  LastCapture = CurrentCapture;
  rolloverCompareCount = 0;
}

/* In case of timer rollover, frequency is to low to be measured set value to 0
   To reduce minimum frequency, it is possible to increase prescaler. But this is at a cost of precision. */
void Rollover_IT_callback(void) {
  rolloverCompareCount++;

  if (rolloverCompareCount > 1) {
    FrequencyMeasured = 0;
  }
}

void setup() {
  mySerial.begin(115200);

  // Automatically retrieve TIM instance and channel associated to pin
  // This is used to be compatible with all STM32 series automatically.
  pinMode(pin, INPUT_PULLUP);
  TIM_TypeDef* Instance = (TIM_TypeDef*)pinmap_peripheral(digitalPinToPinName(pin), PinMap_PWM);
  channel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin), PinMap_PWM));
  pinMode(pin, INPUT_PULLUP);
  // Instantiate HardwareTimer object. Thanks to 'new' instantiation, HardwareTimer is not destructed when setup() function is finished.
  MyTim = new HardwareTimer(Instance);

  // Configure rising edge detection to measure frequency
  MyTim->setMode(channel, TIMER_INPUT_CAPTURE_FALLING, pin);

  // With a PrescalerFactor = 1, the minimum frequency value to measure is : TIM counter clock / CCR MAX
  //  = (SystemCoreClock) / 65535
  // Example on Nucleo_L476RG with systemClock at 80MHz, the minimum frequency is around 1,2 khz
  // To reduce minimum frequency, it is possible to increase prescaler. But this is at a cost of precision.
  // The maximum frequency depends on processing of the interruption and thus depend on board used
  // Example on Nucleo_L476RG with systemClock at 80MHz the interruption processing is around 4,5 microseconds and thus Max frequency is around 220kHz
  uint32_t PrescalerFactor = 1;
  MyTim->setPrescaleFactor(PrescalerFactor);
  MyTim->setOverflow(0x10000);  // Max Period value to have the largest possible time to detect rising edge and avoid timer rollover
  MyTim->attachInterrupt(channel, InputCapture_IT_callback);
  MyTim->attachInterrupt(Rollover_IT_callback);
  MyTim->resume();

  // Compute this scale factor only once
  input_freq = MyTim->getTimerClkFreq() / MyTim->getPrescaleFactor();
}

void loop() {
  /* Print frequency measured on Serial monitor every seconds */
  mySerial.println((String) "Frequency = " + FrequencyMeasured);
  delay(1000);
}

Problem:
I used the official input capture code example and used the PB15 pin of SMT32F030CCT6 as the input pin. In reality, I measured the frequency of this pin at around 265kHz using an oscilloscope, but the serial port printed in the code was 0kHz.
1eb1916fb49e949daa4ad78389880c69

Did you read all comments ?
// Example on Nucleo_L476RG with systemClock at 80MHz the interruption processing is around 4,5 microseconds and thus Max frequency is around 220kHz

Looking at the mcu description:
The STM32F030x4/x6/x8/xC microcontrollers incorporate the high-performance Arm® Cortex®-M0 32-bit RISC core operating at a 48 MHz frequency,

Important

Please avoid to open an issue each time you met a problem. Try the forum or the GH discussion instead.

Did you read all comments ? // Example on Nucleo_L476RG with systemClock at 80MHz the interruption processing is around 4,5 microseconds and thus Max frequency is around 220kHz

Looking at the mcu description: The STM32F030x4/x6/x8/xC microcontrollers incorporate the high-performance Arm® Cortex®-M0 32-bit RISC core operating at a 48 MHz frequency,

Important

Please avoid to open an issue each time you met a problem. Try the forum or the GH discussion instead.

May I ask how to use the PB15 pin of STM32F030CCT6 to measure the frequency between 10kHz and 500kHz

You can't measure 500kHz as stated before. F030CC max freq is only 48MHz....