Demonstrator av vinkelgivare
Examensarbete 15hp
Elektronik
Eskilstuna Elektronik Partner AB, EEPAB
Akademin för Innovation, design och teknik, IDT
Mälardalens högskola
Författare: Jonne Kivinen
Handledare: Mikael Joki, VD (EEPAB)
Handledare/ Examinator: Magnus Otterskog, MDH
Datum: 2009-09-09
Sammanfattning
Eskilstuna Elektronikpartner (EEPAB) är ett elektronikföretag som tillverkar vinkelgivare till
bland annat kranar som är monterade på lastbilsflak.
För att EEPAB på ett intressant sätt ska kunna demonstrera sin produkt på mässor har en
demonstrator tagits fram. Denna demonstrator består av en fjärrstyrd grävmaskin och en
elektronikenhet, som hanterar den analoga signalen från vinkelgivaren. Resultatet, som är
vinkelgivarens lutning i grader, presenteras på två sjusegmentdisplayer som är placerade på
grävmaskinens bägge sidor. Vinkeln skickas även trådlöst från elektronikenheten, via
Bluetooth, till en PC. Grävmaskinens batteri (7,2V) strömförsörjer all hårdvara, vilket gör att
demonstratorn är helt portabel.
Denna rapport beskriver block för block de olika programfunktioner samt hårdvara, som
behövs till en färdig och fungerande demonstrator.
Abstract
Eskilstuna Elektronikpartner (EEPAB) is an electronics company located in Eskilstuna that
produces angle sensors to, for instance, cranes mounted on truck beds.
For EEPAB to be able to demonstrate their product on fairs in an interesting way, a
demonstrator has been made. The demonstrator consists of a remote controlled excavator and
an electronic unit which handles the analog signal from the sensor. The result, which is the
angle of the sensor in degrees, is presented on two sevensegment displays that are placed on
both sides of the excavator. The angle is also sent wirelessly from the electronic unit via
Bluetooth to a PC. The battery of the excavator powers all of the hardware, making the
demonstrator fully portable.
This thesis report describes the various programfunctions and hardware, part by part,
necessary for a complete and functioning demonstrator.
2
Innehållsförteckning
Sammanfattning ...........................................................................................................................
Abstract ........................................................................................................................................
1 Inledning.................................................................................................................................. 5
1.1 Bakgrund .......................................................................................................................... 5
1.2 Syfte ................................................................................................................................. 5
1.3 Problemställning............................................................................................................... 5
1.4 Verktyg ............................................................................................................................. 5
2 Kundkravspecifikation ............................................................................................................ 5
3 Teori ........................................................................................................................................ 6
3.1 Vinkelgivare ..................................................................................................................... 6
4 Design...................................................................................................................................... 7
4.1 Hårdvara ........................................................................................................................... 7
4.1.1 Strömförsörjning ....................................................................................................... 7
4.1.1.1 12V Step up-regulator ........................................................................................ 7
4.1.1.2 5V Spänningsregulator ....................................................................................... 8
4.1.2 Vinkelgivare .............................................................................................................. 9
4.1.3 Mikrokontroller ......................................................................................................... 9
4.1.3.1 Interface mikrokontroller ................................................................................... 9
4.1.3.2 UART ............................................................................................................... 11
4.1.4 Blåtandsmodul ......................................................................................................... 11
4.1.5 Display .................................................................................................................... 12
4.2 Mjukvara ........................................................................................................................ 12
4.2.1 Initieringsfunktioner ................................................................................................ 13
4.2.2 Main-funktion.......................................................................................................... 13
4.2.3 Display-funktion...................................................................................................... 13
4.2.4 Omvandlings-funktion ............................................................................................ 13
4.2.5 Timer ....................................................................................................................... 14
4.2.6 Läsning av ADC ...................................................................................................... 15
4.2.7 Nollställning av vinkel ............................................................................................ 16
4.2.8 Power ON/OFF ....................................................................................................... 16
4.2.9 Fördröjning .............................................................................................................. 16
4.2.10 UART-funktioner .................................................................................................. 16
4.2.10.1 Print-funktion ................................................................................................. 17
4.2.10.2 RX-interrupt ................................................................................................... 17
4.2.10.3 TX-interrupt ................................................................................................... 17
5 Verifiering ............................................................................................................................. 17
5.1 Testning .......................................................................................................................... 17
5.2 Testning av elektronikenhet ........................................................................................... 17
6 Implementering ..................................................................................................................... 18
7 Resultat och diskussion ......................................................................................................... 19
8 Slutsats .................................................................................................................................. 20
9 Referenser.............................................................................................................................. 21
10 Bilaga A - Flödesscheman................................................................................................... 22
11 Bilaga B - Programkod ........................................................................................................ 25
12 Bilaga C - Kretsscheman ..................................................................................................... 30
13 Bilaga D – Datablad ............................................................................................................ 33
3
Förkortningar
ADC
Analog-to-Digital Converter
CA
CAD
JTAG
LED
LSB
MEMS
MS
MSB
UART
Common Anode
Computer-Aided Design
Joint Test Action Group
Light Emitting Diode
Least Significant Bit
Micro-Electro-Mechanical Systems
Microsoft
Most Significant Bit
Universal Asynchronous Receiver/Transmitter
4
1 Inledning
1.1 Bakgrund
Detta projekt är ett förslag från två olika företag från Eskilstuna - Eskilstuna Elektronik
Partner AB (EEPAB) och minST. Elektronik Partner är ett företag som erbjuder
helhetslösningar från en idé till en färdig produkt och minST ett företag, som bland annat
hjälper små och medelstora företag att, genom samarbete, utveckla sina egna produkter med
ny teknik.
EEPAB tillverkar bland annat vinkelgivare. Dessa givare är avsedda för att mäta lutning hos
kranar som till exempel är monterade på lastbilar, för att lasta och lossa av gods från flaket.
Eftersom inga riktiga kranar finns tillgängliga för projektet, samt att det är opraktiskt att
behöva ha en kran som är stor och som tar mycket plats, så används en radiostyrd grävmaskin
till att påverka givaren. En av de första uppgifterna i detta projekt var således att hitta en
lämplig demonstrator för vinkelgivaren. Grävmaskinen som valdes är gjord i plast. Det
faktum att den inte väger mycket gör att den lätt att transportera. Den är 74 cm lång, 49 cm
hög och 22 cm bred – vilket gör att den är tillräckligt stor för att synas. Grävmaskinen kan
köras framåt, bakåt, till höger och vänster. Skopan kan köras upp och ner. Detta gör att den
fungerar utmärkt som en demonstrator för vinkelgivaren.
1.2 Syfte
Syftet med projektet, demonstrator av vinkel, är att EEPAB på ett enkelt och intressant sätt
ska kunna visa upp sin produkt (vinkelgivare), inför en publik på mässor eller liknande
tillställningar, med dess unika funktioner. I detta projekt är det främst lutningen i grader, som
ska demonstreras.
1.3 Problemställning
Uppgiften i detta arbete är att kunna ta emot en analog signal från vinkelgivaren, som anger
lutningen, och använda signalen i ett program för att sedan kunna presentera den på en
sjusegmentdisplay. En ny elektronikenhet konstrueras för att uppnå detta. Resultaten, som
skickas via Bluetooth, ska även kunna hanteras av en PC.
1.4 Verktyg
Programmeringsmiljöerna som använts i detta projekt är Dev-C++, där de första
testprogrammen skrivits, samt IAR Embedded Workbench, som använts för att skriva de
slutliga programmen. AVR Studio 4 har använts för testning och debugging samt LTspice för
simulering av elektronikkretsar. Även ett JTAG-interface användes i debugging.
2 Kundkravspecifikation
Allmänt



