以下函数产生17KHz以下的可调频率方波,可供驱动电机。并将电机的转速显示在OLED屏幕上。
这里利用TimerOne定时器进行多任务操作的方法借鉴这篇文章:
利用Adafruit_SSD1306库做0.96寸OLED屏幕显示的代码很多,这里就不列出了。
实际上,这个代码在跑起来有3个问题:
1.变量Interval降低到30就不能再降低了,所以产生的方波频率最高只能在17KHz左右
2.由于使用的Interval变量不能定义为const,所以输出的方波实际上会有一点抖动,在0.05KHz左右
3.由于choose和toggle函数公用一个定时器Timer1,所以当Interval较小时,choose访问引脚频率会更高。总结起来就是:Interval调低时,会越调越快。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <TimerOne.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET 13 // 重置引脚
#define SCREEN_ADDRESS 0x3C // OLED 显示屏的地址,固化在芯片上
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // 创建实例
bool ca=0;//ca=change,ca=1,表示按键按下;ca=0,表示无事发生,同时禁用lh标志位
bool lh=1;//lh=Lower or Higher,lh=1,表示间隔时间加长;lh=0,表示间隔时间减少
//定义两个标志位
unsigned long interval = 200;
const int intA=1;
const int intB=100;
static word gy=0;
void setup()
{
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.clearDisplay(); // 清屏
delay(100); // 延时 1s
display.setTextColor(WHITE); // 设置字体颜色为白色
display.display(); // 显示
pinMode(13, OUTPUT); // Pin 13 has an LED
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
Timer1.initialize( interval ); // 初始化, interval 以 micro sec 为单位
Timer1.attachInterrupt(choose); // attach the service routine here
Serial.begin(9600);
}
void loop()
{
if(ca==1)//因为用错了关系运算符,浪费了至少20分钟
{
if(lh==1) {interval+=10;}
else
{
if(interval<=30){return;}
interval-=10;
}
}
ca=0;
Timer1.initialize( interval );
Display();
Serial.println(interval);
}
void choose( )//用于翻转LED显示
{
++gy; // 注意: 这 gy 是全局变量(Global variable)
if( gy % intA == 0) Toggle( ); // gy 除以 intA 的余数是 0
if( gy % intB == 0) PinRead( );
}
void Display()
{
display.setTextSize(2); // 设置字体大小
display.setCursor(0,0); // 设置显示起始位置,根据屏幕大小自己计算
display.print("1 Cir Need"); // 输出 Hello 字样
display.setCursor(0,16);
display.print(0.01*interval);
display.setCursor(0,32); // 设置显示起始位置,根据屏幕大小自己计算
display.print("Second");
display.display(); // 显示
display.clearDisplay(); // 刷新
}
void Toggle()
{
digitalWrite(13,digitalRead(13)^1);
}
void PinRead()
{
if(!digitalRead(2)){ca=1;lh=1;}
if(!digitalRead(3)){ca=1;lh=0;}
}
初学者,还请多多指教。