arduino1
2015-05-30 10:04:35 kevin3052974065 阅读数 1828
int redPin = 9;
int greenPin = 10;
int yellowPin = 8;
char ab;
void setup() {
        Serial.begin(9600);
        pinMode(redPin, OUTPUT);
        pinMode(greenPin, OUTPUT);
        pinMode(yellowPin, OUTPUT);
}
void loop() {
  if (Serial.available()>0)
  {
  ab=Serial.read();
  Serial.println(ab);
  if (ab=='r'||ab=='R'){
    redOne();
  }
  else if (ab=='g'||ab=='G'){
    greenOne();
  }
  else if (ab=='y'||ab=='Y'){
     yellowOne(); 
  }
  else  { Serial.println("input error!");
  }
  }
}


void redOne(){
  digitalWrite(redPin,HIGH);
  delay(10000);
   digitalWrite(redPin,LOW);
}
void greenOne(){
  digitalWrite(greenPin,HIGH);
  delay(10000);
   digitalWrite(greenPin,LOW);
}
void yellowOne(){
  digitalWrite(yellowPin,HIGH);
  delay(10000);
   digitalWrite(yellowPin,LOW);
}
2019-03-20 20:53:45 qq_36955622 阅读数 2317

涉及电子专业或行业的人都多少听说过Arduino这个词汇,那么…

何为Arduino?!

Arduino是一款便捷灵活、方便上手的的开源电子原型平台,Arduino平台由硬件(各种型号的Arduino控制板)和Arduino集成开发环境(Arduino IDE)组成,可以理解Arduino为Arduino软硬件平台的统称。
Arduino适用于开发设计师,编程艺术家,业余爱好者和对互动式式开发有兴趣的小伙伴们,它能通过外接各种各样的传感器来“感知”环境,并通过控制灯光、电动机和其他的装置来反馈、影响环境。

Arduino控制板的型号很多,下面一起学习几个比较典型的开发板:

Arduino UNO

目前使用做多的Arduino控制板是Arduino UNO,作为Arduino平台的参考标准模板。Arduino UNO的最新版本是UNO R3,其处理器核心是ATmega328,同时具有14路数字输入/输出口(其中6路可作为PWM输出)、6路模拟输入、一个16MHz晶体振荡器、一个USB接口、一个电源插座、一个ICSP header和一个复位按钮。
在这里插入图片描述
其主要参数配置如下:

  • MCU(处理器):ATmega328
  • 工作电压:5V
  • 输入电压(推荐):7 ~ 12V
  • 输入电压(范围):6 ~ 20V
  • 数字输入/输出引脚:14路,分别为0 ~ 13(其中3、5、6、9、10、11路引脚可作为模拟输出(PWM方式))
  • 模拟输入引脚:6路,分别为A0 ~ A5(这6路 引脚也能作数字输入/输出引脚用)
  • 数字输入/输出引脚最大输出电流:40mA
  • 3.3V电源输出接口最大输出电流:50mA
  • Flash Memory(内存):32KB
  • SRAM:2KB
  • EEPROM:1KB
  • 工作时钟:16MHz

UNO R3与前两版相比在AREF处增加了两个管脚SDA和SCL,支持I2C接口;增加IOREF和一个预留管脚,将来扩展板将能兼容5V和3.3V核心板;改进了复位电路设计,USB接口芯片由ATmega16U2替代了ATmega8U2。
Arduino UNO的电源供应方式有3种:
1)通过USB连线供电,供电电压为5V;
2)通过电源输入插座或电路板上的Vin输入端供电,供电电压为7V ~ 12V,经电路板稳压后提供5V工作电压;
3)通过电路板上的5V输出端供电,供电电压为5V;

Arduino UNO控制板有2个直流电源输出端,分别为5V和3.3V,用于对外接设备供电,其中5V输出端能提供的最大电流为300mA,3.3V输出端能提供的最大电流为50mA。

Arduino Mega 2560

Arduino Mega 2560是采用USB接口的核心电路板,处理器核心是ATmega 2560,同时具有54路数字输入/输出引脚(其中15路可作为PWM输出),适合需要大量I/O接口的设计,16路模拟输入,4路UART接口,一个16MHz晶体振荡器,一个USB接口,一个电源插座,一个ICSP header和一个复位按钮,Arduino Mega 2560也能兼容为Arduino UNO设计的扩展板。
在这里插入图片描述
其主要参数配置如下:

  • 处理器:Mega2560
  • 工作电压:5V
  • 输入电压(推荐):7 ~ 12V
  • 数字输入/输出口:54路(其中15路支持PWM)
  • 模拟输入/输出口:16路
  • 每个输入/输出口的输出电流:40mA
  • 3.3V电源输出接口的输出电流:50mA
  • Flash Memory(内存):256KB
  • SRAM:8KB
  • EEPROM:4KB
  • 工作时钟:16MHz
Arduino Nano

Arduino Nano是Arduino USB接口的微型版本,最大的不同是没有电源插座且USB接口是Mini-B型插座。Arduino Nano的尺寸极小,而且可以插再面包板上使用,其处理器核心是Atmega168 (Nano2.x) 和Atmega328(Nano3.0),同时具有14路数字输入/输出口(其中6路可作为PWM输出)、8路模拟输入、一个16MHz晶体振荡器、一个Mini-B USB接口、一个ICSP header和一个复位按钮。
在这里插入图片描述
其主要参数配置如下:

  • 处理器:ATmega168 或 ATmega328
  • 工作电压:5V
  • 输入电压(推荐):7 ~ 12V
  • 输入电压(范围):6 ~ 20V
  • 数字输入/输出口:14路(其中6路可作为PWM输出)
  • 模拟输入引脚:6路
  • 输入/输出引脚的输出电流:40mA
  • Flash Memory(内存):16KB或32KB
  • SRAM:1KB或者2KB
  • EEPROM:0.5KB或者1KB(ATmega328)
  • FT232RL FTDI USB接口芯片
  • 工作时钟:16MHz
