前言
答应了群主写一些示例程序,一直拖延拖延拖延唉。主要还是害怕在各大高手面前班门弄斧……(这也算是给拖延症找一个美好的理由吧),这几天终于下决心要写出来了,各位高手拍砖敬请轻拍啊。
示例程序
首先是闪灯程序
示例自带的闪灯就略过了,这里写个不大一样的,使用 millis() 来进行时间间隔的判断,与示例使用 delay() 的方式比较,这种方式不会阻塞主进程,以后很多地方会用得上的:
// ---------------------------------------------------------------------------- // millisBlink.ino // // Created 2015-05-28 // By seesea <seesea2517#gmail#com> // // 使用millis()来判断时间间隔进行的闪灯程序 // // 使用板上 LED // ---------------------------------------------------------------------------- const unsigned char led = 13; const unsigned long switchMs = 1000; // 亮灭的切换延时时间 unsigned long lastMs = millis(); bool light = false; void setup() { pinMode(led, OUTPUT); } void loop() { // 如果不到切换时间,则跳出函数,不阻塞主程序 if (millis() - lastMs < switchMs) return; lastMs = millis(); light = !light; digitalWrite(led, light); }
其次,还是闪灯程序
这里使用时钟中断来实现。
// ---------------------------------------------------------------------------- // intBlink.ino // // Created 2015-05-28 // By seesea <seesea2517#gmail#com> // // 使用时钟中断来实现的闪烁灯 // // 使用板上 LED // ---------------------------------------------------------------------------- const int led = 13; const unsigned long T1InitCount = 65536 - F_CPU / 256 / 2; // 2Hz闪烁,TCNT 初始值, 256 预分频 void setup() { pinMode(led, OUTPUT); noInterrupts(); TCCR1A = 0; TCCR1B = 0; TCNT1 = T1InitCount; TCCR1B |= (1 << CS12); // 256 预分频 TIMSK1 |= (1 << TOIE1); // T1 溢出中断允许 interrupts(); } // 中断函数 ISR(TIMER1_OVF_vect) { TCNT1 = T1InitCount; // 重装初值。如果使用比较中断,则不需要重装初值了 digitalWrite(led, ! digitalRead(led)); } void loop() { // loop 函数里啥也不需要,可以做爱做的事情哟 }
接下来要加上一个按钮啦
// ---------------------------------------------------------------------------- // keyLED.ino // // Created 2015-05-29 // By seesea <seesea2517#gmail#com> // // 按钮按下灯亮,松开灯灭的实验 // // 使用板上 LED,按钮引脚接 8 脚及 GND,pin 8 使用内部上拉 // ---------------------------------------------------------------------------- const unsigned char led = 13; const unsigned char key = 8; void setup() { pinMode(led, OUTPUT); pinMode(key, INPUT_PULLUP); } void loop() { digitalWrite(led, ! digitalRead(key)); }
下面还是按钮,使用外部中断来实现
// ---------------------------------------------------------------------------- // keyIntLED.ino // // Created 2015-05-29 // By seesea <seesea2517#gmail#com> // // 使用外部中断来实现的按钮按下灯亮,松开灯灭的实验 // 注:0 号中断固定为 pin 2 // // 使用板上 LED,按钮引脚接 2 脚及 GND,pin 2 使用内部上拉 // ---------------------------------------------------------------------------- const unsigned char led = 13; const unsigned char key = 2; void setup() { pinMode(led, OUTPUT); pinMode(key,INPUT_PULLUP); attachInterrupt(0, lightLED, LOW); // 使用低电平中断 } // 中断函数 void lightLED() { // 中断函数优先于普通函数,低电平会不断中断,从而只执行灯亮的操作 digitalWrite(led, HIGH); } void loop() { // 中断函数优先于普通函数,低电平会不断中断,从而只执行灯亮的操作 // 待中断结束后,执行这里灯灭操作 digitalWrite(led, LOW); }
接着还要做按钮实验,这个实验演示了软件消抖
如果不消抖的话,会有非预期的效果出现哦
// ---------------------------------------------------------------------------- // keyIntLED.ino // // Created 2015-05-29 // By seesea <seesea2517#gmail#com> // // 使用外部中断来实现的按钮按下灯亮,松开灯灭的实验 // 注:0 号中断固定为 pin 2 // // 使用板上 LED,按钮引脚接 2 脚及 GND,pin 2 使用内部上拉 // ---------------------------------------------------------------------------- const unsigned char led = 13; const unsigned char key = 2; void setup() { pinMode(led, OUTPUT); pinMode(key,INPUT_PULLUP); attachInterrupt(0, lightLED, LOW); // 使用低电平中断 } // 中断函数 void lightLED() { // 中断函数优先于普通函数,低电平会不断中断,从而只执行灯亮的操作 digitalWrite(led, HIGH); } void loop() { // 中断函数优先于普通函数,低电平会不断中断,从而只执行灯亮的操作 // 待中断结束后,执行这里灯灭操作 digitalWrite(led, LOW); }
现在不玩按钮了,要实验 PWM
// ---------------------------------------------------------------------------- // pwmLED.ino // // Created 2015-05-31 // By seesea <seesea2517#gmail#com> // // 外部模拟设备控制灯亮度的实验 // // 使用板上 LED,pin 13 没有 pwm 功能,所以用接线把 pin 11 接到 pin 13 进行实验 // 外部模拟器件可使用电位器,两端接 VCC 及 GND,中间接 A0 模拟引脚 // 外部模拟器件或者使用光敏电阻与普通电阻串联,两端接 VCC 及 GND,中间接 A0 模拟引脚 // ---------------------------------------------------------------------------- const unsigned char led = 11; const unsigned char sensor = A0; void setup() { pinMode(led, OUTPUT); pinMode(sensor, INPUT); } void loop() { // 用 map 函数进行范围的映射 analogWrite(led, map(analogRead(sensor), 0, 1023, 0, 255)); }
下面有图有真相,使用电位器来控制灯的亮度,或者用模拟传感器来控制——比如光敏电阻:
|
|
呼吸灯
PWM 会了,大名鼎鼎的呼吸灯不能少
// ---------------------------------------------------------------------------- // breathingLED.ino // // Created 2015-05-29 // By seesea <seesea2517#gmail#com> // // 呼吸灯程序 // // 使用时将 pin 11 用线接到 pin 13 上可以使用板子上的 LED 来实验 // ---------------------------------------------------------------------------- const unsigned char led = 11; void setup() { pinMode(led, OUTPUT); // pinMode(13, INPUT); 如果遇到灯亮度不够的情况,可以试试把这句话加上 } void loop() { static unsigned char pwm = 0; static char delta = 1; if (pwm == 255) { // 最亮的时候改变变化方向为变暗 delta = -1; } else if (pwm == 0) { // 最暗的时候改变变化方向为变亮 delta = 1; } pwm += delta; analogWrite(led, pwm); delay(10); }
简单上个接线图:
数字口实现的呼吸灯
还是呼吸灯,这次使用数字口来实现,以后有遇到 PWM 口不够的时候,就可以用这种模拟的方法了
// ---------------------------------------------------------------------------- // digitalbreathingLED.ino // // Created 2015-05-29 // By seesea <seesea2517#gmail#com> // // 直接使用 pin 13 数字引脚来实现呼吸灯 // ---------------------------------------------------------------------------- const unsigned char led = 13; const unsigned char maxPwm = 100; void setup() { pinMode(13, OUTPUT); } void loop() { static unsigned char pwm = 0; static char delta = 1; if (pwm == 0) { // 最亮的时候改变变化方向为变暗 delta = 1; } else if (pwm == 100) { // 最暗的时候改变变化方向为变亮 delta = -1; } pwm += delta; // 先亮灯,等占空比到切换点的时候灭灯 digitalWrite(led, HIGH); for (unsigned char i = 0; i < maxPwm; ++i) { if (i == pwm) digitalWrite(led, LOW); delayMicroseconds(100); } }
这个也有图,可以看看没有接线的图 :D
时间: 2024-10-25 11:28:37