Arduino 学习

Arduino 背景可以参考官方网站 www.arduino.cc

 

先看一个最简单的示例程序:

打开 Arduino IDE , 选择菜单:文件 -> 示例 -> 01.Basics -> Blink

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

  

程序主体很简单,提供了 setup() 和 loop() 二个函数。

setup 函数做一些初始化的工作,在系统上电或复位后,此函数只会执行一次。

loop 函数会在 setup 之后一直循环运行。

 

在了解功能之后,我们可能对背后的机制很感兴趣,那么我们可以到安装目录下打开代码文件:C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\main.cpp  代码如下:

 

#include <Arduino.h>

int main(void)
{
	init();

#if defined(USBCON)
	USBDevice.attach();
#endif
	
	setup();
    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
        
	return 0;
}

 

相信您看到了这段代码,就该知道 setup 和 loop 函数的前世今生了吧。在 loop 函数运行之后,我们还会看到 serialEventRun 的函数,此函数的功能是当串口有数据过来的时候,它可以调用Arduino的另一个函数 serialEvent。

打开 Arduino IDE , 选择菜单:文件 -> 示例 -> 04.Communication -> SerialEvent 具体看下面的代码:

 

 

/*
  Serial Event example
 
 When new serial data arrives, this sketch adds it to a String.
 When a newline is received, the loop prints the string and 
 clears it.
 
 A good test for this is to try it with a GPS receiver 
 that sends out NMEA 0183 sentences. 
 
 Created 9 May 2011
 by Tom Igoe
 
 This example code is in the public domain.
 
 http://www.arduino.cc/en/Tutorial/SerialEvent
 
 */

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {
    Serial.println(inputString); 
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read(); 
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    } 
  }
}

 

此代码的功能是:系统上电后,接收串口的输入数据并发送回去,类似 echo。系统的实现是通过在主循环判断全局变量 stringComplete 的状态来决定是否发送接收到的数据。而 stringComplete 的状态是在 serialEvent 这个函数里赋值的。根据 serialEvent 函数注释看,此函数的调用是在每次 loop 函数运行之后才执行的。再回到我们之前的代码:

for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}

通过上面的代码,可以很明确的看出 serialEventRun 函数是在 loop 函数之后执行的。如果我们有多个串口,比如 2560 的板子提供了4个串口,那么 serialEventRun 函数又是如何处理的呢,我们打开代码文件:C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp 找到 serialEventRun 函数的实现,代码如下:

 

void serialEventRun(void)
{
#ifdef serialEvent_implemented
  if (Serial.available()) serialEvent();
#endif
#ifdef serialEvent1_implemented
  if (Serial1.available()) serialEvent1();
#endif
#ifdef serialEvent2_implemented
  if (Serial2.available()) serialEvent2();
#endif
#ifdef serialEvent3_implemented
  if (Serial3.available()) serialEvent3();
#endif
}

 

serialEventRun 的函数体中是依次的调用 serialEvent() serialEvent1() serialEvent2() serialEvent3() 函数的。如果您的应用需要通过多个串口读写数据,那么在使用 serialEvent 函数的过程中,就要考虑接受的数据长度以及函数的处理时间,否则极有可能会导致其它串口的接收缓冲区满而影响应用。

 

**** 看门狗 (测试卡死了 bootloader) 请谨慎操作 ****

最新的 Arduino 1.5.6-r2 烧写的bootloader 已经支持看门狗了。

重新烧写mega2560的bootloader 烧写完之后 用usb直接编译下载 已经可以支持avr的这个wdt.h了,不用再像之前那样非得用ISP下载程序了。

使用代码如下:

 

/*------ avr看门狗测试 -----*/
 
#include <avr/wdt.h> 
void setup()
{
   pinMode(13,OUTPUT);
   wdt_enable(WDTO_4S); //开启看门狗,并设置溢出时间为4秒
   digitalWrite(13,HIGH);
   delay(100);
   digitalWrite(13,LOW);
   delay(100);
   digitalWrite(13,HIGH);
   delay(100);
   digitalWrite(13,LOW);
   delay(100);
}
 
void loop()
{
   digitalWrite(13,HIGH);
   delay(600);
   digitalWrite(13,LOW);
   delay(600);
   //wdt_reset(); //喂狗操作,使看门狗定时器复位
}

溢出时间如下:

序号
常量
定义
1
WDTO_15MS
看门狗定时器15ms超时
2
WDTO_30MS
看门狗定时器30ms超时
3
WDTO_60MS
看门狗定时器60ms超时
4
WDTO_120MS
看门狗定时器120ms超时
5
WDTO_250MS
看门狗定时器250ms超时
6
WDTO_500MS
看门狗定时器500ms超时
7
WDTO_1S
看门狗定时器1S超时
8
WDTO_2S
看门狗定时器2S超时
9
WDTO_4S
看门狗定时器4S超时
10
WDTO_8S
看门狗定时器8S超时

  

 

 

Arduino Ethernet Shield MEGA hack

http://mcukits.com/2009/04/06/arduino-ethernet-shield-mega-hack/

 

or

pinMode(11,INPUT);
pinMode(12,INPUT);
pinMode(13,INPUT);

 

posted @ 2014-02-25 11:31  Old  阅读(6708)  评论(1编辑  收藏  举报