Stap 6: Arduino, Chips en Code toevoegen!
U kunt nu programma Arduino Bootloaders uit binnen de IDE en ook de AVR-chips met AVRDUDE vermeld, maar ik zal uitleggen hoe alles doen wat op een minder product georiënteerde Instructable.
Deze sketch verandert de Arduino in een AVRISP
met behulp van de volgende pinnen:
10: reset slave
11: MOSI
12: MISO
13: SCKEen LED (met resistor) zetten de volgende pinnen:
7: fout - oplicht als er iets misgaat (gebruik rood als dat zinvol is)
8: programmeren - communicatie met de slaaf
6: heartbeat - toont de programmeur draait (verwijderd, zie opmerkingen hieronder)
Optioneel - piëzo spreker op pin A3
//
Oktober 2009 door David A. Mellis
-Toegevoegde steun voor de opdracht Lees handtekening
//
Februari 2009 door Randall Bohn
-Toegevoegde steun voor schrijven naar EEPROM (wat zo lang duurde?)
Windows-gebruikers moeten overwegen de WinAVR avrdude in plaats van de
avrdude opgenomen met de Arduino software.
//
Januari 2008 door Randall Bohn
-Met dank aan Amplificar voor portie mij met het STK500-protocol
-De AVRISP/STK500 (mk ik) protocol wordt gebruikt in de bootloader van de arduino
-De SPI functies hierin waren ontwikkeld voor de AVR910_ARD-programmeur
-Meer informatie op http://code.google.com/p/mega-isp
//
Maart 2012 - William Phelps
wijzigen om te werken met Arduino IDE 1.0 heeft een kortere seriële poort ontvangen buffer
getEOP() nu krijgt hele verzoek voordat avrisp() wordt aangeroepen om te verwerken
Serial.Print((char) xxx) gewijzigd in Serial.write(xxx)
uint8_t gewijzigd in byte
toegevoegde ondersteuning voor piëzo-luidspreker
verplaatste Pmode LED tot A0
"heartbeat" op pin 6 verwijderd, toegevoegd in plaats daarvan korte blip van fout-LED
Waarom is het dat PROG_FLASH en PROG_DATA eigenlijk niets doe???
Getest met Arduino IDE 22 en 1.0
IDE 22-5148 bytes
IDE 1.0-5524 bytes!Januari 2014 - Ben grijs
Zet de hartslag geleid terug en stapte rond de pinnen een beetje voor de LEDs.TRAGE CHIP WISSEN EN ZEKERING BRANDEN
//
Inschakelen van LOW_SPEED zodat u kunt wissen chips die anders zou ontbreken
voor met een klok te traag wordt uitgevoerd voor de programmeur.
//
Dit stond me toe om te herstellen van verschillende ATMega328 die had geen opstartlader en de
eerste instructie was de klok wilt instellen op de langzaamste snelheid. Meestal is dit
soort herstel vereist hoogspanning programmeren, maar deze truc zal doen
prima.
//
Hoe verder te gaan:
// 1. Inschakelen van LOW_SPEED, en het laden voor de programmeur.
// 2. Wissen en de zekeringen op de doel-uC branden. Voorbeeld voor ATMega328:
Arduino-1.0.1/Hardware/tools/avrdude-Carduino-1.0.1/hardware/tools/avrdude.conf-patmega328p-cstk500v1 -P /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A900cf1Q-if00-port0-b19200 -e - Ulock: w: 0x3F: m - Uefuse: w: 0x05: m - Uhfuse: w: 0xDA: m - Ulfuse: w: 0xF7: m
// 3. Commentaar LOW_SPEED en laadt u het terug naar de programmeur.
// 4. De doel-uC zoals gebruikelijk Program. In het volgende voorbeeld:
Arduino-1.0.1/Hardware/tools/avrdude-Carduino-1.0.1/hardware/tools/avrdude.conf-patmega328p-cstk500v1 -P /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A900cf1Q-if00-port0-b19200-Uflash:w:firmware.hex:i
//
Opmerking 1: EXTRA_SPI_DELAY toegevoegd om u vertragen SPI nog meer te laten. U kunt
spelen met de waarde als het niet met de standaard werkt.
Noot 2: LOW_SPEED zal alow u alleen voor het wissen van de chip en de zekeringen branden! Het
mislukt als u probeert te programmeren van de doel-uC deze manier!
#define LOW_SPEED
#ifdef LOW_SPEED
#define EXTRA_SPI_DELAY 125
#else
#define EXTRA_SPI_DELAY 0
#endif
#include "pins_arduino.h" / / definieert SS MOSI, MISO, SCK
#define RESET SS
#define LED_ERR 7
#define LED_PMODE 8
#define LED_HB 6
#define PIEZO A3
#define HWVER 2
#define SWMAJ 1
#define SWMIN 18
STK-definities
Const byte STK_OK = 0x10;
Const byte STK_FAILED = 0x11;
Const byte STK_UNKNOWN = 0x12;
Const byte STK_INSYNC = 0x14;
Const byte STK_NOSYNC = 0x15;
Const byte CRC_EOP = 0x20; OK is het een ruimte...
Const byte STK_GET_SYNC = 0x30;
Const byte STK_GET_SIGNON = 0x31;
Const byte STK_GET_PARM = 0x41;
Const byte STK_SET_PARM = 0x42;
Const byte STK_SET_PARM_EXT = 0x45;
Const byte STK_PMODE_START = 0x50;
Const byte STK_PMODE_END = 0x51;
Const byte STK_SET_ADDR = 0x55;
Const byte STK_UNIVERSAL = 0x56;
Const byte STK_PROG_FLASH = 0x60;
Const byte STK_PROG_DATA = 0x61;
Const byte STK_PROG_PAGE = 0x64;
Const byte STK_READ_PAGE = 0x74;
Const byte STK_READ_SIGN = 0x75;
//// TONES ==========================================
Beginnen met het definiëren van de relatie tussen
Opmerking, periode, & frequentie.
#define c 3830 / / 261 Hz
#define d 3400 / / 294 Hz
#define e 3038 / / 329 Hz
#define f 2864 / / 349 Hz
#define g 2550 / / 392 Hz
#define een 2272 / / 440 Hz
#define b 2028 / / 493 Hz
#define C 1912 / / 523 Hz
VOID pulse (int pin, int times);
int fout = 0;
int pmode = 0;
adres voor lezen en schrijven, door STK_SET_ADDR opdracht
int _addr;
byte _buffer [256]; seriële poort buffer
int pBuffer = 0; buffer aanwijzer
int iBuffer = 0; buffer-index
byte buff [256]; tijdelijke buffer
Boole EOP_SEEN = false;
VOID Setup {}
Serial.begin(19200);
pinMode (PIËZO, uitvoer);
Beep(1700, 40);
EOP_SEEN = false;
iBuffer = pBuffer = 0;
pinMode (LED_PMODE, uitvoer);
Pulse (LED_PMODE, 2);
pinMode (LED_ERR, uitvoer);
Pulse (LED_ERR, 2);
pinMode (LED_HB, uitvoer);
Pulse (LED_HB, 2);
pinMode (9, OUTPUT);
opstelling van hoog freq PWM op pin 9 (timer 1)
Taakcyclus van 50% -> 8 MHz
OCR1A = 0;
ICR1 = 1;
OC1A uitgang, snelle PWM
TCCR1A = _BV(WGM11) | _BV(COM1A1);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); geen klok prescale
}
#define beget16(addr) (* addr * 256 + *(addr+1))
typedef struct param {}
byte devicecode;
byte herziening;
byte progtype;
byte parmode;
byte polling;
byte selftimed;
byte lockbytes;
byte fusebytes;
int flashpoll;
int eeprompoll;
int pagesize;
int eepromsize;
int flashsize;
}
parameter;
met de parameter param;
Dit biedt een hartslag op pin 6, zodat u kunt vertellen dat de software wordt uitgevoerd.
byte hbval = 128;
int8_t hbdelta = 4;
ongeldig heartbeat() {}
Als (hbval > 192) hbdelta = - hbdelta;
Als (hbval < 32) hbdelta = - hbdelta;
Als (hbval > 250) hbdelta = - hbdelta;
Als (hbval < 10) hbdelta = - hbdelta;
hbval += hbdelta;
analogWrite (LED_HB, hbval);
vertraging(20);
}
ongeldig getEOP() {}
int minL = 0;
byte avrch = 0;
byte bl = 0;
terwijl (!. EOP_SEEN) {}
terwijl (Serial.available() > 0) {}
byte ch = Serial.read();
_buffer [iBuffer] = ch;
iBuffer = (++ iBuffer) % 256; increment en omslag
Als (iBuffer == 1) avrch = ch; opslaan, opdracht
Als ((avrch == STK_PROG_PAGE) & & (iBuffer == 3)) {}
minL = 256 * _buffer [1] [2] _buffer + 4;
}
Als ((iBuffer>minL) & & (ch == CRC_EOP)) {}
EOP_SEEN = true;
}
}
if (!. EOP_SEEN) {}
heartbeat(); de hartslag LED licht
Als (bl == 100) {}
Pulse(LED_ERR,1,10); de rode LED knipperen
// bl = 0;
// }
BL ++;
delay(10);
}
}
}
serialEvent niet gebruikt dus schets zou compatibel met oudere versies van de IDE
ongeldig serialEvent() {}
int minL = 0;
byte avrch = 0;
terwijl (Serial.available() > 0)
// {
byte ch = Serial.read();
_buffer [iBuffer] = ch;
iBuffer = (++ iBuffer) % 256; increment en omslag
Als (iBuffer == 1) avrch = ch; opslaan, opdracht
Als ((avrch == STK_PROG_PAGE) & & (iBuffer == 3)) {}
minL = 256 * _buffer [1] [2] _buffer + 4;
// }
Als ((iBuffer>minL) & & (ch == CRC_EOP)) {}
EOP_SEEN = true;
// }
// }
//}
ongeldig loop(void) {}
pmode actief is?
Als (pmode) digitalWrite (LED_PMODE, hoge);
anders digitalWrite (LED_PMODE, laag);
digitalWrite (LED_PMODE, laag);
is er een fout?
Als (fout) digitalWrite (LED_ERR, hoge);
anders digitalWrite (LED_ERR, laag);
getEOP();
hebben we een volledige aanvraag ontvangen? (eindigt met CRC_EOP)
Als (EOP_SEEN) {}
digitalWrite (LED_PMODE, hoge);
EOP_SEEN = false;
avrisp();
iBuffer = pBuffer = 0; opnieuw opstarten van de buffer
}
}
byte getch() {}
Als (pBuffer == iBuffer) {/ / spin tot beschikbare gegevens???
Pulse (LED_ERR, 1);
Beep(1700, 20);
fout ++;
retourneren -1;
}
byte ch = _buffer [pBuffer]; krijg volgende char
pBuffer = (++ pBuffer) % 256; increment en omslag
retourneren van ch;
}
VOID readbytes (int n) {}
voor (int x = 0; x < n; x ++) {}
Buff [x] = getch();
}
}
#define PTIJDSBLOK 20
VOID pulse (int pin, int times, int pTijdsblok) {}
{}
digitalWrite (pin, hoge);
delay(ptime);
digitalWrite (pin, laag);
delay(ptime);
tijden--;
}
terwijl (tijden > 0);
}
VOID pulse (int pin, int times) {}
Pulse (pin, tijden, 50);
}
ongeldig spi_init() {}
byte x;
SPCR = 0X53;
#ifdef LOW_SPEED
SPCR = SPCR| B00000011;
#endif
x = SPSR;
x = SPDR;
}
ongeldig spi_wait() {}
{}
}
terwijl (! () SPSR & (1 << SPIF)));
}
byte spi_send (byte b) {}
byte antwoord;
#ifdef LOW_SPEED
cli();
CLKPR = B10000000;
CLKPR = B00000011;
Sei();
#endif
SPDR = b;
spi_wait();
antwoord = SPDR;
#ifdef LOW_SPEED
cli();
CLKPR = B10000000;
CLKPR = B00000000;
Sei();
#endif
retourneren van antwoord;
}
byte spi_transaction (byte per byte byte c, b, byte d) {}
byte n;
spi_send(a);
n=spi_send(b);
Als (n! = een) fout = -1;
n=spi_send(c);
Return spi_send(d);
}
ongeldig replyOK() {}
Als (EOP_SEEN == true) {}
Als (CRC_EOP == getch()) {/ / EOP mag volgende char
Serial.write(STK_INSYNC);
Serial.write(STK_OK);
}
else {}
Pulse (LED_ERR, 2);
Serial.write(STK_NOSYNC);
fout ++;
}
}
VOID breply (byte b) {}
Als (CRC_EOP == getch()) {/ / EOP mag volgende char
Serial.write(STK_INSYNC);
Serial.write(b);
Serial.write(STK_OK);
}
else {}
Serial.write(STK_NOSYNC);
fout ++;
}
}
VOID get_parameter (byte c) {}
switch(c) {}
Case 0x80:
breply(HWVER);
breken;
Case 0x81:
breply(SWMAJ);
breken;
Case 0x82:
breply(SWMIN);
breken;
Case 0x93:
breply('S'); seriële programmeur
breken;
standaard:
breply(0);
}
}
ongeldig set_parameters() {}
noemen dit na het lezen van paramter packet in buff]
param.devicecode = buff [0];
param.Revision = buff [1];
param.progtype = buff [2];
param.parmode = buff [3];
param.polling = buff [4];
param.selftimed = buff [5];
param.lockbytes = buff [6];
param.fusebytes = buff [7];
param.flashpoll = buff [8];
negeren van buff [9] (= buff[8])
getch(); negeren van de tweede waarde
Waarschuwing: niet zeker over de bytevolgorde van de volgende
Hieronder vindt u 16-bits (big endian)
param.eeprompoll = beget16 (& buff[10]);
param.PageSize = beget16 (& buff[12]);
param.eepromsize = beget16 (& buff[14]);
32 bits flashsize (big endian)
param.flashsize = buff [16] * 0x01000000
+ buff [17] * 0x00010000
+ buff [18] * 0x00000100
+ buff [19];
}
ongeldig start_pmode() {}
spi_init();
Na vertragingen werkt mogelijk niet op alle doelen...
pinMode (RESET, uitvoer);
digitalWrite (RESET, hoge);
pinMode (SCK, uitvoer);
digitalWrite (SCK, laag);
delay(50+EXTRA_SPI_DELAY);
digitalWrite (RESET, laag);
delay(50+EXTRA_SPI_DELAY);
pinMode (MISO, INPUT);
pinMode (MOSI, uitvoer);
spi_transaction (0xAC, 0x53, 0x00, 0x00);
PMode = 1;
}
ongeldig end_pmode() {}
pinMode (MISO, INPUT);
pinMode (MOSI, INPUT);
pinMode (SCK, INPUT);
pinMode (RESET, INPUT);
PMode = 0;
}
ongeldig universal() {}
int w;
byte ch;
voor (w = 0; w < 4; w ++) {}
Buff [w] = getch();
// }
readbytes(4);
CH = spi_transaction (buff [0] [1] buff, buff [2], buff[3]);
breply(CH);
}
VOID flitser (byte hilo, int addr bytegegevens) {}
spi_transaction (0x40 + 8 * hilo, addr >> 8 & 0xFF, addr & 0xFF, gegevens);
}
VOID commit (int addr) {}
spi_transaction (0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
}
#define _current_page(x) (hier & 0xFFFFE0)
int current_page (int addr) {}
Als (param.pagesize == 32) keren addr & 0xFFFFFFF0;
Als (param.pagesize == 64) keren addr & 0xFFFFFFE0;
Als (param.pagesize == 128) keren addr & 0xFFFFFFC0;
Als (param.pagesize == 256) keren addr & 0xFFFFFF80;
retourneren addr;
}
byte write_flash (int lengte) {}
Als (param.pagesize < 1) {}
Return STK_FAILED;
}
Als (param.pagesize! = 64) terug van STK_FAILED;
int pagina = current_page(_addr);
int x = 0;
terwijl (x < lengte) {}
Als (pagina! = current_page(_addr)) {}
commit(page);
pagina = current_page(_addr);
}
Flash (LOW, _addr, buff[x++]);
Flash (HIGH, _addr, buff[x++]);
_addr ++;
}
commit(page);
Return STK_OK;
}
byte write_eeprom (int lengte) {}
Hier is het adres van een woord, dus we hier gebruiken * 2
Dit schrijft byte-door-byte,
pagina schrijven kan worden sneller (4 bytes per keer)
voor (int x = 0; x < lengte; x ++) {}
spi_transaction (0xC0, 0x00, _addr * 2 + x, buff[x]);
delay(45);
}
Return STK_OK;
}
ongeldig program_page() {}
byte resultaat = STK_FAILED;
int lengte = 256 * getch() + getch();
Als (lengte > 256) {}
Serial.write(STK_FAILED);
fout ++;
terugkeer;
}
char memtype = (char)getch();
voor (int x = 0; x < lengte; x ++) {}
Buff [x] = getch();
// }
readbytes(length);
Als (CRC_EOP == getch()) {}
Serial.write(STK_INSYNC);
schakelaar (memtype) {}
Case "E":
resultaat = (byte)write_eeprom(length);
breken;
Case "F":
resultaat = (byte)write_flash(length);
breken;
}
Serial.write(result);
Als (resultaat! = STK_OK) {}
fout ++;
}
}
else {}
Serial.write(STK_NOSYNC);
fout ++;
}
}
byte flash_read (byte hilo, int addr) {}
keren spi_transaction (0x20 + hilo * 8,
(addr >> 8) & 0xFF,
addr & 0xFF,
0);
}
char flash_read_page(int length) {}
voor (int x = 0; x < lengte; x+= 2) {}
byte laag = flash_read (lage, _addr);
Serial.write (laag);
byte hoge = flash_read (hoog, _addr);
Serial.write (hoog);
_addr ++;
}
Return STK_OK;
}
char eeprom_read_page(int length) {}
Hier hebben we weer een woord-adres
voor (int x = 0; x < lengte; x ++) {}
byte ee = spi_transaction (0xA0, 0x00, _addr * 2 + x, 0xFF);
Serial.write (ee);
}
Return STK_OK;
}
ongeldig read_page() {}
byte resultaat = (byte) STK_FAILED;
int lengte = 256 * getch() + getch();
char memtype = getch();
Als (CRC_EOP! = getch()) {}
Serial.write(STK_NOSYNC);
terugkeer;
}
Serial.write(STK_INSYNC);
Als (memtype == 'F') resultaat = flash_read_page(length);
Als (memtype == 'E') resultaat = eeprom_read_page(length);
Serial.write(result);
terugkeer;
}
ongeldig read_signature() {}
Als (CRC_EOP! = getch()) {}
Serial.write(STK_NOSYNC);
fout ++;
terugkeer;
}
Serial.write(STK_INSYNC);
byte hoge = spi_transaction (0x30, 0x00, 0x00, 0x00);
Serial.write(High);
byte midden = spi_transaction (0x30, 0x00, 0x01, 0x00);
Serial.write(Middle);
byte laag = spi_transaction (0x30, 0x00, 0x02, 0x00);
Serial.write(Low);
Serial.write(STK_OK);
}
//////////////////////////////////////////
//////////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
int avrisp() {}
bytegegevens, laag, hoog;
byte avrch = getch();
schakelaar (avrch) {}
kast STK_GET_SYNC: / / get synchroon
replyOK();
breken;
kast STK_GET_SIGNON: / / get teken op
Als (getch() == CRC_EOP) {}
Serial.write(STK_INSYNC);
Serial.write ("AVR ISP");
Serial.write(STK_OK);
}
breken;
kast STK_GET_PARM: / / 0x41
get_parameter(getch());
breken;
kast STK_SET_PARM: / / 0x42
readbytes(20);
set_parameters();
replyOK();
breken;
kast STK_SET_PARM_EXT: / / uitgebreid parameters - ignore voor nu
readbytes(5);
replyOK();
breken;
kast STK_PMODE_START: / / 0x50
Beep(2272, 20);
start_pmode();
replyOK();
breken;
kast STK_PMODE_END: //0x51
Beep(1912, 50);
fout = 0;
end_pmode();
replyOK();
breken;
kast STK_SET_ADDR: / / 0x55
_addr = getch() + 256 * getch();
replyOK();
breken;
kast STK_UNIVERSAL: //UNIVERSAL 0x56
Universal();
breken;
kast STK_PROG_FLASH: //STK_PROG_FLASH???
laag = getch();
hoog = getch();
replyOK();
breken;
kast STK_PROG_DATA: //STK_PROG_DATA???
gegevens = getch();
replyOK();
breken;
kast STK_PROG_PAGE: //STK_PROG_PAGE
Beep(1912, 20);
program_page();
breken;
kast STK_READ_PAGE: //STK_READ_PAGE
read_page();
breken;
kast STK_READ_SIGN: //STK_READ_SIGN
read_signature();
breken;
verwacht van een opdracht, niet CRC_EOP
Dit is hoe kunnen we terug in sync
Case CRC_EOP:
Serial.write(STK_NOSYNC);
breken;
iets anders komen we nog terug STK_UNKNOWN
standaard:
Als (CRC_EOP == getch())
Serial.write(STK_UNKNOWN);
anders
Serial.write(STK_NOSYNC);
}
}
pieptoon, zonder gebruik te maken van PWM
VOID pieptoon (int Toon, lange duur) {}
lang verstreken = 0;
terwijl (verstreken < (duur * 10000)) {}
digitalWrite (PIËZO, hoge);
delayMicroseconds(tone / 2);
digitalWrite (PIËZO, laag);
delayMicroseconds(tone / 2);
Bijhouden van hoe lang we gepulseerde
verstreken += Toon;
// }
//}