Aktuell vinkel ska presenteras på två parallellt inkopplade LED-displayer som ska
bestå av gröna enkelradiga 4x7-segmentdisplayer med en teckenhöjd på minst
25mm.
Vinkeln som visas ska vara mellan -185° och 185°.
Elektronikenheten ska strömförsörjas från samma batteri som grävmaskinen.
5



En intern spänning på minst 10V måste genereras från batterispänningen för drivning
av vinkelgivarna.
Via en switch (digital ingång) ska det vara möjligt att nollställa aktuell vinkel.
Vinkeln ska kunna läsas av via Bluetooth för att kunna hanteras av en PC.
Kretslösning



Ett kretskort ska tas fram som hanterar alla in- och utsignaler med hjälp av en
mikrokontroller.
Om det inte går att hitta en färdig LED-display (4x7-segment, höjd>25mm) ska ett
separat kretskort tas fram för detta.
EEPAB hjälper till med CAD av mönsterkort.
3 Teori
3.1 Vinkelgivare
Vinkelgivaren som används är baserad på MEMS-teknik och innehåller två accelerometrar.
Dessutom har den en mikrokontroller som bland annat är programmerad till för att filtrera
bort periodiska lågfrekventa svängningar.
Accelerometrar känner av acceleration med gravitationen som referens. Vinkelgivaren som
används har en accelerometer i både x- och y-led.
En accelerometer fungerar som en massa på en fjäder, se Figur 1. När en extern kraft, i detta
fall gravitationskraften, påverkar accelerometern förflyttas massan tills det råder en balans
mellan gravitationen och fjäderkraften. Därefter omvandlas förflyttningen till en acceleration.
Nya accelerometrar är, för det mesta, mikro-elektro-mekaniska system (MEMS) som bland
annat innehåller en konsolbalk och en (seismisk) massa, se Figur 2. När gravitationskraften
påverkar accelerometern avviker massan ur sitt neutrala läge och denna avvikelse kan sedan
mätas antingen på ett analogt eller digitalt sätt [1].
Figur 1. Accelerometerns funktionsprincip
6
Figur 2. En typisk MEMS-acceleometer
4 Design
4.1 Hårdvara
Hårdvaran kan delas upp i fem olika block: strömförsörjning, vinkelgivare, mikrokontroller,
display och blåtandsmodul, se Figur 3.
Strömförsörjning
Vinkelgivare
Display
Microcontroller
Blåtand
Figur 3. Blockdiagram för hårdvaran
4.1.1 Strömförsörjning
På grund av att demonstratorn är en fjärrstyrd grävmaskin, strömförsörjs allting från
grävmaskinens batteripack (7,2V). Detta är ett krav från kunden som vill kunna använda
demonstratorn vid presentationstillfällena på ett så enkelt och smidigt sätt som möjligt.
4.1.1.1 12V Step up-regulator
I detta projekt används en step up-regulator (LM2577) för att ge vinkelgivaren och displayen
tillräcklig matningsspänning. Denna regulator ”boostar” batterispänningen upp till 12V, vilket
är en bra nivå för vinkelgivaren då den fungerar med 10 - 30V matningsspänning.
Med denna krets behövs endast få externa komponenter för att åstadkomma den önskade
spänningsnivån. Exempel på hur man kopplar regulatorn med dess externa komponenter, i
7
olika applikationer, ges i databladet (se Bilaga D – 13.4). Kopplingen som används är tagen ur
exemplen. Med 5V inspänning kan 12V utspänning levereras, se Figur 4, men i detta projekt
matas regulatorn med 7,2V.
Figur 4. Kopplingsschema för step up-regulatorn
4.1.1.2 5V Spänningsregulator
Denna spänningsregulator (LM2734) används till att reglera 12V spänningen till 5V.
Regulatorns min- och maxvärden för in- respektive utspänning, enligt databladet (se Bilaga D
– 13.3), visas i Tabell 1 nedan.
Tabell 1. Användningsområdet för LM2734
Både mikrokontrollern och blåtandsmodulen matas med 5V spänning. Matningen till
mikrokontrollern får enligt databladet, se Bilaga D – 13.1, matas med högst 6V spänning,
därför måste spänningsregulatorn användas, se Figur 5. Annars riskerar man att förstöra
mikrokontrollern.
Figur 5. Design för 5V-spänningsregulatorn
8
4.1.2 Vinkelgivare
Signalen som givaren ger ut är en ström som varierar mellan 4mA och 20mA beroende på
lutningen. Denna ström måste omvandlas till en spänning för att kunna A/D-omvandlas. Detta
görs med en differetialförstärkarkoppling, se Figur 6. Signalen (strömmen) kommer från den
mellersta kontakten (GIVARE1) och spänningen kommer ut efter operationsförstärkaren
(LM2902), som är kopplad till mikrokontrollern.
Figur 6. Differentialförstärkare för signalen från vinkelgivaren
Vinkelgivaren kan matas med 10 - 30V men i detta projekt har det valts att mata den med
12V. Givaren innehåller även en regulator som ser till att strömmen alltid är 4 - 20mA,
oberoende med vilken spänning den matas med, då matningsspänningen är 10 - 30V.
4.1.3 Mikrokontroller
I detta projekt används Atmels Mega128. Detta var ett val från EEPAB:s sida. En
mikrokontroller med mindre funktioner hade räckt, men Atmels Mega128 valdes för att
EEPAB ville lägga till egna finesser för en slutprodukt med fler användningsmöjligheter.
För programmering av ATMega128 kan programmeringsspråken Assembler och C användas.
Eftersom C används på EEPAB så används den även i detta projekt.
Microkontrollern används bland annat för att A/D-omvandla en signal samt skicka ut resultat
till både displayer och en PC.
4.1.3.1 Interface mikrokontroller
Inportar