Arduino Leonardo

Arduino Leonardo是基于ATmega32U4的一个微控制板,它有20个数字输入/输出引脚(其中7个可用于PWM输出、12个可用于模拟输入)、一个16MHz的晶体振荡器、一个Micro USB接口、一个DC接口、一个ICSP接口以及一个复位按钮。它包含了支持微控制器所需的一切,可以简单地通过连接到计算机的USB接口,或者使用AC-DC是适配器,或者用电池来驱动它。
Leonardo不同于之前所有的Arduino控制器,它直接使用了ATmega32U4的USB通信功能,取消了USB转UART芯片。这使得Leonardo不仅可以作为一个虚拟的(CDC)串行/COM端口,还可以作为鼠标或者键盘连接到计算机。
在这里插入图片描述
其主要参数配置如下:

  • 微控制器:ATmega32U4
  • 工作电压:5V
  • 输入电压(推荐):7 ~ 12V
  • 输入电压(范围):6 ~ 20V
  • 数字输入/输出口:20路
  • PWM通道:7个
  • 模拟输入引脚:12个
  • 每个输入/输出引脚输出电流:40mA
  • 3.3V端口输出电流:50mA
  • Flash:32KB(ATmega32U4)
  • SRAM:2.5KB(ATmega32U4)
  • EEPROM:1KB(ATmega32U4)
  • 工作时钟:16MHz

不管是体积小型化的Arduino Nano和Arduino Mini,或者提及大型化且性能更强大的Arduino Mega 2560,它们均兼容Arduino UNO的程序,因此程序功能介绍就以Arduino UNO板为例介绍,请知悉。

2016-12-18 22:29:34 ydogg 阅读数 3422

这里写图片描述

左侧自上而下:
arduino tiny85
arduino pro mini
arduino pro micro
arduino nano
arduino lily pad

右侧自上而下:
nodeMCU(esp8266)
arduino UNO
arduino Mega2560

焊完引脚后的:
这里写图片描述

2018-07-04 14:37:07 TonyIOT 阅读数 8360

欢迎来到Arduino的世界,本文主要介绍Arduino的优势,开发所涉及的硬件分类,开发语言及开发环境的下载。可登陆Arduino官网学习了解更多Arduino信息。

什么是Arduino

Arduino 是一款便捷灵活、方便上手的开源电子原型平台,包含硬件(各种型号的arduino板)和软件(arduino IDE),她适用于艺术家、设计师、爱好者和对于“互动”有兴趣的朋友们。

Arduino能通过各种各样的传感器来感知环境,通过控制灯光、马达和其他的装置来反馈、影响环境。板子上的微控制器可以通过Arduino的编程语言来编写程序,编译成二进制文件,烧录进微控制器。

对Arduino的编程是利用 Arduino编程语言 (基于 Wiring)和Arduino开发环境(based on Processing)来实现的。基于Arduino的项目,可以只包含Arduino,也可以包含Arduino和其他一些在PC上运行的软件,他们之间进行通信 (比如 Flash, Processing, MaxMSP)来实现。

你可以自己动手制作,也可以购买成品套装。Arduino所使用到的软件都可以免费下载。硬件参考设计 (CAD 文件)也是遵循availableopen-source协议, 你可以非常自由地根据要求去修改他们。

Arduino的优势

目前市场上还有许多其他的单片机和单片机平台,例如51单片机、STM32单片机等。但他们对于普通开发者来说门槛相对较高,需要有一定编程和硬件相关基础,内部寄存器较为繁杂,主流开发环境Keil配置相对麻烦,特别是对于STM32的开发,即使使用官方库也少不了环境配置,还有就是开发环境是收费的。

Arduino不但简化了使用单片机工作的流程,同时还为教师、学生以及兴趣爱好者提供了一些其他系统不具备的优势:

  • 便宜。相比于其他单片机平台而言,Arduino生态的各种开发板性价比相对较高。
  • 跨平台。Arduino软件(IDE)能在Windows、Mac OS X和Linux操作系统中运行,而大多数其他单片机系统仅限于在Windows操作系统中运行。
  • 开发环境简单。Arduino的编程环境易于初学者使用,同时对高级用户来讲也足够灵活,其安装和操作都非常简单。
  • 开源可扩展。Arduino软件硬件都是开源的,开发者可以对软件库进行扩展,也可以下载到千千万万的软件库来实现自己的功能。Arduino允许开发者对硬件电路进行修改和扩展来满足不同的需求。

Arduino开发板类型

Arduino生态包括多种开发板、模块、扩展板、工具和配件。官方将其大致分为五类:入门级、网络版、物联网版、教育版、可穿戴版。具体可从官网查看Arduino开发板类型。

Arduino开发板类型

其中入门级开发板易于使用。建议初学者使用入门级如Arduino UNO R3。

在这里插入图片描述

Arduino开发语言

Arduino使用C/C++编写程序,虽然C++兼容C语言,但这是两种语言,C语言是一种面向过程的编程语言,C++是一种面向对象的编程语言。早期的Arduino核心库使用C语言编写,后来引进了面向对象的思想,目前最新的Arduino核心库采用C与C++混合编写而成。

通常我们说的Arduino语言,是指Arduino核心库文件提供的各种应用程序编程接口(Application Programming Interface,简称API)的集合。这些API是对更底层的单片机支持库进行二次封装所形成的。例如,使用AVR单片机的Arduino的核心库是对AVR-Libc(基于GCC的AVR支持库)的二次封装。

传统开发方式中,需要通过配置多个寄存器来实现相应功能,而在Arduino中,繁杂的寄存器被封装成简单的API,能进行直观控制,增强程序的可读性的同时也提高了开发效率。

