-
原 arduino12015-05-30 10:04:35 kevin3052974065 阅读数 1843
-
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 阅读数 2344
-
涉及电子专业或行业的人都多少听说过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 阅读数 3430
-
左侧自上而下:
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 阅读数 8403
-
欢迎来到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 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软件的介绍将在下一节中详细介绍。
更多内容,欢迎关注我的公众号。 微信扫一扫下方二维码即可关注:
-
2017-07-21 10:26:35 u012763833 阅读数 1506
-
Arduino是一个基于开源代码的快速电子原型开发平台,其由各种型号的Arduino开发板及Arduino IDE组成(官网,中文社区)。目前的Arduino开发板是基于AVR单片机系统开发,并在其基础上作了较完善的软硬件封装,目的是尽量屏蔽底层硬件的影响便于快速开发。
1. Arduino开发板硬件解析,基于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 相关内容

蓝牙模块与arduino 相关内容

蓝牙模块与arduino 相关内容

蓝牙模块与arduino 相关内容

蓝牙模块与arduino 相关内容
-
[Arduino]烧写Arduino BootLoader的几种方法
阅读数 25593
[Arduino]烧写ArduinoBootLoader的几种方法
博文 来自: sysjtlwx -
阅读数 12925
-
阅读数 2443
-
阅读数 1112
-
阅读数 817