|
Starten met de ATtiny2313

Gerelateerde pagina's: AVR Butterfly demo board
met de ATmega, vuurvliegjes als een toepassing van
de ATtiny, en verder de ATtiny software en
hardware pagina's.
Probleemp: een I²C-chip (PCA9634) die ik graag als RGB
powerLED-controller wilde gebruiken (als uitbreiding voor mijn Rabbit, en om te spelen met I²C op mijn omgebouwde
NSLU2) is als hobbyist haast niet betaalbaar
verkrijgbaar, in ieder geval niet in een behuizing die soldeerbaar is; pootjes
minder als 1 mm apart ga ik niet zelf zitten hobbyen... Wat te doen? Kan ik dit
probleem op een andere manier oplossen?
Als ik nu eens een goedkope microcontroller neem, en zelf de functionaliteit
daarin programmeer? Flexibel, ook voor andere zaken inzetbaar, en effectief nog
goedkoper ook. Zo gezegd, zo gedaan? Wel, er komt natuurlijk wel een aantal
extra stappen bij kijken:
- De chip moet goed verkrijgbaar (en betaalbaar) en hanteerbaar zijn
- De chip moet voldoende mogelijkheden hebben; hier I²C slave en PWM
(Pulse Width Modulation) uitgangen
- Je hebt een programmer nodig
- Je hebt ontwikkeltools nodig, liefst C/C++
Lastige chips zijn wel te bestellen, maar wel met forse bestel- en
verzendkosten (20..30€) etc. Een mogelijke leverancier voor wat ik zocht
is DigiKey; die leveren ook aan
particulieren. Alleen, de behuizing die ik zocht was er niet, en een
TSSOP20-behuizing is mij te klein...
Al met al is de keuze gevallen op de Atmel ATtiny2313. Een goed
verkrijgbare microcontroller met FLASH geheugen, in een eenvoudig verwerkbare
20-pins DIL behuizing. Online gekocht, bij Conrad €2.14 (#154166-89); voor iets meer geld
heb je bijvoorbeeld de ATmega ATMEG8535-16PU met 8-kanaals A/D etc (#154257-89,
maar was voor mij niet nodig; ooit in een ander project?). Veel informatie op
internet. Past zo op de standaard gaatjesprint die ik gebruik voor
prototypen.
Een AVR-programmer voor de seriële poort is zo gemaakt, en de tiny2313
is 'in-circuit'-programmeerbaar, dus je hoeft de chip niet eens uit je
schakeling te halen om de functionaliteit te veranderen.
De Atmel
ATtiny2313
De ATtiny2313 is (als opvolger/vervanger van de
AT90S2313) een prima AVR microcontroller voor beginners. Een overzichtje van de
eigenschappen en functies van de ATtiny2313; zie ook de uitgebreide
documentatie in de
datasheet (PDF 2MB):
- 8-bit AVR architectuur (1..2 cycles/instruction; Harvard memory arch)
- 2kB flash programma geheugen, 10.000x schrijfbaar
- 128 bytes ram geheugen
- 128 bytes eeprom geheugen, 100.000x schrijfbaar
- Seriële poorten, timers, counters, etc
- 4 PWM kanalen (Puls Breedte Modultatie)
- I²C (TWI) slave en master mogelijkheid
- 20 pins, waarvan 18 als I/O te gebruiken
- maximaal 20 miljoen instructies per seconde bij een 20MHz klok
- interne oscillator, geen extern kristal noodzakelijk (maar kan
wel)
- Voeding 2.7 (1.8 voor V versie) tot 5.5V, dus werkt ook op twee
batterijen
De
programmer
De
programmer-componenten
1x Sub-D connector, 9-polig
3x weerstand 4K7
1x weerstand 10K
1x weerstand 33K
1x transistor BC549C
1x diode 1N4148
2x zener 5V1
1x 20-polig IC voetje
1x condensator 0.1 uF
1x condensator 33 uF/16V
1x 3-polige header
1x 2x5-polige header
gaatjesprint met eilandjes
Ik heb gekozen voor een low-cost programmer voor gebruik met een
seriële poort. Erg low-cost (denk minder dan € 10, en geen IC's
nodig); volgens het web veiliger voor de computer dan de parallelle poort
uitvoering, en zo in elkaar te zetten met standaard verkrijgbare onderdelen; in
een uurtje had ik mijn programmer compleet.
Mijn versie is gebaseerd op het schema van de seriële programmer
AVR
programmer Olimex AVR-PG1, en de vergelijkbare AVR programmer van
electronics-diy. Paar kleine modificaties, met name haal ik de 5 Volt uit
de USB-poort van mijn laptop, dus een USB-kabeltje gehalveerd en hiervan de
ground en +5V aangesloten op de 3-polige header, zodat de tiny2313 voeding
heeft en ook zonder seriële kabel programma'tjes kan uitvoeren. En ik heb
naast de 2x5-pins ISP (In-System Programming) header een
20-polig IC-voetje geplaatst (Vcc op pin 20, GND op pin 10, reset pin 1, etc),
kan dus zowel losse 2313's als bordjes met ISP (in-system programming)
programmeren. Zie de foto hieronder, met al een ATtiny in het 20-pins voetje
(opmerking: enkele SMD-weerstanden zitten aan de onderkant).

Deze programmer is zowel compatible met de avrdude software
als met de PonyProg software (zie
bij 'De Tools'). De programmer is ook gelijk een mini-applicatiebordje, in de
zin dat programma's er ook gelijk kunnen draaien; zie bijvoorbeeld 'Het eerste
programma'tje' verderop.
De Tools
AVR met
Linux: aanpassen
Om GCC en avrdude
onder Linux werkend te maken was even tricky. avrdude in combinatie met
een trage (128 kHz low power) clock van de ATtiny draaide voor mij te
snel onder Linux (windows was OK), en
ik moest de -i 40 parameter toevoegen. O ja, en -P
/dev/ttyS0 ipv -P com1
Ook de Code::Blocks configuratie
was niet optimaal voor avrdude, voeg -R .fuse -R .lock -R
.signature toe in de build options: pre/post build steps, eerste
avr-objcopy commando.
Verder heb ik standaard de volgende compiler-opties toegevoegd:
-gdwarf-2 -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct
-fshort-enums
Wil je een .lss file, voeg dan aan de pre/post build steps toe:
avr-objdump -h -S $(TARGET_OUTPUT_FILE) >
$(TARGET_OUTPUT_FILE).lss
Ik wil de tools kunnen draaien op een laptop met Windows XP, of Ubuntu
Linux. Daar ik liever niet in assembler programmeer (weer een andere
assembly-taal) ga ik voor C: de GCC compiler suite is ook verkrijgbaar
voor de 2313. Minimaal is nodig de WinAVR GCC omgeving, dit is de Windows
GCC C/C++ compiler voor de AVR processoren, met alle bijhorende tools
(Linux/Ubuntu: AVR-GCC .deb
packages). Een belangrijk onderdeel hiervan is de runtime library
AVR-libc, met uitgebreide AVR-libc documentatie en voorbeelden
(ook over bijvoorbeeld interrupts, mixen met assembler code, etc).
De hele AVR GCC suite is command-line gebaseerd (dus zo'n ouderwets DOS
boxje), gebruik je liever een complete grafische IDE, kijk dan naar de Atmel AVR
Studio 4 (Windows). Dit programma is gratis te downloaden (eerst het
programma, en dan de twee service packs, en in de goede volgorde installeren:
programma, dan SP1, dan pas SP2). Werkt samen met de GCC compiler, maar je kan
ook in assembler werken. Als alternatief, en óók onder
Linux, kan je de Code::Blocks
IDE gebruiken, heeft standaard ook de AVR configuratie in zijn templates (al
linkt'ie iets anders, waardoor de binary niet exact hetzelfde is als bij AVR
Studio).
Als je een programma gecompileerd hebt, moet je het ook in de 2313 zien te
krijgen, oftewel je hebt een tool nodig om met de programmer te kunnen praten.
Het eenvoudigst qua omgeving is om hiervoor avrdude te
gebruiken; meegeleverd in WinAVR. Wil je echter dit niet vanaf de command line
hoeven te doen, dan kan je ook PonyProg gebruiken, deze heeft een
vriendelijker grafische gebruikersomgeving. Ik heb het zelf overigens niet
gebruikt, gebruik alleen avrdude.
Meer info over de C compiler: zie de software tips
pagina.
Het
eerste programma'tje
De 'hello world' voor embedded systems is het laten knipperen
van een LEDje... Ik ben hiervoor uitgegaan van de Nederlandstalige intro
'Knipperende LED', waar
op de site behoorlijk wat over de tiny2313 wordt uitgelegd. Zeker lezen! Op de
programmer twee extra onderdelen geplaatst: weerstand 470 Ohm plus een rode
LED, en in serie aangesloten tussen Vcc en pin PD2 (pin 6 op het voetje): dus
anders dan in de tutorial! Dit omdat ik ook een extern kristal wil
kunnen gebruiken: deze wordt op pin 4 en 5 aangesloten, waar in de tutorial de
LED zit. Ook de source (bij mij knipper.c) dus even hierop
aanpassen...
Ik gebruik AVR Studio om te compileren; met 'F7' vertaal
je de hele boel. In de directory 'default' vind je de gegenereerde
files; de .hex file bevat de binary om in de chip te branden. de
.lss file bevat een uitgebreide listing, inclusief startup code.
AVR Studio doet een aantal stappen; de meest belangrijke is het
aanroepen van de compiler; hieronder (verkort) weergegeven om te laten zien met
welke opties vertaald wordt:
avr-gcc -mmcu=attiny2313 -Wall -gdwarf-2 -Os -std=gnu99
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
knipper.c
De -Os optimaliseerd voor grootte. Let op: na dit commando
volgt er nog een aantal commando's om de uiteindelijke hex file te maken; hier
niet weergegeven (doet AVR Studio voor je, maar wel van belang als je
zelf een .bat of een makefile wilt maken). Downloaden naar de chip
gaat met avrdude en de zojuist gemaakte seriële programmer:
avrdude -p t2313 -c siprog -P com1 -U flash:w:knipper.hex
En ja, het LEDje gaat na het downloaden vanzelf knipperen. Het hele
programma is 116 bytes (de grootte van de te downloaden binary, dus inclusief
libraries en opstartcode), niet slecht voor een heel C programma!
Losgekoppeld van de computer, en op een regelbare voeding aangesloten. Eens
kijken hoe ver ik de voeding kan laten dalen... Zelfs bij 1.33 Volt (de laagste
stand die ik haal) blijft de uitgang keurig op en neer gaan, al is door de te
lage spanning de LED al niet meer zichtbaar. Netjes, formeel is'ie maar vanaf
2.7 Volt gegarandeerd (en de V-versie vanaf 1.8V). Houdt in dat'ie ook op twee
oplaadbare batterijen werkt, handig voor een volgens project dat ik in
gedachten heb (soort vuurvliegjes gebaseerd op de zonnecel van zo'n oude
LED-tuinlamp).
Interrupts
Altijd handig om een gevoel van tijd te hebben, dus een interrupt-routine om
ticks te tellen is plezierig. De timers lopen toch al (vanwege de PWM), dus ik
gebruik timer 0 overflow om elke periode een interrupt te genereren. Met een 4
MHz kristal; prescaler op 8, en 256 ticks voor een PWM-ronde kom ik zo op een
PWM- en interrupt-frequentie van haast 2 kHz (4MHz / 8 / 256). In de
interrupt-routine gebruik ik dit (om te testen) om een LEDje te laten
knipperen; ziet er op de scope goed uit. Timer 0 instellen als pwm en in
TIMSK timer overflow interrupt aanzetten, en de globale enable
flag aanzetten met de sei() functie:
#include <avr/interrupt.h>
volatile int pwm_counter;
ISR(TIMER0_OVF_vect) // T0 interrupt service routine
{
PORTD ^= (1 << PD2); // toggle LED output at 1 kHz
}
...
// in main: timer0 as fast PWM, clear pwm output on match
TCCR0A = (1 << COM0A1) | (1 << WGM01) | (1 << WGM00);
TCCR0B = (1 << CS01); // timer0 prescale by factor 8
TIMSK |= (1 << TOIE0); // enable timer0 overflow interrupt
sei();
// global enable interrupts
...
De timer interrupt wordt uiteindelijk gebruikt voor onder andere het
geleidelijk aan- en uit-zetten van de leds, en het bijhouden van de real-time
klok.
De I²C (of TWI)
Atmel noemt I²C "TWI", Two-Wire Interface, om trade-mark issues
te voorkomen. Ik had gehoopt code van het Arduino project te kunnen gebruiken,
maar helaas: hardware is anders. De ATtiny2313 heeft een USI poort
(Universal Serial Interface), die meerdere standaarden — waaronder
I²C — aankan. Toch was er ook voor de tiny op internet wel wat te
vinden; twee projecten vond ik met name van belang (de Atmel eigen code uit de
app-notes werkt volgens fora niet altijd betrouwbaar, deze links hebben
bijgewerkte versies):
- Deze I²C
dimmer applicatie, waar een circulaire buffer voor communicatie
gebruikt wordt: handig als je een message-based protocol wilt. Overigens is
deze app ook een slimme manier om een 8-kanaals PWM te implementeren op de
ATtiny.
- Deze I²C
eeprom simulatie, die zich gedraagt als een seriële eeprom, dus
meer een memory-mapped manier van communicatie
Ben met de eprom-simulatie aan de slag gegaan; was het eenvoudigst hier een
register-gebaseerde interface á la PCA9634 mee op te bouwen. De code
deed niet helemaal wat er gezegd werd, heb wat kleine wijzigingen doorgevoerd,
zoals de merge van de send- en receive-buffer in een geheugenbuffer. De hele
code is minder dan 500 bytes, dus ik heb nog meer dan 3/4 over voor de
eigenlijke applicatie. Alle i2c-communicatie wordt in de interrupt afgehandeld;
het main program is een lege eindeloze loop.
Ook gezorgd dat de LED en een switch (met een weerstand van 1K, van PD3/pin
7 naar aarde) ergens in het "eprom"-geheugengebied zijn gemapped door in de
eindeloze loop van het 'main'-programma deze waarden heen en weer te
kopiëren van de I/O naar de geheugenbuffer waar de eeprom gesimuleerd
wordt. Ja, ik kan nu (vanuit de NSLU2) de LED
aan en uitzetten, en de schakelaar uitlezen (via de i2cset en
i2cget commando's)! I²C werkt. Ongeveer een week nadat
ik de onderdelen van de programmer binnenkreeg, toch netjes.
Ik ga overigens niet een 8-kanaals PCA9634 exact nabouwen (waarvoor de
dimmer-app een goed startpunt zou zijn); maar de extra intelligentie van de
tiny gebruiken voor een besturing op hoger niveau (commando's als ga in zoveel
seconden naar die helderheid); misschien dat dan een message-based protocol als
in de dimmer dan toch meer toepasselijk is. Bovendien (in verband met de
gevoeligheid van het menselijk oog) wil ik meer een logarithmische curve, en
daarvoor heb ik meer dan 8 (lineaire) bits nodig, zit aan 12 te denken... Maar,
dat wordt misschien nog wel eens een andere pagina.
Een krachtiger LED
Bij Conrad enkele power LEDs besteld,
rood/groen/blauw, per kleur ongeveer 1 Watt. Deze LEDs (181159-89; €14,14)
mogen per stuk 350 mA hebben (mits goed gekoeld, 188052-89), en dat is
wat veel voor de ATtiny. Met enkele low-cost HEXFETs IRL510 (162789-89; €
0,60) is het echter wel goed te doen.
Een simpel schema'tje geeft ook een stroombegrenzing,
zodat ongeacht de voedingsspanning de stroom binnen de veilige grenzen
blijft: als de spanning over R2 te hoog gaat, gaat T1 geleiden, en knijpt T2
dicht --> stroom wordt minder en de spanning over R2 daalt, evenwicht bij
ongeveer 0.63V. Let op, als de FET in stroombegrenzingsmode werkt, valt er wel
spanning over (gaat als weerstand werken), en dissipeert hij dus ook vermogen:
bescheiden koelplaatje is nodig! Bij de gegeven waardes, en de blauwe LED (3.5V
spanning, x2) op 350 mA staat er 2.9V over R3, en dus 1.45V over de FET -->
0.5W (en 1W over R3), bij de rode LED (2.5V, x2) meer: 3.45V resp. 1.2W over de
FET.
De ingang is compatible met de ATtiny op 5 Volt, en aangesloten op de
PWM-uitgangen op pin 14..16 (3 FETs in totaal, dus). Dit geeft een lamp met
behoorlijke lichtopbrengst, en instelbare kleur en helderheid.
Een eerste testprogramma'tje is gebaseerd op een RGB-LED tutorial, hierin wordt
gedemonstreerd hoe je de pulsbreedte modulatie (PWM) gebruikt. Er zijn voor mij
enkele kleine aanpassingen nodig: de driver-trap zoals geschreven gedraagt zich
als een inverter, dus uit → aan, en omgedraaid. De 2313 heeft in zijn
configuratieregisters bits om de uitgang om te draaien (zie b.v.
COM0A1), daarmee gedraagt het programma zich zoals gewenst.
En
verder...
Ben nog met wat extra zaken bezig, zoals een low-cost AD conversie op de
ATtiny; zie meer op mijn ATtiny Hardware Tips
pagina... En tips over de software/debug kant op de software tips pagina.
Plus: Een ongesorteerde dump van mijn bookmarks over de AVR:
Algemeen:
Programmers:
Onderdelen nodig?
|