Arduino开发环境

Arduino开发环境IDE可从官网进行下载,支持Windows、Mac OS X、Linux不同平台,对应PC平台进行下载。IDE下载地址
当前最新版本为1.8.5。我的电脑为Windows系统,Windows版本有三种下载方式,选择一种下载即可。

IDE下载

关于IDE软件的介绍将在下一节中详细介绍。

更多内容,欢迎关注我的公众号。 微信扫一扫下方二维码即可关注:
扫码加入微信公众号:TonyCode

2017-07-21 10:26:35 u012763833 阅读数 1500

  Arduino是一个基于开源代码的快速电子原型开发平台,其由各种型号的Arduino开发板及Arduino IDE组成(官网中文社区)。目前的Arduino开发板是基于AVR单片机系统开发,并在其基础上作了较完善的软硬件封装,目的是尽量屏蔽底层硬件的影响便于快速开发。
 
1. Arduino开发板硬件解析,基于Arduino UNO R3.
  原理图下载:点我
  实物图如下:
  

Arduino UNO R3

  
  开发板硬件主要由 USB 控制器,AVR单片机 Atmega 328P 系统,电源系统及相应的一些外围电路组成。
  1. 电源系统,开发板可采用“DC-5”或“USB接口”供电。
  2. USB控制器,从原理图可以看出其与Atmega 328P的USART串口相连,用于传输数据;端口PD7用于控制Atmega 328P的复位,已便在Arduino IDE下载程序时,使单片机复位进入Bootloader程序。
  通常的AVR单片机开发采用ISP接口下载程序,需要专门的ISP下载器。Arduino为了简化外围设备,采用USB串口下载程序。其原理是将AVR单片机系统程序分为“Bootloader”和“APP”两部分,“Bootloader”负责将USB串口接收的程序通过自编程(IAP)烧写至Flash,并在一定条件下控制程序跳转至“APP”区执行;“APP”是真正用户编写的程序。(PS: 有些单片机厂商在出厂前已将“Bootloader”固化到单片机,如 STM32 系列单片机,其可通过串口,I2C 等接口程接收用户程序,用户通过控制 BOOT 相关引脚的电平,控制程序跳转。)
  3. AVR 单片机 Atmega 328P 系统,含时钟电路、复位电路、I/O端口。
  
  待续。。。
  
2. Arduino Bootloader源码分析
  在Ardunino IDE的安装目录下,个人目录:“E:\Arduino\hardware\arduino\avr\bootloaders\atmega”。
  Bootloader主要实现功能:1. 接收外部发送来的程序;2. 将程序烧写到Flash;3. 控制程序跳转。
  
  待续。。。
 

/**********************************************************/
/* Serial Bootloader for Atmel megaAVR Controllers        */
/*                                                        */
/* tested with ATmegarduino8, ATmega128 and ATmega168  */
/* should work with other mega's, see code for details    */
/*                                                        */
/* ATmegaBOOT.c                                           */
/*                                                        */
/*                                                        */
/* 20090308: integrated Mega changes into main bootloader */
/*           source by D. Mellis                          */
/* 20080930: hacked for Arduino Mega (with the 1280       */
/*           processor, backwards compatible)             */
/*           by D. Cuartielles                            */
/* 20070626: hacked for Arduino Diecimila (which auto-    */
/*           resets when a USB connection is made to it)  */
/*           by D. Mellis                                 */
/* 20060802: hacked for Arduino by D. Cuartielles         */
/*           based on a previous hack by D. Mellis        */
/*           and D. Cuartielles                           */
/*                                                        */
/* Monitor and debug functions were added to the original */
/* code by Dr. Erik Lins, chip45.com. (See below)         */
/*                                                        */
/* Thanks to Karl Pitrich for fixing a bootloader pin     */
/* problem and more informative LED blinking!             */
/*                                                        */
/* For the latest version see:                            */
/* http://www.chip45.com/                                 */
/*                                                        */
/* ------------------------------------------------------ */
/*                                                        */
/* based on stk500boot.c                                  */
/* Copyright (c) 2003, Jason P. Kyle                      */
/* All rights reserved.                                   */
/* see avr1.org for original file and information         */
/*                                                        */
/* This program is free software; you can redistribute it */
/* and/or modify it under the terms of the GNU General    */
/* Public License as published by the Free Software       */
/* Foundation; either version 2 of the License, or        */
/* (at your option) any later version.                    */
/*                                                        */
/* This program is distributed in the hope that it will   */
/* be useful, but WITHOUT ANY WARRANTY; without even the  */
/* implied warranty of MERCHANTABILITY or FITNESS FOR A   */
/* PARTICULAR PURPOSE.  See the GNU General Public        */
/* License for more details.                              */
/*                                                        */
/* You should have received a copy of the GNU General     */
/* Public License along with this program; if not, write  */
/* to the Free Software Foundation, Inc.,                 */
/* 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */
/*                                                        */
/* Licence can be viewed at                               */
/* http://www.fsf.org/licenses/gpl.txt                    */
/*                                                        */
/* Target = Atmel AVR m128,m64,m32,m16,m8,m162,m163,m169, */
/* m8515,m8535. ATmega161 has a very small boot block so  */
/* isn't supported.                                       */
/*                                                        */
/* Tested with m168                                       */
/**********************************************************/


/* some includes */
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>

/* the current avr-libc eeprom functions do not support the ATmega168 */
/* own eeprom write/read functions are used instead */
#if !defined(__AVR_ATmega168__) || !defined(__AVR_ATmega328P__) || !defined(__AVR_ATmega328__)
#include <avr/eeprom.h>
#endif

/* Use the F_CPU defined in Makefile */