PORTD6 från SWITCH1
PORTD7 från SWITCH2



PORTF0 (ADC0) från GIVARE1
PORTF1 (ADC1) från GIVARE2
PORTF2 (ADC2) från GIVARE3
Utportar

PORTA0 till segment ”DP”
9







PORTA1 till segment ”G”
PORTA2 till segment ”F”
PORTA3 till segment ”E”
PORTA4 till segment ”D”
PORTA5 till segment ”C”
PORTA6 till segment ”B”
PORTA7 till segment ”A”




PORTC0 till CA pinnen i DISP1
PORTC1 till CA pinnen i DISP2
PORTC2 till CA pinnen i DISP3
PORTC3 till CA pinnen i DISP4



PORTE0 till RXD0 (Bluetooth)
PORTE1 till TXD0 (Bluetooth)
PORTE5 till Battery-Hold
Figur 7. Illustration av I/O-portar för ATMega128
Analoga ingångar:
In i dessa ingångar kommer en spänning på ca 0,86 - 4,26V som ska A/D-omvandlas. En 5V
(uppmätt 4,92V) extern referensspänning används. Resultatet som fås efter A/Domvandlingen hanteras sedan i programmet.
Digitala ingångar för switchar:
Det finns två digitala ingångar tillgängliga för switchar. Med den ena switchen (switch 1) kan
programmet stoppas och sedan startas. Med den andra (switch 2) kan den aktuella vinkeln
nollställas.
Digitala utgångar till segmenten:
Denna port, PORTA, är kopplad till de åtta segmenten på 7-segmentdisplayen, som visar den
aktuella lutningen. Punkten ”DP” är kopplad men används inte för mina ändamål.
Digitala utgångar till CA på displayen:
Dessa utgångar är kopplade till de gemensamma anoderna på 7-segmentdisplayen. Syftet med
dessa signaler är att styra vilka av de åtta displayen som ska lysa.
Digital utgång för Battery-Hold:
För val av batteripack som spänningskälla måste en hög signal skickas från pinne 5 på
PORTE.
10
Portar för UART:
Med hjälp av dessa portar skickar man information från elektronikenheten till en dator, via
Bluetooth.
4.1.3.2 UART
UART är en hårdvara som sekventiellt skickar data bitvis till en annan hårdvara som också
har UART. Mottagaren lägger sedan ihop datat till en hel byte igen.
Med UART kan mikrokontrollern kommunicera med, i detta fall, en blåtandsmodul. Det sker
genom att mikrokontrollern skickar data från sin Tx-port (transmitter) till blåtandsmodulens
Rx-port (receiver). Därefter svarar blåtandsmodulen genom att skicka tillbaka data från dess
Tx-port till mikrokontrollerns Rx-port.
För att mikrokontrollern och blåtandsmodulen ska kunna kommunicera, måste samma
inställningar sättas till bägge hårdvarorna för UART-interfacet. I detta projekt används
följande inställningar:




