ATtiny Hardware Tips
Kant-en-klare bordjes met AVR processor? Kijk eens op de Arduino pages; is een uitgebreide
gebruikers-community bij. Leuk bordje is bijvoorbeeld de Arduino Duemilanove
(wel krachtiger dan de ATtiny).
Deze pagina is een vervolg op mijn Starten met de
ATtiny2313 pagina... Het behandelt een aantal tips en trucks aan de
hardwarekant voor mensen die met de 2313 willen werken (en dient eigenlijk
voornamelijk als naslagwerk voor mezelf). Voor software/debuggen zie de
ATtiny Software (en debugging) Tips.
Onderwerpen op deze pagina:
Geen garanties, maar hopelijk heeft naast mezelf nog iemand er iets aan.
Fuse programming vanuit je C source, of met
AVRDUDE
Naast het programmageheugen heeft de tiny2313 nog meer programmeerbare
delen; met name de fuses voor het instellen van de verschillende modes (zoals
welke klok te gebruiken). Die fuses zijn vaak wat raadselachtig (zo is
'programmed' een 0, en 'cleared' een 1), maar gelukkig is er op het net wel wat
uitleg verkrijgbaar; zo is er bijvoorbeeld de fuse calculator, welke de fuse waardes
netjes uitrekent aan de hand van je keuzes. Als je de waardes berekend hebt kan
je met avrdude deze programmeren. Pas op; een verkeerde waarde kan je
chip onbruikbaar maken (zeker als je alleen een seriële programmer hebt)!
Meer info ook op de AVR
Fuses HOWTO Guide (en natuurlijk in de datasheet).
Het is nuttig eerst eens de huidige waardes uit te lezen, met het commando
(serial programmer, windows resp. linux):
avrdude -p t2313 -c siprog -P com1 -U lfuse:r:-:h -U
hfuse:r:-:h -U efuse:r:-:h
avrdude -p t2313 -P /dev/ttyS0 -i 40 -c siprog -U hfuse:r:-:h -U
efuse:r:-:h
Enkele Fuse-settings
Default 8MHz / 8: Low=0x64 , High=0xFD ,
Ext=0xFF
Extern 4 MHz Xtal: Low=0xFD
Internal 128 kHz clock (low power): Low=0xE6
Watchdog & brownout@2.7V: High=0xCB
Dit levert bij mij de waarden op (even zoeken in de output): low fuse
0x64 , high fuse 0xdf , extended fuse
0xff . Dit zijn de standaard fabriekswaarden (interne RC
oscillator, etc). Ik wil de processor op het kristal laten lopen (extern
kristal, 4 MHz, geen deling door 8); dit levert een low fuse waarde op
van 0xfd . De high fuse en extended fuse kunnen ongewijzigd
blijven! Commando (hier met de usb programmer; -c usbasp ):
avrdude -p t2313 -c usbasp -U lfuse:w:0xfd:m
En ja, programmer uitgebreid met een 4 MHz kristal en 2 stuks 22 pF
condensatoren, en mijn ledje knippert nu 4x sneller (in plaats van de 1 MHz
interne RC-klok, de 4 MHz kristalwaarde). Zoals gezegd: een verkeerde fuse
waarde kan je chip onbruikbaar maken; altijd dubbel-checken!!!
Fuses in je C programma
Je kunt ook de waarde van fuses in je programma (en daarmee direct in je
binary files) opnemen, zodat deze informatie in de bijhorende source en
.elf file staat en niet verloren gaat als je je kladblaadje per
ongeluk weg gooit, en ze bovendien automatisch op de goede manier
meegeprogrammeerd worden. Dit gaat (op een wat primitieve manier, de fuse calculator blijft nodig om te
checken of je het goed hebt) met behulp van de avr/fuses.h include
file en een door jezelf in je C file op te geven configuratie,
bijvoorbeeld:
#include <avr/io.h>
#include <avr/fuse.h>
FUSES = // specified bits will be zeroed...
{ // select 128 kHz internal
oscilator with slow start
.low = (FUSE_CKSEL0 & FUSE_CKSEL3 &
FUSE_SUT0), // 0xE6
.high =
HFUSE_DEFAULT,
// 0xFD
.extended =
EFUSE_DEFAULT,
// 0xFF
};
Je kunt de waarde van de fuses uitlezen uit de .elf file met
behulp van het commando avr-objdump -s -j .fuse
<filenaam>.elf . Helaas, de waardes worden nog niet
automatisch door AVRDUDE geprogrammeerd (staan niet in de
.hex file), dit moet je nog steeds 'handmatig' doen (zie
hierboven)...
Low-cost zero-CPU-load analog-to-digital
converter
De ATtiny2313 heeft zelf geen A/D-converter. In de
applicatienote AVR401: 8-bit
precision A/D converter van Atmel staat wel hoe er met de analoge
comparator er zelf een te maken is, maar deze was mij te complex (ook qua
software). Ik heb zelf een gestripte versie gemaakt met de volgende
voordelen:
- Minimaal aantal onderdelen: een low-cost transistor, twee weerstanden en
een condensator
- Gebruikt slechts twee pinnen op de ATtiny2313 (pin 12 en 13)
- Minimale software; slechts een extra instructie in de timer interrupt
routine (plus enkele initialisatie-instrucies)
- Bereik praktisch 0.1 .. 4.9 Volt (bij 5 Volt supply)
- Minimaal energiegebruik
Het principe is eenvoudig (zie schema 1 en ook de app note):
de te meten spanning wordt op pin 12 (AIN0) aangeboden. Op pin 13 (AIN1) wordt
een lineair stijgende spanning gemaakt: met behulp van een constante stroom
(als ingesteld door de transistor Q1 en weerstand R2) wordt een condensator C1
opgeladen. Op hetzelfde moment is een timer gestart. Op het moment dat de
spanning op de condensator dezelfde is als de spanning op de meet-ingang wordt
de waarde van de timer in het timer capture register ingeklokt; dit is de
gemeten waarde.
Na een vaste tijd wordt de condensator leeggemaakt (in
ongeveer 20 µs), door pin 13 van de ATtiny2313 tijdelijk als output met waarde
0 te configureren (met de weerstand R1 als stroombegrenzer), en kan de cyclus
opnieuw beginnen. Het geheel loopt op Timer1 die ik toch al had lopen voor
andere taken (met name de PWM outputs, klok op 4 MHz/8 dus ~2 kHz PWM); kost
dus geen extra resources. Het enige extra is een instructie in de interrupt
routine die pin 13 van input (meten) naar output met waarde 0 (ontladen)
schakelt, en weer terug (toggle: DDRB ^= _BV(PB1); ). OK, niet
helemaal zero-CPU-load, maar enkele instructies elke 500 µs (2 kHz) is
verwaarloosbaar.
Op de meet-ingang wel nog wat onderdelen om deze te beschermen tegen te hoge
spanningen en zo; of dit nodig is hangt af van je toepassing (schema 2, zener
is 5.1 Volts).
Voor de precieze waarde van de condensator moet je wat experimenteren,
afhankelijk van je timing, en met name de kwaliteit van je condensator en van
de gebruikte transistor, waarvan de versterkingsfactor (en daarmee de stroom)
niet voor elke transistor dezelfde is...
De meetwaarde is uit te lezen uit het Timer/Counter 1 capture
register, ICR1L . De waarde wordt elke milliseconde bijgewerkt (1
kHz sample frequency). De meting is gekoppeld aan de voedingsspanning, ideaal
voor weerstand-gebaseerde sensoren; maar calibratie is eventueel ook mogelijk:
schakel de AIN0 input van de comparator naar de interne referentiespanning
(1.1V) en meet deze; dit geeft je een schaalfactor. De ondergrens is niet
helemaal 0 Volt, omdat de condensator niet helemaal leeg raakt (blijft een
kleine laadstroom lopen, ook tijdens het ontladen, geeft een ondergrens van
ongeveer 1 mA x 100 Ohm = 100 mV).
Initialisatie voor A/D conversie (exclusief de PWM-initialisatie op 2
kHz fast mode):
// Timer initialisation for PWM not shown
// TIMER 1 ADconv: noise filter, neg edge
TCCR1B |= (1 << ICNC1) | (0 << ICES1);
// ACO: output of comparator; ACIC enable timer capture; ACIS:2 -> pos
edge
ACSR = (1 << ACO) | (1 << ACIC) | (1 << ACIS1) | (0 <<
ACIS0);
// only use as analog input; disable digital input (power reduction)
DIDR = (1 << AIN1D) | (1 << AIN0D);
Simpel, niet?
HomeNode met simpel LCD display
Onderdeel van mijn home control system: een simpele ATtiny
gebaseerde node die een aantal sensoren en schakelaars bestuurd. Het prototype
hiernaast hangt met een flatcable aan de USBasp programmer (rechts, aangesloten
op een USB hub), en aan een LCD display. Op de print daarnaast nog wat headers
voor I2C en solid state relais; plus natuurlijk de blauwe 3-pin connector voor
aansluiting aan het netwerk. Meeste passieve componenten zitten als
SMD-onderdelen aan de onderkant van het printje.
De node heeft de mogelijkheid om een simpel LCD aan te sluiten; zie plaatje.
Het gaat hier om een simpel 2x16 display (hier LCM-S01602DSR) dat in allerlei
uitvoeringen vrij goedkoop te krijgen is (in allerlei maten, 2x16; 2x20, 4x20,
etc). Aansluiting is mogelijk via slechts zes draadjes plus de 5 Volt voeding:
4 datalijnen, een command/data selectielijn en een write puls. Heb je meer
pinnen beschikbaar dan kan het wat efficienter, bijvoorbeeld via een 8-bits
databus en een read/write select (totaal 11 draadjes, plus voeding).
Al deze displays maken gebruik van dezelfde compatible controllers (vaak de
HD44780U),
dus de software is herbruikbaar voor allerlei types. Ik maak gebruik van de
code van Donald Weiman, die
verschillende uitvoeringen op zijn site heeft staan. Hiernaast op het scherm
zijn testprogramma (aangepast voor de ATtiny HomeNode door de pinnummers te
wijzigen; tekst aangevuld met "/KM" zodat ik kon zien dat het mijn aangepaste
software was).
Let op: voor de Arduino zijn er vergelijkbare display te vinden, die echter
via een ingebouwde converter met I2C aangestuurd worden (nog minder pinnen maar
trager). Zijn niet compatible met de software van Donald!
Stroomgebruik in een werkelijke
schakeling
In mijn vuurvlieg-project (een batterij- en
zonnecel-gevoed ontwerp) heb ik eens de stroom gemeten. De details zijn
verhuisd naar de vuurvlieg-pagina...
|