/* 20060803: hacked by DojoCorp */
/* 20070626: hacked by David A. Mellis to decrease waiting time for auto-reset */
/* set the waiting time for the bootloader */
/* get this from the Makefile instead */
/* #define MAX_TIME_COUNT (F_CPU>>4) */

/* 20070707: hacked by David A. Mellis - after this many errors give up and launch application */
#define MAX_ERROR_COUNT 5

/* set the UART baud rate */
/* 20060803: hacked by DojoCorp */
//#define BAUD_RATE   115200
#ifndef BAUD_RATE
#define BAUD_RATE   19200
#endif


/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */
/* never allow AVR Studio to do an update !!!! */
#define HW_VER   0x02
#define SW_MAJOR 0x01
#define SW_MINOR 0x10


/* Adjust to suit whatever pin your hardware uses to enter the bootloader */
/* ATmega128 has two UARTS so two pins are used to enter bootloader and select UART */
/* ATmega1280 has four UARTS, but for Arduino Mega, we will only use RXD0 to get code */
/* BL0... means UART0, BL1... means UART1 */
#ifdef __AVR_ATmega128__
#define BL_DDR  DDRF
#define BL_PORT PORTF
#define BL_PIN  PINF
#define BL0     PINF7
#define BL1     PINF6
#elif defined __AVR_ATmega1280__ 
/* we just don't do anything for the MEGA and enter bootloader on reset anyway*/
#else
/* other ATmegas have only one UART, so only one pin is defined to enter bootloader */
#define BL_DDR  DDRD
#define BL_PORT PORTD
#define BL_PIN  PIND
#define BL      PIND6
#endif


/* onboard LED is used to indicate, that the bootloader was entered (3x flashing) */
/* if monitor functions are included, LED goes on after monitor was entered */
#if defined __AVR_ATmega128__ || defined __AVR_ATmega1280__
/* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128, Arduino Mega) */
#define LED_DDR  DDRB
#define LED_PORT PORTB
#define LED_PIN  PINB
#define LED      PINB7
#else
/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duomilanuove */ 
/* other boards like e.g. Crumb8, Crumb168 are using PB2 */
#define LED_DDR  DDRB
#define LED_PORT PORTB
#define LED_PIN  PINB
#define LED      PINB5
#endif


/* monitor functions will only be compiled when using ATmega128, due to bootblock size constraints */
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
#define MONITOR 1
#endif


/* define various device id's */
/* manufacturer byte is always the same */
#define SIG1    0x1E    // Yep, Atmel is the only manufacturer of AVR micros.  Single source :(

#if defined __AVR_ATmega1280__
#define SIG2    0x97
#define SIG3    0x03
#define PAGE_SIZE   0x80U   //128 words

#elif defined __AVR_ATmega1281__
#define SIG2    0x97
#define SIG3    0x04
#define PAGE_SIZE   0x80U   //128 words

#elif defined __AVR_ATmega128__
#define SIG2    0x97
#define SIG3    0x02
#define PAGE_SIZE   0x80U   //128 words

#elif defined __AVR_ATmega64__
#define SIG2    0x96
#define SIG3    0x02
#define PAGE_SIZE   0x80U   //128 words

#elif defined __AVR_ATmega32__
#define SIG2    0x95
#define SIG3    0x02
#define PAGE_SIZE   0x40U   //64 words

#elif defined __AVR_ATmega16__
#define SIG2    0x94
#define SIG3    0x03
#define PAGE_SIZE   0x40U   //64 words

#elif defined __AVR_ATmega8__
#define SIG2    0x93
#define SIG3    0x07
#define PAGE_SIZE   0x20U   //32 words

#elif defined __AVR_ATmega88__
#define SIG2    0x93
#define SIG3    0x0a
#define PAGE_SIZE   0x20U   //32 words

#elif defined __AVR_ATmega168__
#define SIG2    0x94
#define SIG3    0x06
#define PAGE_SIZE   0x40U   //64 words

#elif defined __AVR_ATmega328P__
#define SIG2    0x95
#define SIG3    0x0F
#define PAGE_SIZE   0x40U   //64 words

#elif defined __AVR_ATmega328__
#define SIG2    0x95
#define SIG3    0x14
#define PAGE_SIZE   0x40U   //64 words

#elif defined __AVR_ATmega162__
#define SIG2    0x94
#define SIG3    0x04
#define PAGE_SIZE   0x40U   //64 words

#elif defined __AVR_ATmega163__
#define SIG2    0x94
#define SIG3    0x02
#define PAGE_SIZE   0x40U   //64 words

#elif defined __AVR_ATmega169__
#define SIG2    0x94
#define SIG3    0x05
#define PAGE_SIZE   0x40U   //64 words

#elif defined __AVR_ATmega8515__
#define SIG2    0x93
#define SIG3    0x06
#define PAGE_SIZE   0x20U   //32 words

#elif defined __AVR_ATmega8535__
#define SIG2    0x93
#define SIG3    0x08
#define PAGE_SIZE   0x20U   //32 words
#endif


/* function prototypes */
void putch(char);
char getch(void);
void getNch(uint8_t);
void byte_response(uint8_t);
void nothing_response(void);
char gethex(void);
void puthex(char);
void flash_led(uint8_t);

/* some variables */
union address_union {
    uint16_t word;
    uint8_t  byte[2];
} address;

union length_union {
    uint16_t word;
    uint8_t  byte[2];
} length;

struct flags_struct {
    unsigned eeprom : 1;
    unsigned rampz  : 1;
} flags;

uint8_t buff[256];
uint8_t address_high;

uint8_t pagesz=0x80;

uint8_t i;
uint8_t bootuart = 0;

uint8_t error_count = 0;

void (*app_start)(void) = 0x0000;