Baud rate: 9600
Data bits: 8
Paritet: none
Stop bit: 1
UART-interfacet används i detta projekt till för att skicka den aktuella vinkeln från
mikrokontrollern via blåtandsmodulen till en PC. Syftet med denna funktion är att kunna se
resultaten på en dataskärm, se Figur 8.
UARTinterface
Tx
Rx
Mikrokontroller
Blåtandsmodul
Rx
Bluetooth
Dongle
PC
Tx
Figur 8. Blockschema för funktion av UART och blåtand.
4.1.4 Blåtandsmodul
Blåtandsmodulen som används är en Ezurio BISM2 Bluetooth Version 2 Serial Module, se
Bild 1. Denna modul har valts på grund av att EEPAB använder den i sina applikationer,
därför används den även i detta arbete. Med hjälp av blåtandsmodulen kan data överföras till
en extern enhet, i detta fall en PC. Datat överförs trådlöst från modulen till en så kallad
Bluetooth dongle som sitter i PC:n, se Figur 8. Datat som skickas är grävskopans aktuella
vinkel.
11
Bild 1. Ezurio BiSMII Bluetooth Version 2 Serial Module
4.1.5 Display
För våra ändamål används gröna sjusegmentdisplayer (SA10-21GWA) med en teckenhöjd på
25,4 mm (vilket uppfyller kraven för höjd i kravspecifikationen). Dessa är av typen Common
Anode (CA) vilket betyder att lysdioden i segmenten är kopplade så att de har en gemensam
anod. Segmenten i denna display består av två lysdioder.
För att kunna visa en vinkel mellan -185° och 185° behövs tre siffertecken, samt ett tecken för
minus. I projektet behövdes 2x4 displayer som bildar två hela displayer – en på vardera sida
av grävmaskinen. Då inga tillräckligt stora sjusegmentdisplayer med fyra tecken hittades,
konstruerades ett display-mönsterkort. Därmed kopplades fyra separata sjusegmentdisplayer
parallellt för att uppfylla kraven.
För att visa en siffra på displayen tänder man de segment som bildar siffran, genom att skicka
en logisk etta från de utgångar, som är kopplade till respektive segment. Dessutom måste man
aktivera den displayen som man vill använda, genom att också skicka en logisk etta från
utgången som är kopplad till CA-pinnen på den aktuella displayen.
4.2 Mjukvara
Mjukvaran är modulärbaserad, detta innebär att programmet är uppdelat i flera olika separata
delar (block), se Figur 9. Varje del är placerad i en egen källkodsfil. Detta för att det ska vara
lättare att förstå programmet eftersom det är så pass stort.
Initieringar
Läsning av
ADC
UART
ADC till
grader
Main
Timer
Display
Kalibrering
Figur 9. Blockdiagram för mjukvaran
12
4.2.1 Initieringsfunktioner
För att göra main-funktionen så ”ren” och snygg som möjligt, användes egna funktioner för
initiering av I/O-portar, ADC, Timer0 och UART. Dessa initieras således med bara några
rader kod. I/O-portarna initieras så att de satisfierar interfacet för mikrokontrollern, Timer0
till att ge ett interrupt varannan millisekund och i UART möjliggörs användning av mottagare
och sändare samt receive interrupt.
4.2.2 Main-funktion
Main-funktionen består inte av så mycket kod eftersom den vill göras lättåskådlig. Den
innehåller initieringsfunktionerna samt en så kallad forever-loop. I forever-loopen anropas
funktionen som omvandlar ADC-värdet till ett antal grader och därefter skickar resultatet ut
till både displayen och PC:n. Detta forsätter tills programmet stängs av (se Bilaga A).
4.2.3 Display-funktion
Med denna funktion styrs vilken display som ska vara aktiverad, det vill säga lysa, och här
hanteras även utskrift av siffra.
Display-funktionen är designad så att entalssiffran av vinkeln först skrivs ut på första
displayen, sedan tiotalssiffran på andra displayen och slutligen hundratalssiffran på tredje
displayen. Dessutom skrivs ett minustecken ut på fjärde displayen om vinkeln är negativ.
I funktionen kommer vinkeln (talet) att gås igenom, i ordningen ental, tiotal, hundratal och
eventuellt minus-tecken, med hjälp av en loop som scannar varje tecken en efter en. För att se
en mer noggrann förklaring av funktionen, se Bilaga A (flödesschema) och Bilaga B
(programkod).
För utskrift av entalssiffran tas vinkeln modulus (%) 10. Till exempel om vinkeln är 123° tas
123%10 . 10 går 12 gånger i talet 123 och resten blir tre. Alltså skrivs det ut en trea. Därefter
divideras talet med 10 vilket resulterar i 12,3. Men eftersom programmet endast hanterar
heltal, blir siffran 12. Under nästa varv tas modulus 10 av talet igen och detta ger en tvåa. I
näst sista varvet, när division med 10 utförts, är talet 1,2, vilket blir en etta. Slutligen
kontrolleras om talet är negativt.
I programkoden finns en variabel (Sevenseg[]) som är ett fält med 10 element. När respektive
siffra skrivs ut används följande kodrad:
PORTB=SevenSeg[x];
Istället för x erhålls en siffra av de operationer som beskrivits tidigare i kapitlet, till exempel
123%10  3 . Trean är i detta fall x:et. Det som finns i det tredje elementet i variabeln blir då
utskrivet. I detta fall ”three”, som är definierad i koden. ”Three” motsvarar ett hexadecimalt
tal (0xF2) som tänder de segment på displayen som slutligen bildar siffran tre (se Bilaga B för
programkod).
4.2.4 Omvandlings-funktion
För att det ska vara möjligt att hantera något som ger ut en analog signal i ett program måste
den först analog-till-digital-omvandlas. Mikrokontrollern har en 10-bit ADC, som används för
detta. Omvandlingsvärdet, ADC-värdet, som enligt databladet för ATMega128, se Bilaga D –
13.1) fås ur följande ekvation:
ADC 
VIN  1024
(1)
VREF
13
där VIN är inspänningen och VREF är referensspänningen (uppmätt 4,92V).
Utspänningen från differentialsteget, efter vinkelgivaren, varierar mellan ca 0,86V och 4,26V
beroende på lutningen av givaren. Dessa värden motsvarar mininum (min) och maximum
(max) ström från givaren före differentialsteget, det vill säga 4mA respektive 20mA. Enligt
databladet för vinkelgivaren, se Bilaga D – 13.2, motsvarar 4mA en vinkel på -185° och
20mA vinkeln +185°. Dessutom motsvarar 12mA vinkeln 0°, se Tabell 2. Vinkelgivaren är
därför linjär.
VIN (V )
0,857
2,558
4,259
I GIVARE (mA)
4
12
20
Vinkel ()
-185
0
185
ADC
178,4
532,4
886,4
Tabell 2. Konverteringsfaser från ström till vinkel
När inspänningen sätts in i ekvation (1) erhålls motsvarande ADC-värde till spänningen,
vilket också blir linjärt. Därmed kan en ekvation beräknas ur dess lutning. Detta har gjorts
genom att rita upp en graf i MS Excel, med ADC-värdet på x-axeln och vinkeln på y-axeln, se
Graf 1. Följande ekvation erhålls ur lutningen:
y  0,5226  x  278,21 , där x är ADC (2)
y = 0,5226x - 278,21
250
200
150
100
50
0
0
100
200
300
400
500
600
700
800
900
1000
-50
-100
-150
-200
-250
Graf 1. Förhållandet mellan ADC-värdet och vinkeln
Eftersom en funktion för nollställning av vinkel används, behövs ekvation (2.) modifieras, se
kapitel Nollställning av vinkel. Den ser då ut på följande sätt:
y  0,5226  x , där x är ADC  offset (3)
I programkoden för själva omvandlingsfunktionen (ADC_To_Deg) används endast ekvation
(3). Därefter sparas resultatet i en variabel och returneras till slut, se Bilaga C för programkod.
4.2.5 Timer
Timern som används är Timer0. Den är en 8-bit Timer/Counter som räknar från 0 - 255. När
den har nått sitt maxvärde genereras ett interrupt, om användning av interrupt möjliggjorts.
14
Vid ett interrupt avbryts programmet och fortsätter sedan i en så kallad timer-interruptfunktion. När timer-interrupt-funktionen är exekverad återgår programmet till den plats där
interruptet skedde.
Med hjälp av räknare, som är gjorda med if-satser, och information om processorns
klockfrekvens kan fördröjningar av valfri storlek skapas.
I detta projekt används en extern klocka, en kristall, på 7,3728 MHz. Med följande ekvation
kan frekvensen av interrupten beräknas:
f clk
(4), där f clk är klockfrekvensen på kristallen, n är antalet bitar (8-bitar) på
2 N
Timer/Counter0 och N är storleken på prescalern1. För att uppnå ett bra resultat är faktorn
vald till 64 på prescalern. Med dessa parametrar instoppade i ekvation (4) fås frekvensen till
450 Hz, vilket betyder att interruptet sker ungefär varannan millisekund, som fås ur ekvation
(6):
f 
f 
n
1
1
1
 0,00222s , där T är periodtiden och f är frekvensen.
