微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

LED 闪烁“太快”@ NUCLEO-H755ZI-Q

如何解决LED 闪烁“太快”@ NUCLEO-H755ZI-Q

嗨!

根据 STM32H755ZI 的手册 RM0399,§9.5.6 (pg. 377),重置后的认时钟应为 64 MHz (HSI)。由于相同的代码在其他设备上完美运行,例如一个 NUCLEO-F303K8,我希望(红色)LED 以 1 Hz 的频率闪烁。但是,事实并非如此。我还尝试使用预分频器值 (TIM2->PSC),但这似乎没有任何效果......顺便说一句,LED 实际上闪烁,但 ~7 Hz 而不是预期的 1 Hz . 似乎 ISR 是由其他东西触发的,但如果我只是禁用 TIM2,程序执行不会到达 ISR。

/*!*****************************************************************************
 * \file main.cpp
 * \brief
 * This program implements a very basic application that makes a LED blink with
 * 1 Hz.
 */

#include <stdlib.h>

#include <stm32h755xx.h>

#define SYstem_CLOCK 64000000

/*!
 * \brief Configures pin PB14 ("LD3/Red LED") as digital output.
 */
static void Config_Red_Led(void) {
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOBEN;
  GPIOB->MODER &= ~(0x3u << (2 * 14));
  GPIOB->MODER |= (0x1u << (2 * 14));
  GPIOB->OTYPER &= ~(0x1u << 14);
  GPIOB->ODR = ~(0x1u << 14);
}

/*!
 * \brief Configures TIM2 overflow with 10 us period.
 */
static void Config_10us_Blink_Timer(void) {
  //Enable the TIM2 clock.
  RCC->APB1LENR |= RCC_APB1LENR_TIM2EN;

  //Enable TIM2 interrupts.
  NVIC_EnableIRQ(TIM2_IRQn);

  //Make sure the timer's "counter" is off.
  TIM2->CR1 &= ~TIM_CR1_CEN;

  //Reset the peripheral.
  RCC->APB1lrsTR |= (RCC_APB1lrsTR_TIM2RST);
  RCC->APB1lrsTR &= ~(RCC_APB1lrsTR_TIM2RST);

  //Set the timer prescaler/autoreload timing registers.
  TIM2->PSC = SYstem_CLOCK / 1000000;
  TIM2->ARR = 10 - 1;

  //Send an update event to reset the timer and apply settings.
  TIM2->EGR |= TIM_EGR_UG;
}

/*!
 * \brief Enables the "Blink Timer",which will Now fire interrupts that trigger
 * execution of the "App Loop" (--> \c TIM2_IRQHandler()).
 */
static void Run_App(void) {
  //Clear TIM2_IRQn update interrupt,TIM2->SR &= ~TIM_SR_UIF;

  //Enable the hardware interrupt.
  TIM2->DIER |= TIM_DIER_UIE;

  //Enable the timer.
  TIM2->CR1 |= TIM_CR1_CEN;
}

/*!
 * \brief Initializes any peripheral being used.
 */
static void Init(void) {
  //disable cpu to respond to any configurable interrupt.
  __disable_irq();

  Config_Red_Led();
  Config_10us_Blink_Timer();

  //Enable cpu to respond to any configurable interrupt.
  __enable_irq();
}

/*!
 * \brief Initializes the system and runs the application.
 */
int main(void) {
  Init();

  Run_App();

  while(true);

  return EXIT_SUCCESS;
}

/*!
 * \brief This IRQ handler will be triggered every 10 us by the "Blink Timer".
 * This "time base" is used to blink a LED with a defined pattern.
 */
extern "C" void TIM2_IRQHandler(void) {
  //Blink the LED with a PWM signal of 1 Hz period and 50% DS.
  {
    static auto s = 0;
    if(++s >= 50000) {
      //Toggle PB14,which is the LED ("LD3/Red LED").
      GPIOB->ODR ^= (1 << 14);
      s = 0;
    }
  }

  //Clear TIM2 update interrupt flag.
    TIM2->SR &= ~TIM_SR_UIF;

  //Power-down until next "tick"/interrupt.
  //__WFE();
}

如果我改用 TIM6,频率为 ~2 Hz,现在修改预分频器值很重要。 IE。如果我假设 128 MHz 而不是 64 MHz,我会得到 1 Hz LED 闪烁器:

/*!*****************************************************************************
 * \file main.cpp
 * \brief
 * This program implements a very basic application that makes a LED blink with
 * 1 Hz.
 */

#include <stdlib.h>

#include <stm32h755xx.h>

/*!
 * \brief Configures pin PB14 ("LD3/Red LED") as digital output.
 */
static void Config_Red_Led(void) {
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOBEN;
  GPIOB->MODER &= ~(0x3u << (2 * 14));
  GPIOB->MODER |= (0x1u << (2 * 14));
  GPIOB->OTYPER &= ~(0x1u << 14);
  GPIOB->ODR = ~(0x1u << 14);
}

/*!
 * \brief Configures TIM6 overflow with 10 us period.
 */
static void Config_10us_Blink_Timer(void) {
  //Enable the TIM6 clock.
  RCC->APB1LENR |= RCC_APB1LENR_TIM6EN;

  //Enable TIM6 interrupts.
  NVIC_EnableIRQ(TIM6_DAC_IRQn);

  //Make sure the timer's "counter" is off.
  TIM6->CR1 &= ~TIM_CR1_CEN;

  //Reset the peripheral.
  RCC->APB1lrsTR |= (RCC_APB1lrsTR_TIM6RST);
  RCC->APB1lrsTR &= ~(RCC_APB1lrsTR_TIM6RST);

  //Set the timer prescaler/autoreload timing registers.
  TIM6->PSC = 128000000 / 1000000;
  TIM6->ARR = 10 - 1;

  //Send an update event to reset the timer and apply settings.
  TIM6->EGR |= TIM_EGR_UG;
}

/*!
 * \brief Enables the "Blink Timer",which will Now fire interrupts that trigger
 * execution of the "App Loop" (--> \c TIM6_DAC_IRQHandler()).
 */
static void Run_App(void) {
  //Clear TIM6_IRQn update interrupt,TIM6->SR &= ~TIM_SR_UIF;

  //Enable the hardware interrupt.
  TIM6->DIER |= TIM_DIER_UIE;

  //Enable the timer.
  TIM6->CR1 |= TIM_CR1_CEN;
}

/*!
 * \brief Initializes any peripheral being used.
 */
static void Init(void) {
  //disable cpu to respond to any configurable interrupt.
  __disable_irq();

  Config_Red_Led();
  Config_10us_Blink_Timer();

  //Enable cpu to respond to any configurable interrupt.
  __enable_irq();
}

/*!
 * \brief Initializes the system and runs the application.
 */
int main(void) {
  Init();

  Run_App();

  while(true);

  return EXIT_SUCCESS;
}

/*!
 * \brief This IRQ handler will be triggered every 10 us by the "Blink Timer".
 * This "time base" is used to blink a LED with a defined pattern.
 */
extern "C" void TIM6_DAC_IRQHandler(void) {
  //Blink the LED with a PWM signal of 1 Hz period and 50% DS.
  {
    static auto s = 0;
    if(++s >= 50000) {
      //Toggle PB14,which is the LED ("LD3/Red LED").
      GPIOB->ODR ^= (1 << 14);
      s = 0;
    }
  }

  //Clear TIM6 update interrupt flag.
  TIM6->SR &= ~TIM_SR_UIF;

  //Power-down until next "tick"/interrupt.
  //__WFE();
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?