/* main program starts here */
int main(void)
{
    uint8_t ch,ch2;
    uint16_t w;

#ifdef WATCHDOG_MODS
    ch = MCUSR;
    MCUSR = 0;

    WDTCSR |= _BV(WDCE) | _BV(WDE);
    WDTCSR = 0;

    // Check if the WDT was used to reset, in which case we dont bootload and skip straight to the code. woot.
    if (! (ch &  _BV(EXTRF))) // if its a not an external reset...
        app_start();  // skip bootloader
#else
    asm volatile("nop\n\t");
#endif

    /* set pin direction for bootloader pin and enable pullup */
    /* for ATmega128, two pins need to be initialized */
#ifdef __AVR_ATmega128__
    BL_DDR &= ~_BV(BL0);
    BL_DDR &= ~_BV(BL1);
    BL_PORT |= _BV(BL0);
    BL_PORT |= _BV(BL1);
#else
    /* We run the bootloader regardless of the state of this pin.  Thus, don't
    put it in a different state than the other pins.  --DAM, 070709
    This also applies to Arduino Mega -- DC, 080930
    BL_DDR &= ~_BV(BL);
    BL_PORT |= _BV(BL);
    */
#endif


#ifdef __AVR_ATmega128__
    /* check which UART should be used for booting */
    if(bit_is_clear(BL_PIN, BL0)) {
        bootuart = 1;
    }
    else if(bit_is_clear(BL_PIN, BL1)) {
        bootuart = 2;
    }
#endif

#if defined __AVR_ATmega1280__
    /* the mega1280 chip has four serial ports ... we could eventually use any of them, or not? */
    /* however, we don't wanna confuse people, to avoid making a mess, we will stick to RXD0, TXD0 */
    bootuart = 1;
#endif

    /* check if flash is programmed already, if not start bootloader anyway */
    if(pgm_read_byte_near(0x0000) != 0xFF) {

#ifdef __AVR_ATmega128__
    /* no UART was selected, start application */
    if(!bootuart) {
        app_start();
    }
#else
    /* check if bootloader pin is set low */
    /* we don't start this part neither for the m8, nor m168 */
    //if(bit_is_set(BL_PIN, BL)) {
    //      app_start();
    //    }
#endif
    }

#ifdef __AVR_ATmega128__    
    /* no bootuart was selected, default to uart 0 */
    if(!bootuart) {
        bootuart = 1;
    }
#endif


    /* initialize UART(s) depending on CPU defined */
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
    if(bootuart == 1) {
        UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
        UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
        UCSR0A = 0x00;
        UCSR0C = 0x06;
        UCSR0B = _BV(TXEN0)|_BV(RXEN0);
    }
    if(bootuart == 2) {
        UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
        UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
        UCSR1A = 0x00;
        UCSR1C = 0x06;
        UCSR1B = _BV(TXEN1)|_BV(RXEN1);
    }
#elif defined __AVR_ATmega163__
    UBRR = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
    UBRRHI = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
    UCSRA = 0x00;
    UCSRB = _BV(TXEN)|_BV(RXEN);    
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__)

#ifdef DOUBLE_SPEED
    UCSR0A = (1<<U2X0); //Double speed mode USART0
    UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*8L)-1);
    UBRR0H = (F_CPU/(BAUD_RATE*8L)-1) >> 8;
#else
    UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
    UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
#endif

    UCSR0B = (1<<RXEN0) | (1<<TXEN0);
    UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);

    /* Enable internal pull-up resistor on pin D0 (RX), in order
    to supress line noise that prevents the bootloader from
    timing out (DAM: 20070509) */
    DDRD &= ~_BV(PIND0);
    PORTD |= _BV(PIND0);
#elif defined __AVR_ATmega8__
    /* m8 */
    UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8;  // set baud rate
    UBRRL = (((F_CPU/BAUD_RATE)/16)-1);
    UCSRB = (1<<RXEN)|(1<<TXEN);  // enable Rx & Tx
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // config USART; 8N1
#else
    /* m16,m32,m169,m8515,m8535 */
    UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
    UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
    UCSRA = 0x00;
    UCSRC = 0x06;
    UCSRB = _BV(TXEN)|_BV(RXEN);
#endif

#if defined __AVR_ATmega1280__
    /* Enable internal pull-up resistor on pin D0 (RX), in order
    to supress line noise that prevents the bootloader from
    timing out (DAM: 20070509) */
    /* feature added to the Arduino Mega --DC: 080930 */
    DDRE &= ~_BV(PINE0);
    PORTE |= _BV(PINE0);
#endif


    /* set LED pin as output */
    LED_DDR |= _BV(LED);


    /* flash onboard LED to signal entering of bootloader */
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
    // 4x for UART0, 5x for UART1
    flash_led(NUM_LED_FLASHES + bootuart);
#else
    flash_led(NUM_LED_FLASHES);