(5)  T 
(6) 
T
450 Hz
f
För att sedan bestämma fördröjningens längd (sekunder) kan räknarens maxvärde beräknas
med följande ekvation:
T  max värde  delay (7)  max värde 
delay
(8). Maxvärdet sätts sedan som villkor i ifT
satsen, se Bilaga C för programkod.
När interruptet sker kontrolleras om ADC-räknaren samt nollställningssräknaren har nått sina
maxvärden. Dessutom kontrolleras om displayräknaren nått sitt minimumvärde. Om inte,
kommer bägge räknarna att adderas med ett och den sistnämnda kommer att subtraheras med
ett. Därefter återgår man till main-funktionen.
4.2.6 Läsning av ADC
Läsning av ADC sker i timer-interrupt-funktionen men inte vid varje interrupt. För att
bestämma när läsningen sker används en egen räknare. Först när räknaren nått sitt maxvärde
sker läsningen.
När en A/D-omvandling är klar hittas resultaten i de två ADC data registren, ADCL (ADC
Low) och ADCH (ADC High), där ADCL är de åtta LSBn och ADCH de två MSBn av 10bitars resultat, se Figur 10. I denna funktion läses ADC-registret av i sin helhet och sedan
sparas resultatet i en variabel. Därefter startas en ny omvandling. Till slut nollställs räknaren
för att senare hamna i denna funktion igen, se Bilaga A för flödesschema och Bilaga B för
programkod.
Figur 10. ADC data registren ADCL och ADCH
Eftersom en analog-till-digital-omvandling bara tar 13 - 260 μs, enligt databladet för
ATMega128, se Bilaga D – 13.1, kommer siffrorna på displayen att ändras för snabbt för att
1
Prescalern dividerar klockfrekvensen med någon av följande faktorer: 8, 32, 64, 128, 256 och 1024.
15
det ska vara lättbegripligt. Ett sätt att hantera detta problem är att minska på frekvensen för
läsning av ADC-värdet. Tack vare att läsningen av ADC-värdet görs i timer-interruptfunktionen, är det möjligt att reglera frekvensen på avläsningen (i sekunder).
4.2.7 Nollställning av vinkel
Med denna funktion kan den aktuella vinkeln, som visas på displayen, nollställas. Detta görs
med ett knapptryck genom att hålla knappen nedtryck i två sekunder. Nollställningen sker
även i timer-interrupt-funktionen. Detta betyder att tiden som knappen ska vara nedtryckt kan
bestämmas, genom att välja ett lämpligt maxvärde för räknaren.
Nollställningen görs genom att en variabel (offset, i ekvation 3) tilldelas det aktuella ADCvärdet, då knappen varit nedtryck i rätt tid. På detta sätt förflyttas nollstället till det aktuella
ADC-värdet, vilket medför att y, som är vinkeln, i ekvation (3) blir noll. Slutligen nollställs
nollställningsräknaren, se Bilaga A för flödesschema och Bilaga B för programkod.
4.2.8 Power ON/OFF
För att kunna stänga av strömmen, och därmed spara batteri vid demonstrationstillfällena,
finns en switch som man kan slå av batteriet med.
Programmet startas då strömmen till demonstratorn slås på. När det är önskvärt att stänga
demonstratorn kan detta göras genom att hålla switch1 intryckt i tre sekunder. För att starta
programmet igen trycks switch1 in ytterligare en gång.
4.2.9 Fördröjning
För att segmenten i displayen ska lysa kraftigt, så att siffrorna syns ordentligt, måste de hinna
lysa en viss tid. Detta regleras genom att lägga en fördröjning efter att en display tänts.
Fördröjningen skapas även med hjälp av en räknare i timer-interrupt-funktionen. Om räknaren
inte har nått sitt minimumvärde kommer tändningen av display inte att ske, utan räknaren
minskas för varje gång som timer-interruptet sker.
4.2.10 UART-funktioner
UART-funktionerna Rx-interrupt och Tx-interrupt innehåller båda en cirkulär buffer, som är
ett fält med 128 element, se Figur 11. Där lagras ny data som sedan skickas vidare. Ny indata
kan därmed sparas samtidigt som utdata skickas iväg. Annars finns det en risk, att när data är
på väg att skickas ut och just då kommer data in, att man förlorar det inkomna datat.
Figur 11. Illustration av den cirkulära buffern
Rx-interrupt och Tx-interrupt har både en head och en tail. Både head och tail pekar på ett
element i respektive buffer. När nya tecken kommit in i Rx-buffern flyttas Rx-headen så långt
framåt som tecken kommit in, genom att ett nytt index för Rx-headen beräknas. Sedan skickas
ett tecken åt gången iväg och därefter beräknas ett nytt index för Tx-tailen.
16
4.2.10.1 Print-funktion
Denna funktion används för att skicka den aktuella vinkeln till PC:n. I funktionen tas vinkeln
som indata och skickas sedan till PC:n, genom att först konvertera den till en ASCII-sträng
och sedan skicka datat som finns i Tx-buffern. Detta görs med 0,3 sekunders mellanrum så att
resultaten på skärmen inte ändras för snabbt. Även denna funktion exekveras i timerinterrupt-funktionen.
4.2.10.2 RX-interrupt
I denna funktion läses UART data registret och datat sparas i en variabel. Därefter beräknas
ett nytt index för Rx-head och till slut sparas det mottagna datat i Rx-buffern. Om head och
tail är lika, det vill säga att det inte finns några nya tecken, görs ingenting.
4.2.10.3 TX-interrupt
Här kontrolleras först om all data skickats. Om det fortfarande finns data kvar i Tx-buffern,
startas sändningen. Därefter beräknas ett nytt index för Tx-tail. Om all data är skickat, görs
ingenting.
5 Verifiering
5.1 Testning
Testandet påbörjades redan i en tidig fas. Detta skedde i form av simuleringar av olika
elektronikkretsar i programvaran LTspice och i programmet Circuit Simulator Applet [2],
som kan användas gratis på Internet. Det var främst för simuleringar av signalen från
vinkelgivaren för att se att man får ut en rätt slags utspänning från
differentialförstärkarkopplingen. Justeringar gjordes på resistorvärden på diff.kopplingen för
att få de önskade spänningarna. Med 4mA och 20mA fick man 0,857V respektive 4,259V
utspänning till A/D-ingångarna.
Eftersom flera delar av elektronikkonstruktionen, såsom switchar och spänningsregulatorer,
inte varit så avancerade har personalen på konstruktionsavdelningen på företaget kunnat
granska dessa. Därför har de varken behövts simuleras eller testas rent fysiskt genom
uppkoppling på en labb-platta.
Med hjälp av Atmels utvecklingskort STK-500, och annan utrustning från EEPAB, samt ett
labb-kort från MDH, har mycket av programkoden kunnat testas innan det slutliga
mönsterkortet varit tillgänglig. Med ett spänningsaggregat kopplat till STK-kortet har man
kunnat testa A/D-omvandlingen. Dessutom när labb-kortet, som innehåller en 7segmentdisplay med två tecken, kopplats till STK-kortet kunde man se hur
spänningenförändringen påverkar resultatet på displayen. Även UART-interfacet har kunnat
testas med samma STK-kort, genom att koppla kortet till datorns COM-port. Ett program,
som heter Terminal, användes för att kunna se resultatet som man skickar från
mikrokontrollern via UART-interfacet.
5.2 Testning av elektronikenhet
Vad gäller testandet av elektronikenheten testades regulatorerna först för att se att man fick
rätt spänning både in och ut. Step up-regulatorn skulle få in ca 7,2V från batteripacket och ge
ut 12V. Vid testandet av elektronikenheten användes ett späningsaggregat istället för
batteripacket från grävmaskinen, för verifiering av inspänning till step up-regulatorn.
17
Spänningsreglatorn skulle få in 12V och ge en utspänning på ca 5V. När allt detta var
verifierat kunde testandet av mikrokontrollern påbörjas.
På kortet finns två lysdioder som företaget lagt till för senare användning. För att testa
mikrokontrollerns portar gjordes ett testprogram som tänder dessa lysdioder. När detta
verifierats var det dags att koppla i displayen och testa dem. Slutligen kopplades
vinkelgivaren på elektronikenheten för testning.
Det sista som testades var kommunikationen mellan PC och elektronikenhet. Först måste
spänningen till blåtandsmodulen kontrolleras, så att den får in 5V. Därefter kan verifieringen,
av att mikrokontrollern kan skicka en vinkel via Bluetooth till ett terminalprogram i PC:n,
göras.
6 Implementering
När elektronikenheten hade testats och allt fungerade som det ska, monterades kortet in i
grävmaskinen, se Bild 2 och Bild 4.
Bild 2. Grävmaskinen
Grävmaskinens batteripack kopplades till elektronikenheten så att den matas av
grävmaskinen. Displayen, se Bild 3, sattes på plats på varsin sida av grävmaskinen.
Vinkelgivaren fästes i skopan och en knapp för både nollställing av vinkel och för start och
stop av programmet, monterades.
Bild 3. Display som monteras på grävmaskinens bägge sidor
Sedan drogs kablar från vinkelgivaren längs armen till elektronikenheten och från displayen
till elektronikenheten. Det är i denna fas som demonstratorn blir till en färdig produkt, se Bild
5.
18
Bild 4. Elektronikenheten
Bild 5. Den färdiga demonstratorn
7 Resultat och diskussion
Det slutliga kortet, det vill säga elektronikenheten, som tillverkades fungerade i stort sett
problemfritt redan från början. Endast värden på några resistorer fick ändras.
Vad gäller programkod så fungerade allt nästan som det ska. Algoritmen för displayen hade
några brister. Till exempel skrevs siffror på flera av displayerna samtidigt och på fel ställen,
eftersom släckning av display inte utfördes rätt. Men med lite omkodning kunde problemet
lösas. Nästa problem var att segmenten på displayen lyste alldeles för svagt. Detta berodde på
att pnp-transistorn, som används i aktivering av display, inte öppnades ordentligt och därmed
flöt inte tillräckligt mycket ström till displayen. Detta löstes med att byta plats på två
resistorer.
I kommunikation mellan elektronikenheten och PC:n finns några brister i programmet. Ett
problem är att när buffern, dit tecknen som ska skickas lagras, blir full kommer några
”skräp”-tecken även att skrivas ut. För övrigt fungerar blåtandskommunikationen bra.
Utöver det som var uppgiften i detta examensarbete gjordes det mycket annat till produkten.
Företaget ville lägga till extra funktioner till demonstratorn så att den har bredare
19
användningsområde. Till exempel ville de att det ska vara möjligt att kunna koppla
elektronikenheten till ett fordon.
På grund av dessa extra funktioner påverkades uppgiften en aning, till exempel påverkades
val av spänningsregulator samt att en Battery-Hold-signal, som aktiverar grävmaskinens
batteripack som spänningskälla, fick läggas till. I det slutliga mönsterkortet som EEPAB
tillverkat finns en switchad spänningsregulator, LM2734, istället för LM7805, som hade
kunnat användas. Men eftersom EEPAB vill kunna koppla demonstratorn i ett fordon, och
därmed matas den med fordonets batteri, vore inte LM7805 lämplig för detta. LM7805 är
nämligen en linjär spänningsregulator som inte tål höga inspänningar. Däremot är LM2734
lämplig eftersom den kan matas med upp emot 20V, vilket räcker gott och väl då spänningen i
ett fodonsbatteri är bara 12V. Dessutom fås mindre förluster, i form av värme, med LM2734.
I kretsschemat ser man dock att en LM7805 används som 5V regulator även om det finns en
LM2734 i det slutliga kretskortet. Detta på grund av att EEPAB ville ha denna extra funktion,
som inte finns med i kravspecifikationen.
8 Slutsats
Det har varit intressant att arbeta med detta projekt. Att få vara med i att designa och
konstruera en produkt som kommer att användas av företaget känns roligt. Man har fått lära
sig mycket nya saker under projektet och även se vad det är att jobba i ett företag. Eftersom
arbetet utfördes individuellt var det bra att jobba på företaget då man kunde bolla idéer med
kollegor.
Tidsplanen höll inte eftersom det dröjde så pass länge innan kretskortet som konstruerats var
tillgängligt. Detta på grund av att företaget själv ville rita in kretsscheman i sin programvara
samt rita mönsterkortet. Eftersom företaget också hade annat att göra så var detta inte första
prioritet. Dessutom beställdes kortet utomlands och därmed dröjde det ytterligare.
Resultaten sett utifrån kravspecifikationen är bra. En fungerande demonstrator till företagets
vinkelgivare har tagits fram.
20
9 Referenser
[1] Accelerometer, http://en.wikipedia.org/wiki/Accelerometer, 2009-08-23
[2] Ciruit Simulator Applet, http://falstad.com/circuit
21
10 Bilaga A - Flödesscheman
Main-funktion:
START
Main()
INITIERING AV:

