STM32F103C8T6基于Arduino框架下利用定时器跑RBG灯闪烁

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F103C8T6基于Arduino框架下利用定时器跑RBG灯闪烁相关的知识,希望对你有一定的参考价值。

STM32F103C8T6基于Arduino框架下利用定时器跑RGB灯闪烁


  • 🌼演示效果

✨在程序示例测试当中发现好多库对STM32系列支持的不够全面,其中原因有STM32固件本身就有缺陷和bug,导致好多库都只能在部分型号中实现。另外测试STM32F1_RTC库,也是只能在C8T6上面跑。

  • ⚡测试了STM32F103VET6STM32G070RBT6都不能跑起来,编译和烧录都没有问题,就是运行不起来,应该是固件中的定时器相关配置不正确导致的,像之前发现的STM32F103VET6串口乱码问题就是固件中的时钟配置不对导致串口打印乱码,使用STM32F103C8T6板子并烧录后可以正常按照代码运行。

🎉个人学习还是推荐使用STM32F103C8T6最小系统板。就目前固件版本来看,此款型号的bug少一些。不然需要花费好多时间在找bug的过程中。有些问题不是不能解决,只是所花费的时间比较多。如果想促进固件的完善,则就需要不断的有人去探索,对于有经验的人可以尝试这么做,对于新手那就算了,使用遵循拿来即用的原则,怎么简单怎么来。如果在其他平台开发那就不一样了。

  • 🔖如果想在STM32F103VET6上运行,定时器任务数只能跑2个,跑3个或以上需要将开发板型号切换到VCCGND_F103ZET6烧录才能运行。

所需库

  • STM32_TimerInterrupt:版本: 1.3.0

✅可在IDE管理库当中搜索并下载到。

📚示例代码

📝效果的类似Ticker库,这里只是做功能演示,当然可以利用此库去实现自己功能代码。这个比跑FreeRTOS任务简单多了。

/****************************************************************************************************************************
  TimerInterruptLEDDemo.ino
  For STM32 boards
  Written by Khoi Hoang
  
  Built by Khoi Hoang https://github.com/khoih-prog/STM32_TimerInterrupt
  Licensed under MIT license
  
  Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
  unsigned long miliseconds), you just consume only one STM32 timer and avoid conflicting with other cores' tasks.
  The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
  Therefore, their executions are not blocked by bad-behaving functions / tasks.
  This important feature is absolutely necessary for mission-critical tasks.
*****************************************************************************************************************************/

/*
   Notes:
   Special design is necessary to share data between interrupt code and the rest of your program.
   Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
   variable can not spontaneously change. Because your function may change variables while your program is using them,
   the compiler needs this hint. But volatile alone is often not enough.
   When accessing shared variables, usually interrupts must be disabled. Even with volatile,
   if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
   If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
   or the entire sequence of your code which accesses the data.
*/

#if !( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3)  ||defined(STM32F4) || defined(STM32F7) || \\
       defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7)  ||defined(STM32G0) || defined(STM32G4) || \\
       defined(STM32WB) || defined(STM32MP1) || defined(STM32L5) )
  #error This code is designed to run on STM32F/L/H/G/WB/MP1 platform! Please check your Tools->Board setting.
#endif

// These define's must be placed at the beginning before #include "STM32TimerInterrupt.h"
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
// Don't define TIMER_INTERRUPT_DEBUG > 2. Only for special ISR debugging only. Can hang the system.
#define TIMER_INTERRUPT_DEBUG         0
#define _TIMERINTERRUPT_LOGLEVEL_     0

#include "STM32TimerInterrupt.h"

#ifndef LED_BUILTIN
  #define LED_BUILTIN       PA4               // Pin 33/PB0 control on-board LED_GREEN on F767ZI
#endif

#ifndef LED_BLUE
  #define LED_BLUE          PA2               // Pin 73/PB7 control on-board LED_BLUE on F767ZI
#endif

#ifndef LED_RED
  #define LED_RED           PA1              // Pin 74/PB14 control on-board LED_BLUE on F767ZI
#endif
   
#include "STM32TimerInterrupt.h"
#include "STM32_ISR_Timer.h"

#define TIMER_INTERVAL_MS         100
#define HW_TIMER_INTERVAL_MS      50

// Depending on the board, you can select STM32 Hardware Timer from TIM1-TIM22
// For example, F767ZI can select Timer from TIM1-TIM14
// If you select a Timer not correctly, you'll get a message from ci[ompiler
// 'TIMxx' was not declared in this scope; did you mean 'TIMyy'? 

// Init STM32 timer TIM1
STM32Timer ITimer(TIM1);

// Init STM32_ISR_Timer
// Each STM32_ISR_Timer can service 16 different ISR-based timers
STM32_ISR_Timer ISR_Timer;

#define TIMER_INTERVAL_0_5S           500L
#define TIMER_INTERVAL_1S             1000L
#define TIMER_INTERVAL_1_5S           1500L

void TimerHandler()

  ISR_Timer.run();


// In STM32, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething1()

  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));


void doingSomething2()

  digitalWrite(LED_BLUE, !digitalRead(LED_BLUE));

void doingSomething3()

  digitalWrite(LED_RED, !digitalRead(LED_RED));


void setup()

   Serial.setRx(PA10); 
  Serial.setTx(PA9);
  Serial.begin(115200);
  
  while (!Serial);

  delay(100);

  Serial.print(F("\\nStarting TimerInterruptLEDDemo on ")); Serial.println(BOARD_NAME);
  Serial.println(STM32_TIMER_INTERRUPT_VERSION);
  Serial.print(F("CPU Frequency = ")); Serial.print(F_CPU / 1000000); Serial.println(F(" MHz"));

  // Instantiate HardwareTimer object. Thanks to 'new' instanciation, HardwareTimer is not destructed when setup() function is finished.
  //HardwareTimer *MyTim = new HardwareTimer(Instance);

  // configure pin in output mode
  pinMode(LED_BUILTIN,  OUTPUT);
  pinMode(LED_BLUE,     OUTPUT);
  pinMode(LED_RED,      OUTPUT);

  // Interval in microsecs
  if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
  
    Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(millis());
  
  else
    Serial.println(F("Can't set ITimer. Select another freq. or timer"));

  // Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
  // You can use up to 16 timer for each ISR_Timer
  ISR_Timer.setInterval(TIMER_INTERVAL_0_5S,  doingSomething1);
  ISR_Timer.setInterval(TIMER_INTERVAL_1S,    doingSomething2);
  ISR_Timer.setInterval(TIMER_INTERVAL_1_5S,  doingSomething3);



void loop()

  /* Nothing to do all is done by hardware. Even no interrupt required. */

  • 串口打印

以上是关于STM32F103C8T6基于Arduino框架下利用定时器跑RBG灯闪烁的主要内容,如果未能解决你的问题,请参考以下文章

STM32F103C8T6在Arduino框架下驱动ssd1306 0.96“ IIC OLED显示

stm32f103c8t6引脚功能图以及在arduino IDE编程环境下引脚调用

Arduino STM32F103C8T6 驱动ssd1306 I2C oled

STM32F103C8T6 + 0.96“ I2C OLED显示3D_Cube

STM32学习笔记 二基于STM32F103C8T6和STM32CubeMX实现UART串口通信数据收发

STM32学习笔记 二基于STM32F103C8T6和STM32CubeMX实现UART串口通信数据收发