#endif

    /* 20050803: by DojoCorp, this is one of the parts provoking the
         system to stop listening, cancelled from the original */
    //putch('\0');

    /* forever loop */
    for (;;) {

    /* get character from UART */
    ch = getch();

    /* A bunch of if...else if... gives smaller code than switch...case ! */

    /* Hello is anyone home ? */ 
    if(ch=='0') {
        nothing_response();
    }


    /* Request programmer ID */
    /* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry  */
    /* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares.  */
    else if(ch=='1') {
        if (getch() == ' ') {
            putch(0x14);
            putch('A');
            putch('V');
            putch('R');
            putch(' ');
            putch('I');
            putch('S');
            putch('P');
            putch(0x10);
        } else {
            if (++error_count == MAX_ERROR_COUNT)
                app_start();
        }
    }


    /* AVR ISP/STK500 board commands  DON'T CARE so default nothing_response */
    else if(ch=='@') {
        ch2 = getch();
        if (ch2>0x85) getch();
        nothing_response();
    }


    /* AVR ISP/STK500 board requests */
    else if(ch=='A') {
        ch2 = getch();
        if(ch2==0x80) byte_response(HW_VER);        // Hardware version
        else if(ch2==0x81) byte_response(SW_MAJOR); // Software major version
        else if(ch2==0x82) byte_response(SW_MINOR); // Software minor version
        else if(ch2==0x98) byte_response(0x03);     // Unknown but seems to be required by avr studio 3.56
        else byte_response(0x00);               // Covers various unnecessary responses we don't care about
    }


    /* Device Parameters  DON'T CARE, DEVICE IS FIXED  */
    else if(ch=='B') {
        getNch(20);
        nothing_response();
    }


    /* Parallel programming stuff  DON'T CARE  */
    else if(ch=='E') {
        getNch(5);
        nothing_response();
    }


    /* P: Enter programming mode  */
    /* R: Erase device, don't care as we will erase one page at a time anyway.  */
    else if(ch=='P' || ch=='R') {
        nothing_response();
    }


    /* Leave programming mode  */
    else if(ch=='Q') {
        nothing_response();
#ifdef WATCHDOG_MODS
        // autoreset via watchdog (sneaky!)
        WDTCSR = _BV(WDE);
        while (1); // 16 ms
#endif
    }


    /* Set address, little endian. EEPROM in bytes, FLASH in words  */
    /* Perhaps extra address bytes may be added in future to support > 128kB FLASH.  */
    /* This might explain why little endian was used here, big endian used everywhere else.  */
    else if(ch=='U') {
        address.byte[0] = getch();
        address.byte[1] = getch();
        nothing_response();
    }


    /* Universal SPI programming command, disabled.  Would be used for fuses and lock bits.  */
    else if(ch=='V') {
        if (getch() == 0x30) {
            getch();
            ch = getch();
            getch();
            if (ch == 0) {
                byte_response(SIG1);
            } else if (ch == 1) {
                byte_response(SIG2); 
            } else {
                byte_response(SIG3);
            } 
        } else {
            getNch(3);
            byte_response(0x00);
        }
    }


    /* Write memory, length is big endian and is in bytes  */
    else if(ch=='d') {
        length.byte[1] = getch();
        length.byte[0] = getch();
        flags.eeprom = 0;
        if (getch() == 'E') flags.eeprom = 1;
        for (w=0;w<length.word;w++) {
            buff[w] = getch();                          // Store data in buffer, can't keep up with serial data stream whilst programming pages
        }
        if (getch() == ' ') {
            if (flags.eeprom) {                     //Write to EEPROM one byte at a time
                address.word <<= 1;
                for(w=0;w<length.word;w++) {
#if defined(__AVR_ATmega168__)  || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
                    while(EECR & (1<<EEPE));
                    EEAR = (uint16_t)(void *)address.word;
                    EEDR = buff[w];
                    EECR |= (1<<EEMPE);
                    EECR |= (1<<EEPE);
#else
                    eeprom_write_byte((void *)address.word,buff[w]);
#endif
                    address.word++;
                }           
            }
            else {                          //Write to FLASH one page at a time
                if (address.byte[1]>127) address_high = 0x01;   //Only possible with m128, m256 will need 3rd address byte. FIXME
                else address_high = 0x00;
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)
                RAMPZ = address_high;
#endif
                address.word = address.word << 1;           //address * 2 -> byte location
                /* if ((length.byte[0] & 0x01) == 0x01) length.word++;  //Even up an odd number of bytes */
                if ((length.byte[0] & 0x01)) length.word++; //Even up an odd number of bytes
                cli();                  //Disable interrupts, just to be sure
#if defined(EEPE)
                while(bit_is_set(EECR,EEPE));           //Wait for previous EEPROM writes to complete
#else
                while(bit_is_set(EECR,EEWE));           //Wait for previous EEPROM writes to complete
#endif
                asm volatile(
                     "clr   r17     \n\t"   //page_word_count
                     "lds   r30,address \n\t"   //Address of FLASH location (in bytes)
                     "lds   r31,address+1   \n\t"
                     "ldi   r28,lo8(buff)   \n\t"   //Start of buffer array in RAM
                     "ldi   r29,hi8(buff)   \n\t"
                     "lds   r24,length  \n\t"   //Length of data to be written (in bytes)
                     "lds   r25,length+1    \n\t"
                     "length_loop:      \n\t"   //Main loop, repeat for number of words in block                                                         
                     "cpi   r17,0x00    \n\t"   //If page_word_count=0 then erase page
                     "brne  no_page_erase   \n\t"                        
                     "wait_spm1:        \n\t"
                     "lds   r16,%0      \n\t"   //Wait for previous spm to complete
                     "andi  r16,1           \n\t"
                     "cpi   r16,1           \n\t"
                     "breq  wait_spm1       \n\t"
                     "ldi   r16,0x03    \n\t"   //Erase page pointed to by Z
                     "sts   %0,r16      \n\t"
                     "spm           \n\t"                            
#ifdef __AVR_ATmega163__
                     ".word 0xFFFF      \n\t"
                     "nop           \n\t"
#endif
                     "wait_spm2:        \n\t"
                     "lds   r16,%0      \n\t"   //Wait for previous spm to complete
                     "andi  r16,1           \n\t"
                     "cpi   r16,1           \n\t"
                     "breq  wait_spm2       \n\t"                                    

                     "ldi   r16,0x11    \n\t"   //Re-enable RWW section
                     "sts   %0,r16      \n\t"                                    
                     "spm           \n\t"
#ifdef __AVR_ATmega163__
                     ".word 0xFFFF      \n\t"
                     "nop           \n\t"
#endif
                     "no_page_erase:        \n\t"                            
                     "ld    r0,Y+       \n\t"   //Write 2 bytes into page buffer
                     "ld    r1,Y+       \n\t"                            

                     "wait_spm3:        \n\t"
                     "lds   r16,%0      \n\t"   //Wait for previous spm to complete
                     "andi  r16,1           \n\t"
                     "cpi   r16,1           \n\t"
                     "breq  wait_spm3       \n\t"
                     "ldi   r16,0x01    \n\t"   //Load r0,r1 into FLASH page buffer
                     "sts   %0,r16      \n\t"
                     "spm           \n\t"

                     "inc   r17     \n\t"   //page_word_count++
                     "cpi r17,%1            \n\t"
                     "brlo  same_page   \n\t"   //Still same page in FLASH
                     "write_page:       \n\t"
                     "clr   r17     \n\t"   //New page, write current one first
                     "wait_spm4:        \n\t"
                     "lds   r16,%0      \n\t"   //Wait for previous spm to complete
                     "andi  r16,1           \n\t"
                     "cpi   r16,1           \n\t"
                     "breq  wait_spm4       \n\t"
#ifdef __AVR_ATmega163__
                     "andi  r30,0x80    \n\t"   // m163 requires Z6:Z1 to be zero during page write
#endif                                                       
                     "ldi   r16,0x05    \n\t"   //Write page pointed to by Z
                     "sts   %0,r16      \n\t"
                     "spm           \n\t"
#ifdef __AVR_ATmega163__
                     ".word 0xFFFF      \n\t"
                     "nop           \n\t"
                     "ori   r30,0x7E    \n\t"   // recover Z6:Z1 state after page write (had to be zero during write)
#endif
                     "wait_spm5:        \n\t"
                     "lds   r16,%0      \n\t"   //Wait for previous spm to complete
                     "andi  r16,1           \n\t"
                     "cpi   r16,1           \n\t"
                     "breq  wait_spm5       \n\t"                                    
                     "ldi   r16,0x11    \n\t"   //Re-enable RWW section
                     "sts   %0,r16      \n\t"                                    
                     "spm           \n\t"                            
#ifdef __AVR_ATmega163__
                     ".word 0xFFFF      \n\t"
                     "nop           \n\t"
#endif
                     "same_page:        \n\t"                            
                     "adiw  r30,2       \n\t"   //Next word in FLASH
                     "sbiw  r24,2       \n\t"   //length-2
                     "breq  final_write \n\t"   //Finished
                     "rjmp  length_loop \n\t"
                     "final_write:      \n\t"
                     "cpi   r17,0       \n\t"
                     "breq  block_done  \n\t"
                     "adiw  r24,2       \n\t"   //length+2, fool above check on length after short page write
                     "rjmp  write_page  \n\t"
                     "block_done:       \n\t"
                     "clr   __zero_reg__    \n\t"   //restore zero register
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)
                     : "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
#else
                     : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
#endif
                     );
                /* Should really add a wait for RWW section to be enabled, don't actually need it since we never */
                /* exit the bootloader without a power cycle anyhow */
            }
            putch(0x14);
            putch(0x10);
        } else {
            if (++error_count == MAX_ERROR_COUNT)
                app_start();
        }       
    }


    /* Read memory block mode, length is big endian.  */
    else if(ch=='t') {
        length.byte[1] = getch();
        length.byte[0] = getch();
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
        if (address.word>0x7FFF) flags.rampz = 1;       // No go with m256, FIXME
        else flags.rampz = 0;
#endif
        address.word = address.word << 1;           // address * 2 -> byte location
        if (getch() == 'E') flags.eeprom = 1;
        else flags.eeprom = 0;
        if (getch() == ' ') {                       // Command terminator
            putch(0x14);
            for (w=0;w < length.word;w++) {             // Can handle odd and even lengths okay
                if (flags.eeprom) {                         // Byte access EEPROM read
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
                    while(EECR & (1<<EEPE));
                    EEAR = (uint16_t)(void *)address.word;
                    EECR |= (1<<EERE);
                    putch(EEDR);
#else
                    putch(eeprom_read_byte((void *)address.word));
#endif
                    address.word++;
                }
                else {

                    if (!flags.rampz) putch(pgm_read_byte_near(address.word));
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
                    else putch(pgm_read_byte_far(address.word + 0x10000));
                    // Hmmmm, yuck  FIXME when m256 arrvies
#endif
                    address.word++;
                }
            }
            putch(0x10);
        }
    }


    /* Get device signature bytes  */
    else if(ch=='u') {
        if (getch() == ' ') {
            putch(0x14);
            putch(SIG1);
            putch(SIG2);
            putch(SIG3);
            putch(0x10);
        } else {
            if (++error_count == MAX_ERROR_COUNT)
                app_start();
        }
    }


    /* Read oscillator calibration byte */
    else if(ch=='v') {
        byte_response(0x00);
    }