I/O, TIMER0

ADC, UART
AKTIVERA
BATTERIPACK
OÄNDLIG LOOP - GÖR
DETTA SÅ LÄNGE SOM
PROGRAMMET KÖRS.
KONVERTERA
ADC-RESULTAT
TILL VINKEL
SKRIV UT
VINKEL PÅ
DISPLAY
22
Display-funktion:
START
Display()
DIGIT = 0
NEJ
ÄR DISPLAYRÄKNARE 0?
DISPLAYRÄKNARE--
JA
DISPLAYRÄKNARE = 2
JA
ÄR DIGIT 0?
VINKELN
LAGRAS I EN
VARIABEL
DIGIT = 8
NEJ
SLÄCK ALLA
SEGMENT I
DISPLAY
AKTIVERA
DISPLAY(1,2,3,4)
ÄR DIGIT 1?
NEJ
TA
ABSOLUTBELOPPET
AV VINKELN
JA
JA
ÄR VINKELN
NEGATIV?
NEJ
SLÄCK ALLA
SEGMENT I
DISPLAY
SKRIV UT
SIFFRA PÅ
DISPLAY(1,2,3,4)
DIVIDERA
VINKEL MED 10
SKIFTA DIGIT EN
BIT HÖGER
23
SKRIV UT
MINUS-TECKEN
PÅ DISPLAY 4
Timer-funktion:
START
A
Timer()
D
ADCRÄKNARE++
HAR ADC-RÄKNARE
NÅTT SITT MAX VÄRDE?
NEJ
STARTA TIMER0
JA
NEJ
LAGRA ADCRESULTAT I EN
VARIABEL
HAR TIMERN NÅTT
MAX VÄRDE?
STARTA NY
OMVANDLING
JA
TIMER0
INTERRUPT
SKER
SKICKA VINKEL
TILL PC
A
NOLLSTÄLL
ADC-RÄKNARE
B
B
NEJ
C
ÄR KALIB-SWITCH
INTRYCKT?
JA
ÄR
DISPLAYRÄKNARE
0?
HAR KALIB-RÄKNARE
NÅTT SITT MAX VÄRDE?
NEJ
KALIBRÄKNARE++
NEJ
DISPLAYRÄKNARE--
JA
NYTT OFFSETVÄRDE
D
NOLLSTÄLL
KALIB-RÄKNARE
C
24
JA
11 Bilaga B - Programkod
Defines.h
#define
#define
#define
#define
#define
#define
#define
#define
#define
Bit0 0x01
Bit1 0x02
Bit2 0x04
Bit3 0x08
Bit4 0x10
Bit5 0x20
Bit6 0x40
Bit7 0x80
Bit15 0x8000
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
zero 0xFC
one 0x60
two 0xDA
three 0xF2
four 0x66
five 0xB6
six 0xBE
seven 0xE0
eight 0xFE
nine 0xF6
minus 0x02
#define
#define
#define
#define
SBit(Reg,Bit) (Reg |= Bit)
// Sätter motsvarande bit i register Reg till 1.
CBit(Reg,Bit) (Reg &= ~(Bit)) // Sätter motsvarande bit i register Reg till 0.
Bit_True(Reg,Bit) ((Reg & Bit) == Bit)
Bit_False(Reg,Bit) ((Reg & Bit) == 0)
Main.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
<ina90.h>
<iom128.h>
<stdio.h>
<stdlib.h>
<string.h>
"basetype.h"
"timer.h"
"uart.h"
"adc.h"
"defines.h"
int x;
int tal1;
int Angle;
int Digit=0;
int DispTemp;
int value, value_abs;
extern int counter_Disp;
int SevenSeg[10]={zero,one,two,three,four,five,six,seven,eight,nine}; // Array med tio tecken
som bildar siffrorna till displayen.
void init_IO(void) //
{
DDRA=0xFF;
//
DDRB=0xFF;
//
DDRC=0xFF;
//
DDRD=0x00;
//
DDRE=0x22;
//
utport(Battery-Hold).
DDRF=0x00;
//
}
Initierar I/O-portarna.
PORTA
PORTB
PORTC
PORTD
PORTE
utport(Segments => Bildar siffrorna).
utport
utport(Common Anode => Styr displayen).
bit 7:6 inport(Switch1 => Kalibrering av vinkel, start av program)
bit 0 inport(UART Rx), bit 1 utport(UART Tx), bit 5
PORTF inport(ADC2:1 => Signal från givare)
void Display(int value)
// Display-funktion
{
if (counter_Disp != 0)
// Om räknaren inte är 0...
return;
// ...gå ur funktionen.
counter_Disp=2;
// Räknaren tilldelas ett tal.
if(Digit == 0)
{
Digit = 8;
DispTemp = value;
}
// Om Digit är 0...
// Tilldelas Digit 8, binärt 0000 1000.
// Vinkeln lagras i variabeln DispTemp.
25
PORTA=0;
// Släcker alla segment.
PORTC=Digit;
// Aktiverar D1/D2/D3/D4.
if (Digit == 1)
// Om Digit är 1...
{
if(value < 0)
// Om vinkeln är negativ...
{
PORTA=minus;
// Skriv ut minus-tecken på D4.
}
else
// Annars...
PORTA=0;
// Släck segmenten.
}
else
// Annars...
PORTA=SevenSeg[abs(DispTemp%10)]; // Skriv ut siffra på display.
DispTemp/=10;
// Dividera DispTemp med 10.
Digit >>=1;
// Skifta Digit en bit till höger(minska med en bit).
return;
}
void main(void) // Huvudprogram
{
/* Initieringar */
init_IO();
// Initierar in- och utportar.
init_Timer0();
// Initierar timer0 för användning.
init_ADC();
// Initierar A/D-omvandlaren.
init_UART();
// Initierar UART-interfacet.
__enable_interrupt();
// Möjliggör användning av interrupter.
PORTB=0x30;
PORTE=0x20;
// Aktiverar batteripack.
while(1)
//forever loop
{
Angle=ADC_To_Deg(); // Sparar returvärdet från ADC_To_Deg() till varabeln Angle.
Display(Angle);
// Anropar funktionen Display() med Angle som inparameter.
}
}
adc.c
#include
#include
#include
#include
#include
#include
#include
#include
<ina90.h>
<iom128.h>
<stdio.h>
<stdlib.h>
<string.h>
"basetype.h"
"timer.h"
"adc.h"
float ADC_Angle;
void init_ADC(void)
{
offset=524;
ADCSR=0xC3;
// Enable ADC(ADEN=1) och startar konversation. Prescaler faktor 8.
ADMUX=0x40;
// Extern ref.spänning(5V) och ADC0(PF0),som ingång,valt.Resultat Left
Adjusted.
}
float ADC_To_Deg(void)
{
if (ADC_resultat > 150)
// Om ADC-värdet är större än 150…
ADC_Angle=(0.5226 * (float)(ADC_resultat-offset)); // Lutningen(vinkeln) fås ur
ekvationen.
else
// Annars...
ADC_Angle=0;
// Skriv ut en nolla på display.
return ADC_Angle;
}
timer.c
#define timer_c
#include <ina90.h>
#include <iom128.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "basetype.h"
#include "uart.h"
26
#include "timer.h"
#include "adc.h"
#include "defines.h"
#define DELAY_ADC 135
#define DELAY_Kalib 900
#define DELAY_Stop 1350
int offset;
int counter_ADC;
int counter_Kalib;
int counter_Stop;
int counter_Disp;
extern int Angle;
/*---------------------------------------Timer Interrupt sker vid:
DELAY_ADC ~300ms
DELAY_Kalib ~2000ms
DELAY_Stop ~3000ms
-----------------------------------------*/
void init_Timer0(void)
{
TIMSK=0x01; // Timer/Counter Overflow Interrupt Enable.
TCCR0=0x04; // Normal mode timer/counter. Prescaler faktor 64.
}
#pragma vector=TIMER0_OVF_vect
__interrupt void TIMER_0_Interrupt (void)
{
if (counter_ADC++ >= DELAY_ADC)
{
ADC_resultat=ADC; // Läs av ADC-registret och spara till en variabel.
ADCSR |= (1<<6);
//Starta ny AD omvandling
Print_int(Angle); // Skicka vinkeln till PC.
counter_ADC=0;
// Nollställer räknaren.
}
/* T1-Start/Stop */
if (Bit_True(PIND,Bit6)) // Om Switch1 intryckt…
{
if (counter_Stop++ >= DELAY_Stop) // Om tre sekunder gått…
{
PORTE=0x00;
// Deaktiverar batteripack.
PORTA=0x00;
// Släcker segmenten.
counter_Stop=0;
// Nollställer räknaren.
while (1);
// Oändlig loop.
}
}
else if (Bit_False(PIND,Bit6)) // Annars om Switch1 INTE är intryckt…
{
counter_Stop=0;
// Nollställer räknaren.
}
/* T2-Nollställning */
if (Bit_True(PIND,Bit7)) // Om Switch2 intryckt…
{
if (counter_Kalib++ >= DELAY_Kalib) // Om två sekunder gått…
{
offset=ADC_resultat; // Ett nytt offset-värde tilldelas.
counter_Kalib=0;
// Nollställer räknaren.
}
}
else if (Bit_False(PIND,Bit7)) // Annars om Switch2 INTE är intryckt…
{
counter_Kalib=0;
// Nollställer räknaren.
}
if (counter_Disp != 0)
{
counter_Disp--;
}
// Om räknaren inte är 0…
// Minska räknaren.
}
27
uart.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
<ina90.h>
<iom128.h>
<stdio.h>
<stdlib.h>
<string.h>
"basetype.h"
"timer.h"
"adc.h"
"defines.h"
"uart.h"
/* AT-Kommandon */
char HangUpp[] = "ATH\r";
char AskBTR[] = "AT+BTR?\r";
char HWReset[] = "ATZ\r";
char WriteNovRam[] = "AT&W\r";
char ClearNovRam[] = "AT&F*\r";
char Sreg504[] = "ATS504=1\r";
char Sreg507[] = "ATS507=0\r";
char Sreg512[] = "ATS512=1\r";
char Sreg520[] = "ATS520=9600\r";
char Sreg530[] = "ATS530=2000\r";
char PrintBuf[10];
/* UART Buffer Defines */
#define UART_RX_BUFFER_SIZE 128
#define UART_TX_BUFFER_SIZE 128
// 2,4,8,16,32,64,128 or 256 bytes
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 )
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 )
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
#error TX buffer size is not a power of 2
#endif
char
char
char
char
char
char
UART_RxBuf[UART_RX_BUFFER_SIZE];
UART_RxHead;
UART_RxTail;
UART_TxBuf[UART_TX_BUFFER_SIZE];
UART_TxHead;
UART_TxTail;
/* Initiering av UART */
void init_UART(void)
{
unsigned char x;
UBRR0L = 0x2F;
// Sätter baud rate till 9600
/* Enable UART receiver och transmitter, och receive interrupt */
UCSR0B = ( (1<<RXCIE0) | (1<<RXEN0) | (1<<TXEN0) );
x = 0;
UART_RxTail
UART_RxHead
UART_TxTail
UART_TxHead
=
=
=
=
x;
x;
x;
x;
}
/* Interrupt hanterare */
#pragma vector=USART0_RXC_vect
__interrupt void UART_RX_interrupt( void )
{
unsigned char data;
unsigned char tmphead;
data = UDR0;
// Läser mottagen data
/* Beräkna buffer index */
tmphead = ( UART_RxHead + 1 ) & UART_RX_BUFFER_MASK;
UART_RxHead = tmphead;
// Lagra ny index
28
if ( tmphead == UART_RxTail )
{
/* ERROR! Receive buffer overflow */
}
UART_RxBuf[tmphead] = data;
// Lagra mottagen data i buffer
}
#pragma vector=USART0_UDRE_vect
__interrupt void UART_TX_interrupt( void )
{
unsigned char tmptail;
if ( UART_TxHead != UART_TxTail )
// Kontrollera om all data sänts
{
UDR0 = UART_TxBuf[UART_TxTail]; // Starta sändning
/* Beräkna buffer index */
tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
UART_TxTail = tmptail;
// Lagra ny index
}
else
{
UCSR0B &= ~(1<<UDRIE0);
// Disable UDRE interrupt
}
}
void TransmitArray(char *data, char size)
{
unsigned char tmphead;
/* Beräkna buffer index */
tmphead = ( UART_TxHead + size ) & UART_TX_BUFFER_MASK; // Invänta ledig utrymme i
buffern
while ( tmphead == UART_TxTail );
if(UART_TxHead==0)
{
memcpy(&UART_TxBuf[UART_TxHead], data, size);
}
else if ( size < (char)(UART_TX_BUFFER_SIZE - tmphead))
{
memcpy(&UART_TxBuf[tmphead], data, size);
}
UCSR0B |= (1<<UDRIE0);
UART_TxHead = tmphead;
/* Enable UDRE interrupt */
/* Lagra ny index */
}
void Print_int(int data)
{
wordToAsciiString(PrintBuf, (WORD)data);
TransmitArray(PrintBuf,strlen(PrintBuf));
}
void wordToAsciiString(char * Buffer, WORD Value)
{
WORD InValue = Value;
Buffer[0] = ' ';
if (BITTRUE(InValue, BIT15))
{
InValue = (~InValue)+1;
Buffer[0] = '-';
}
//Buffer[1] = (InValue/10000) + '0';
//InValue = InValue%10000;
//Buffer[2] = (InValue/1000) + '0';
//InValue = InValue%1000;
Buffer[1] = (InValue/100) + '0';
InValue = InValue%100;
Buffer[2] = (InValue/10) + '0';
InValue = InValue%10;
Buffer[3] = InValue + '0';
Buffer[4] = '\n';
//Buffer[7] = 0;
}
29
12 Bilaga C - Kretsscheman
Mikrokontroller + annat:
30
Transistorsteg:
31
Display:
32
13 Bilaga D – Datablad
13.1 ATMega128
33
34
35
13.2 Vinkelgivare
36
13.3 Spänningsregulator LM2734
37
13.4 Step up-regulator LM2577
38