#if defined MONITOR 

    /* here come the extended monitor commands by Erik Lins */

    /* check for three times exclamation mark pressed */
    else if(ch=='!') {
        ch = getch();
        if(ch=='!') {
        ch = getch();
        if(ch=='!') {
            PGM_P welcome = "";
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
            uint16_t extaddr;
#endif
            uint8_t addrl, addrh;

#ifdef CRUMB128
            welcome = "ATmegaBOOT / Crumb128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
#elif defined PROBOMEGA128
            welcome = "ATmegaBOOT / PROBOmega128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
#elif defined SAVVY128
            welcome = "ATmegaBOOT / Savvy128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
#elif defined __AVR_ATmega1280__ 
            welcome = "ATmegaBOOT / Arduino Mega - (C) Arduino LLC - 090930\n\r";
#endif

            /* turn on LED */
            LED_DDR |= _BV(LED);
            LED_PORT &= ~_BV(LED);

            /* print a welcome message and command overview */
            for(i=0; welcome[i] != '\0'; ++i) {
                putch(welcome[i]);
            }

            /* test for valid commands */
            for(;;) {
                putch('\n');
                putch('\r');
                putch(':');
                putch(' ');

                ch = getch();
                putch(ch);

                /* toggle LED */
                if(ch == 't') {
                    if(bit_is_set(LED_PIN,LED)) {
                        LED_PORT &= ~_BV(LED);
                        putch('1');
                    } else {
                        LED_PORT |= _BV(LED);
                        putch('0');
                    }
                } 

                /* read byte from address */
                else if(ch == 'r') {
                    ch = getch(); putch(ch);
                    addrh = gethex();
                    addrl = gethex();
                    putch('=');
                    ch = *(uint8_t *)((addrh << 8) + addrl);
                    puthex(ch);
                }

                /* write a byte to address  */
                else if(ch == 'w') {
                    ch = getch(); putch(ch);
                    addrh = gethex();
                    addrl = gethex();
                    ch = getch(); putch(ch);
                    ch = gethex();
                    *(uint8_t *)((addrh << 8) + addrl) = ch;
                }

                /* read from uart and echo back */
                else if(ch == 'u') {
                    for(;;) {
                        putch(getch());
                    }
                }
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
                /* external bus loop  */
                else if(ch == 'b') {
                    putch('b');
                    putch('u');
                    putch('s');
                    MCUCR = 0x80;
                    XMCRA = 0;
                    XMCRB = 0;
                    extaddr = 0x1100;
                    for(;;) {
                        ch = *(volatile uint8_t *)extaddr;
                        if(++extaddr == 0) {
                            extaddr = 0x1100;
                        }
                    }
                }
#endif

                else if(ch == 'j') {
                    app_start();
                }

            } /* end of monitor functions */

        }
        }
    }
    /* end of monitor */
#endif
    else if (++error_count == MAX_ERROR_COUNT) {
        app_start();
    }
    } /* end of forever loop */

}


char gethexnib(void) {
    char a;
    a = getch(); putch(a);
    if(a >= 'a') {
        return (a - 'a' + 0x0a);
    } else if(a >= '0') {
        return(a - '0');
    }
    return a;
}


char gethex(void) {
    return (gethexnib() << 4) + gethexnib();
}


void puthex(char ch) {
    char ah;

    ah = ch >> 4;
    if(ah >= 0x0a) {
        ah = ah - 0x0a + 'a';
    } else {
        ah += '0';
    }

    ch &= 0x0f;
    if(ch >= 0x0a) {
        ch = ch - 0x0a + 'a';
    } else {
        ch += '0';
    }

    putch(ah);
    putch(ch);
}


void putch(char ch)
{
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
    if(bootuart == 1) {
        while (!(UCSR0A & _BV(UDRE0)));
        UDR0 = ch;
    }
    else if (bootuart == 2) {
        while (!(UCSR1A & _BV(UDRE1)));
        UDR1 = ch;
    }
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__)
    while (!(UCSR0A & _BV(UDRE0)));
    UDR0 = ch;
#else
    /* m8,16,32,169,8515,8535,163 */
    while (!(UCSRA & _BV(UDRE)));
    UDR = ch;
#endif
}


char getch(void)
{
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
    uint32_t count = 0;
    if(bootuart == 1) {
        while(!(UCSR0A & _BV(RXC0))) {
            /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
            /* HACKME:: here is a good place to count times*/
            count++;
            if (count > MAX_TIME_COUNT)
                app_start();
        }

        return UDR0;
    }
    else if(bootuart == 2) {
        while(!(UCSR1A & _BV(RXC1))) {
            /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
            /* HACKME:: here is a good place to count times*/
            count++;
            if (count > MAX_TIME_COUNT)
                app_start();
        }

        return UDR1;
    }
    return 0;
#elif defined(__AVR_ATmega168__)  || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__)
    uint32_t count = 0;
    while(!(UCSR0A & _BV(RXC0))){
        /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
        /* HACKME:: here is a good place to count times*/
        count++;
        if (count > MAX_TIME_COUNT)
            app_start();
    }
    return UDR0;
#else
    /* m8,16,32,169,8515,8535,163 */
    uint32_t count = 0;
    while(!(UCSRA & _BV(RXC))){
        /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
        /* HACKME:: here is a good place to count times*/
        count++;
        if (count > MAX_TIME_COUNT)
            app_start();
    }
    return UDR;
#endif
}


void getNch(uint8_t count)
{
    while(count--) {
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
        if(bootuart == 1) {
            while(!(UCSR0A & _BV(RXC0)));
            UDR0;
        } 
        else if(bootuart == 2) {
            while(!(UCSR1A & _BV(RXC1)));
            UDR1;
        }
#elif defined(__AVR_ATmega168__)  || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__)
        getch();
#else
        /* m8,16,32,169,8515,8535,163 */
        /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
        //while(!(UCSRA & _BV(RXC)));
        //UDR;
        getch(); // need to handle time out
#endif      
    }
}


void byte_response(uint8_t val)
{
    if (getch() == ' ') {
        putch(0x14);
        putch(val);
        putch(0x10);
    } else {
        if (++error_count == MAX_ERROR_COUNT)
            app_start();
    }
}


void nothing_response(void)
{
    if (getch() == ' ') {
        putch(0x14);
        putch(0x10);
    } else {
        if (++error_count == MAX_ERROR_COUNT)
            app_start();
    }
}

void flash_led(uint8_t count)
{
    while (count--) {
        LED_PORT |= _BV(LED);
        _delay_ms(100);
        LED_PORT &= ~_BV(LED);
        _delay_ms(100);
    }
}


/* end of file ATmegaBOOT.c */

Arduino重置-复位

阅读数 12915

arduino 是什么

阅读数 1111

没有更多推荐了,返回首页