• No results found

Från verkligheten till LabView: ett äventyr via USB

N/A
N/A
Protected

Academic year: 2022

Share "Från verkligheten till LabView: ett äventyr via USB"

Copied!
67
0
0

Loading.... (view fulltext now)

Full text

(1)

EXAMENSARBETE

HÖGSKOLEINGENJÖRSPROGRAMMET ELEKTRONIK

Från verkligheten till LabView

Ett äventyr via USB

Mats Eriksson och Fredrik Lindberg

(2)

Sammanfattning

Uppgiften vi fick var att designa en mätutrustning för vibrationsmätning i en fordonshytt, utrustningen ska samla in mätdata och via USB skicka datat till LabView. Arbetet har utförts i uppdrag av Arbetslivsinstitutet i Umeå. Vår engagerade och handlingskraftiga handledare var fil Dr Patrik Holmlund.

Systemet består av:

• Givare, accelerometrar

• Signalanpassning, filtrering och förstärkning

• A/D-omvandling, 22 bitars upplösning

• Interface mellan A/D-omvandlare och mikrokontroller

• EZ-USB, mikrokontroller med stöd för USB kommunikation

• DLL-fil, hanterar kommunikation mellan USB och LabView

• LabView, insamling sortering och behandling av mätdata

Som grund att utgå ifrån hade vi ett tidigare utfört examensarbete, i det skedde datainsamlingen i ett DSP-kort istället för via USB till LabView. Det tidigare examensarbetet är utfört av Tobias Lagander och Fredrik Brännström. Det vi kunde ta med oss från det var principen för hur A/D-omvandlarna skulle kopplas och förslag på signalanpassning.

Den mesta koncentrationen i projektet har blivit riktad till att få igång en

fungerande kommunikation mellan LabView och USB eftersom det är ett

intressant område som har många möjligheter att erbjuda.

(3)

INNEHÅLLSFÖRTECKNING

1. SYSTEMBESKRIVNING... 5

2. GIVARE ADXL105 ... 6

3. SIGNALANPASSNING... 7

3.1 F ILTRERING ... 7

3.2 F ÖRSTÄRKNING ... 7

4. A/D-OMVANDLING... 9

4.1 K ONTROLLREGISTER ... 10

4.2 U TDATA FRÅN AD7716 ... 10

4.3 T IMING ... 11

5. INTERFACING AD7716 MED EZ-USB ... 12

5.1 I NITIERING AV AD7716 ... 12

5.2 R ESET - PULS ... 12

5.3 S ERIEKLOCKA ... 13

5.4 PAL FÖR HANDSKAKNING ... 13

5.5 S ERIELLT TILL PARALLELLT ... 14

5.6 R ÄKNARE ... 14

5.7 S KIFTREGISTER ... 14

5.8 L ATCH ... 14

5.9 PAL FÖR R EAD -S TROBE ... 15

5.10 K ASKADKOPPLING AV AD7716 ... 15

6. EZ-USB. ... 16

6.1 P ROGRAMMERINGEN AV PROCESSORN PÅ MÄTKORTET ... 17

6.2 A TT UPPNÅ HÖGRE HASTIGHET ... 18

6.3 O M ”T URBO MODE ” ... 18

6.4 K ODEN I EZ-USB ... 20

6.5 T EST AV PROGRAMMET ... 21

6.6 I NITIERINGSKODEN . ... 21

7. DLL-FIL ... 23

7.1 Ö VERSIKT AV KODEN ... 26

9. ÖVERGRIPANDE OM USB... 28

10. SPÄNNINGSMATNING ... 29

11. LITTERATURFÖRTECKNING... 30

(4)

BILAGOR

1. PALCE PROGRAM... 31

2. EZ-USB PROGRAM ... 36

3. DLL PROGRAM ... 45

4. LABVIEW SCHEMAN... 55

5. KOPPLINGSSCHEMAN ... 61

(5)

1. Systembeskrivning

Systemet skall mäta vibrationer i en fordonshytt och via USB läsa in det i PC till LabView samt lagra det på hårddisk.

Systemet består av vibrationsgivare som mäter acceleration i x-led. Signalen från givaren filtreras, förstärks och A/D-omvandlas med 22 bitars upplösning.

Interfacet mellan A/D-omvandlaren och EZ-USB:n omvandlar seriellt data till en 8 bitars databuss. EZ-USB:n som läser av databussen och skickar datat till PC via USB. Kommunikationen mellan USB och LabView sker i en DLL-fil. I LabView sorteras, behandlas och presenteras mätdatat.

Givare

Signal- anpassning

A/D Interface EZ-USB DLL-

fil

LabView

(6)

2. Givare ADXL105

ADXL105 är en enaxlig accelerometer med hög noggrannhet inbyggd i en IC- krets. Den har ett mätområde på ± 5g och utsignalen är en analog spänning.

ADXL105 kan mäta både dynamiska acceleration (t.ex. vibration) och statisk acceleration (t.ex. gravation eller lutning). Kretsen har en inbyggd ej inkopplad op-förstärkare som man kan använda till att förstärka utsignalen.

g till 1.5 V/g beroende på om man vill förstärka den eller ej.

Utsignalen från en krets som ligger vågrät är 2.50V, en krets som står lodrät 2.75V eller 2.25V beroende vilken sida som står uppåt. Dom stående kretsarna

g respektive –g.

Se bilaga 5 för kopplingsschema.

(7)

3. Signalanpassning

3.1 Filtrering

Genom att koppla den i givaren inbyggda op-förstärkaren på detta vis får vi ett

Genom att välja C till 33nF och R1 till 10kΩ beräknas brytfrekvensen till 482Hz. Förstärkning behövs ej i detta läge eftersom det kommer att göras i nästa steg, därför väljer vi R2 till 10k Ω , då blir förstärkningen –1.

3.2 Förstärkning

Detta är till för att förstärka insignalerna från varje givare till de analoga ingångarna på AD7716. Principen är tagen från ett av de förslag från tidigare exjobb. Som förstärkare används TN064CN. Eftersom ingången på A/D- omvandlaren har insignalsområde på ±2.5V så ska op-förstärkaren matas med

± 2.5V.

R2 GAIN R1

R1 C 2ð f 1

: beräknas ng

förstärkni och

ns Brytfrekve

3dB

=

= ⋅

Till AD7716

Analog 8 till 1 multiplexer

8 till 1 multiplexer Binär

räknare Vcc

Räknarens värde

Resistansnät Rx

Lysdioder för

indikation Från givare

Ry

(8)

Räknaren räknar knapptryckningar och antar ett värde, den analoga multiplexern öppnar då en kanal och förstärkningen beräknas:

Ry Rx Ry 1 Rx Ry

Ry Rx Vin

GAIN = Vut = + + ≈

Den andra mupltiplexern i kopplingen antar samma värde som den analoga

multiplexern, på dess kanaler sitter lysdioder som används till indikatorer på

vilken förstärkning man använder. Ett alternativ är att med hjälp av en port på

EZ-USB:n styra den analoga multiplexern, det skulle ge möjlighet att välja

(9)

4. A/D-omvandling

AD7716 är en krets för insamling av mätdata, den innehåller 4st kanaler med en bandbredd på 584 Hz, upplösningen för varje kanal är 22 bitar. Varje kanal har en egen A/D-omvandlare som tillämpar sigma-delta teknologi. A/D- omvandlarna innehåller ett digitalt filter varvid systemets filtreringskrav minskas.

Kretsen har också ett CASCIN-ben och ett CASCOUT-ben vilka tillåter att man kaskadkopplar flera kretsar.

Tre adresseringspinnar ger kretsen en adress, det betyder att man kan samla in data från 8 kretsar vilket innebär 32 kanaler.

Utdatat från varje kanal är ett 32 bitars ord, av det är 22 bitar resultatet från A/D-omvandling, 2 bitar kanaladress och 3 bitar är kretsens adress, det innebär att varje kanal får en 5 bitars adress.

Kretsens kontrollregister programmeras med hjälp av benen SCLK, SDATA

och TFS. Tre av bitarna i kontrollregistret bestämmer brytfrekvensen på det

digitala filtret.

(10)

4.1 Kontrollregister

Det 16 bitar långa kontrollregistret programmeras med två bytes. Vilken byte det är som skickas hålls reda på med den minst signifikanta biten (LSB). Datat skickas med LSB först. FC0, FC1 och FC2 bestämmer brytfrekvensen på det digitala filtret. Genom att lägga M0-biten hög så ignoreras adressbitarna, det innebär att man kan adressera flera kretsar samtidigt så dom får samma brytfrekvens.

Kontrollregistrets bitar samt det digitala filtrets brytfrekvenser.

Utdatats bitar samt

kanalernas adresser

(11)

4.3 Timing

Vid initiering läggs TFS (Transmit Frame Sync) på AD7716 låg, samtidigt som

TFS går låg skiftas data ut på dataledningen. AD7716 läser av datat på negativ

flank på SCLK (serieklockan). När en byte skickats så läggs TFS hög igen.

(12)

5. Interfacing AD7716 med EZ-USB

Interfacet mellan AD7716 och EZ-USB sett från EZ-USB sidan består endast av en 8-bitars databuss och en Read-Strobe, information för initiering samt reset av AD7716. Alla synkroniseringssignaler tas om hand hårdvarumässigt samt i programmerbara logikkretsar (PAL). Se bild för översiktlig beskrivning.

5.1 Initiering av AD7716

Vid uppstart måste man skriva till kontrollregistret på AD7716 för att

bestämma det digitala filtrets brytfrekvens. Hela initieringscykeln sköts av en PAL krets, det enda som sköts från EZ-USB är att välja önskad brytfrekvens på det digitala filtret samt att starta en initieringscykel. PAL-kretsen är

programmerad så att den tar hand om synkroniseringssignalerna till AD7716 under initieringsförloppet. Det enda som behöver ske från EZ-USB är att bestämma vilken brytfrekvens som det digitala filtret i AD7716 skall få samt att bestämma när initiering skall ske. Detta sker på 4st ingångar på

program se bilaga 1.

AD7716 EZ-USB

PAL för initiering

Seriell till parallell

PAL för Read Strobe PAL för

handskakning

Databuss Synkroniserings-

signaler

Seriedata

Initieringsinformation

Reset

(13)

5.3 Serieklocka

Vid data sändning är det serieklockan (SCLK) som bestämmer hastigheten för dataöverföringen. Om AD7716 är kopplade i mastermode så har SCLK samma frekvens dom CLKIN på AD7716, i vårt fall är den på 8MHZ. Hastigheten på databussen skulle då bli 1Mbit/s vilket är för högt. På grund av detta kopplas AD7716 som slav vilket innebär av vi kan bestämma hastigheten på SCLK.

Efter vissa beräkningar kom vi fram till att en lämplig hastighet skulle vara 750kHz. EZ-USB har en klockutgång på 24MHz (CLK24) och ur den skapas SCLK genom att dela den med 2

5

. Detta realiseras genom att koppla CLK24 till en 4-bits binär räknare, hastigheten på den MSB på räknaren blir då 1,5MHz, den halveras då med en JK-vippa och då har vi fått vår SCLK

Alla synkroniseringssignaler för sändning av data hanteras i en PAL, det innebär att det enda EZ-USB:n behöva göra är att läsa från en databuss.

AD7716 är kopplad som slav, det innebär att PAL:en får fungera som master vid datasändning. Ett problem som uppstår är att PAL:en arbetar i SCLK:s hastighet (750kHz) och signalen som AD7716 skickar när den sänt sitt data (CASCOUT) kommer i 8MHz hastighet, det innebär att PAL:en inte kommer att hinna detektera den. Det löses med en JK-vippa som har till ingång

CASCIN eller CASCOUT. Vippan är kopplad så att den

flank på dess ingång, det innebär att det inverterade utgången kommer då att CASCIN kommer och gå hög när CASCOUT kommer, utgången kommer då att ligga hög till det att nästa CASCIN kommer. PAL:en kommer då att kunna använda den signalen för att detektera CASCOUT från AD7716.

CASCIN CASCOUT

JK-vippa ut

JK-vippa in

(14)

5.5 Seriellt till parallellt

AD7716 skickar ut sitt data seriellt men på grund av hastighetskomplikationer så kan ej EZ-USB kretsen läsa i den hastighet som AD7716 skickar, därför omvandlas det seriella datat till en 8 bitars parallelldatabuss vilket sänker läshastigheten med 8 gånger. Se bild för översiktlig beskrivning.

Räknaren är en 4-bitars binär räknare av typen 74163. Den är till för att hålla reda på när 8 bitar har skiftats ut från AD7716. När data börjar skiftas ut på dataledningen så börjar räknaren räkna klockcykler på serieklockan, när 8 klockpulser räknats (dvs. när räknaren har värdet 7) skickar räknaren en CLEAR puls till sig själv och en signal till resten av systemet att 8 bitar har skiftats ut från AD7716. När allt data skickats ut stannar räknaren och väntar

5.7 Skiftregister

Skiftregistret är ett 8 bitars seriell till parallell register av typen 74164. Data som kommer på seriedataledningen skiftas ut på registret vid positiv flank på serieklockan.

5.8 Latch

0-7

Skift- register

Latch

Seriellt data Serieklocka

PAL för Read- Strobe

8 bitars parallell databuss

Read-Strobe

(15)

5.9 PAL för Read-Strobe

Denna krets är av typen PAL 22V10. När signal kommer från räknaren lägger den ut en signal på Read-Strobe under de två efterföljande klockcyklerna.

Denna får fungera som indikation att giltigt data finns på databussen. För program se bilaga 1.

5.10 Kaskadkoppling av AD7716

När den första AD-omvandlaren har skickat sitt data så sänder den en puls på

CASCOUT. Denna puls kan då kopplas på CASCIN på nästa A/D-amvandlare

som då börjar sända sitt data. I ett system kan man ha upp till 8st AD7716

kaskadkopplade.

(16)

6. EZ-USB.

kommunikationen. I detta fall består kringutrustningen av A/D-omvandlare.

8051 USB-

CONTROL

USB-BUSS

I/O

(17)

6.1 Programmeringen av processorn på mätkortet

När vi fick utvecklingskortet från Stockholm monterade vi upp det omgående.

Vi testade utvecklingskortet med ett medföljande testprogram, på det sätt kunde vi fastställa att all medföljande utrustning fullföljde sin uppgift. Testet skedde utan problem. När vi skrev ett eget enkelt program så fungerade det ej.

Felsökning inleddes och orsaken till felet uppdagades. Inställningarna i C- kompilatorn från Keil (www.keil.com) var ej korrekt inställda, problemet åtgärdades genom att studera inställningarna från det medföljande

testprogrammet. Vi kom fram till att inställningarna från början adresserade den kompilerade koden till fel minnesadress. Programmet vi gjort skrev till en port på EZ-USB:n.

Vi fick dock oss en funderare när vi vände våra blickar mot oscilloskopet.

Kodens uppgift var att EZ-USB:n skulle ”toggla” (skriva ett och noll) porten med högsta möjliga hastighet. När vi tittade på oscilloskopet kunde vi se att

”togglingen” utfördes med bekymrande låg hastighet (porten ”togglade” med 200 kHz hastighet) . Vi blev fundersamma när vi upptäckte att det gick så sakta. I det övergripande faktabladet om EZ-USB:n hävdades det att

processorn aldrig behövde bli flaskhalsen vid kommunikationen mot PC:n. Nu visade sig att det inte var korrekt. I vår applikation blev det en flaskhals trots att EZ-USB:n endast hämtade in data. Vi önskade läsa in data seriellt med en hastighet på minst 1,2Mbit/s och den klarar endast av att skriva (och läsa) till en port med 200kHz hastighet.

Nu förstod vi att vi hade en stor utmaning framför oss. Vi började med att titta på några alternativ som möjliggör en snabb bithastighet. Ett alternativ var att läsa in seriellt via en UART som var inbyggd i EZ-USB:n. Genom den kan inläsning ske seriellt med en hastighet upp mot 6Mbit/s (vi önskar 1,2Mbit/s).

Vi tittade närmare på det och fann att man endast kan läsa in 8 bitar åt gången innan man mjukvarumässigt blev tvingad att nollställa en flagga. Vi vill läsa in 32 bitar åt gången och inte 8 bitar. Alltså kunde inte det alternativet användas.

Vi surfade in på cypress hemsida och tittade närmare på den Internet sida som innehöll uppgifter om att processorn inte skulle bli en flaskhals

(http://www.cypress.com/usb/usbappnotes.html#performance) . Dom hade gjort ett test som bevisade detta. Vi hämtade hem ett –pdf dokument där dom beskrev hur testen hade gått till.

Testen visade att dom använde en speciell port för den snabba överföringen

och en speciell adresseringsteknik för att uppnå den höga hastigheten (turbo

mode). Vidare var programmet helt skrivet i assembler. Vi bestämde oss också

för att byta programmeringsspråk till assembler. Assemblerkod är enligt vår

mening det bästa alternativet vid tidskritiska situationer.

(18)

6.2 Att uppnå högre hastighet

Vi tittade på flera exempel om 8051:ans assembler kod och hade hjälp av det vi mindes från hårdvaruprojektet och mikrodatorlektionerna. Det skall påpekas att vi hade god hjälp av anteckningarna från mikrodatorlektionerna På kort tid hade lyckades vi med att förstå tillvägagångssättet för att skriva assemblerkod till 8051 processorer. Efter att vi hade ställt in kompilatorn på assembler kodning var det bara att börja skriva en ny kod, fast den här gången i

assembler. Vi började med en kod som ”togglade” en port, precis som i vårt tidigare C-program. Vi såg att hastigheten snabbades upp jämfört med koden i C-programmet, det var en positiv överraskning.

En klar fördel för oss blev nu att vi tack vare assembler programmeringen fick möjlighet att räkna på hur lång tid en instruktion tar. Det gav oss en möjlighet att skriva en så effektiv kod som möjligt utan att behöva testköra den. Vi räknade på hur lång tid vår kod tog att exekvera innan vi skrev den. Vi verifierade våra uträkningar med ett oscilloskop, portarna var höga precis lika lång tid som vi hade räknat ut. Trots framgången hade vi inte fått upp den hastighet på avläsningen av databussen som krävdes. Vi konstaterade att det berodde på att vi inte använde det speciella adresseringsättet (”Turbo mode”).

Nu läste vi oss in på det snabba sättet att ta in data till EZ-USB. Vi studerade databladet från cypress som visade deras ”snabbhetstest” .

(http://www.cypress.com/usb/usbappnotes.html#performance )

6.3 Om ”Turbo mode”

Snabbhetstestetes viktigaste del bestod av en funktion som heter ”Turbo mode”. Funktionen är unik och finns ej i en vanlig 8051:a.

När man använder ”turbo mode” läser EZ-USB egentligen av sin egen databuss

på 8 bitar , det är huvudorsaken till den snabba hastigheten. Man kopplar in

dataledningarna man ville läsa av direkt på processorns databuss. Den ger

också ut två signaler som talar om i fall den läser eller skriver en ”turbo

transfer”. När den läst in data skickas det till en pipa (array) och i ”turbo

transfer” får samma variabel föregående värde plus ett automatiskt.

(19)

”Turbo mode” förklarat i kod:

Assemblerkod:

mov dptr,#AUTODATA ; This register will now access IN2BUF as a FIFO movx @dptr,a; Denna kodrad läser databussen. ”turbo mode”

movx @dptr,a; Denna kodrad läser databussen. ”turbo mode”

movx @dptr,a; Denna kodrad läser databussen. ”turbo mode”

Varje movx @dptr,a gör samma som ett varv i loopen. Räknar upp adressen ett stege automatiskt.

Förklaringskod:

Loop: pipe[I] = datbuss // För varje gång en databussläsning adderas ett till i I = i +1

Jumpto Loop

Blid som visar hur ofta man utför 64 stycken läsningar från databussen. Detta sker i ”turbo mode”.

Övre bild visar 64 stycken läsningar.

Nedre bild visar fyra stycken läsningar

(20)

6.4 Koden i EZ-USB

Koden i EZ-USB:n bygger på principen att när det finns data att läsa läser den det och skickar det till PC:n. Genom en signal från en PALCE får EZ-USB:n reda på att data finns att läsa . Efter initieringen lägger sig programmet i en loop för att lyssna efter signalen från PALCEN. När signalen kommer hoppar programmet till en rutin. Rutinen läser av databussen och lägger det hämtade datat i en pipa (en array). När 64st avbrottsförfrågningar har inträffat aktiveras den pipan som man skrivit till. Det betyder att pipan ska skickas till PC:n. När pipan aktiverats (arrayen med data) hoppar programmet tillbaka och väntar på signal från PALCE. När den får den förstaavbrottsförfrågningen från PALCEN kontrollerar den att pipan inte håller på att bli skickad över USB:n. Om pipan är ledig börjar nästa inläsningsperiod med 64 stycken nya byte. Om pipan är upptagen inträffar ingen ny inläsning. För att inte data ska gå förlorat finns en FIFO ( minne) som sparar data då pipan är upptagen.

Kodens tre funktioner 1 Väntar på initieringsbyte 2 Initierar

3 Börjar ta in mätdata och skickar det till PC

Data till pipan kommer från A/D omvandlaren som skickar ut data seriellt med en hastighet på 1,2Mbit i sekunden. EZ-USB:n läser av data en byte åt gången, detta efter att data passerat en seriell/parallell omvandlare.

Med andra ord EZ-USB ska läsa en byte med en frekvens av 93,75kHz.

(750kHz/8).

(21)

6.5 Test av programmet.

I början testade vi vår kod genom att koppla upp EZ-USB-kortet mot ett

kopplingsdäck. Vi ville vara säkra på att EZ-USB:n utförde sin uppgift innan vi kopplade upp den mot A/D omvandlarna.

Vi skrev först en kod som använde sig av interruptfunktionen men det visade sig gå lite för sakta. Detta på grund av att 8051:an bara går i 24Mhz och varje instruktionscykel tar 1/6Mhz. Det tidskrävande med interrupt är faktum att man måste spara undan vissa register när man hoppar in i interruptrutinen (det tar 20st instruktionscyklar). Den tiden som det tar är för lång eftersom 8051:an endast har 63 stycken ((1/(40*(1/6M)=150k) instruktionscykler på sig innan

Vi beslöt oss att ändra taktik och övergick till en pollande kod. Istället för att ligga i en loop och vänta på ett interrupt så ligger koden i en loop och pollar en ingång till en port. När den pinnen går låg så exekverar den koden nedanför omedelbart. Inget behov för att spara undan register. På det sättet lyckades vi med att hinna läsa av databussen innan det kommer ett nytt värde på den. Det pollande alternativet är av mätsätten det som är effektivast för vårt ändamål.

6.6 Initieringskoden.

Då vi var nöjda med loopen som utförde datainsamlingen tittade vi på

möjligheterna att initiera AD7716 från EZ-USB:n. För att göra detta krävs att man läser in 16 stycken bitar som sedan läggs ut seriellt till A/D-omvandlarna.

Vi har gjort en kod och testkört den mot ett oscilloskop där den ser ut att fungera som den ska men vi har inte testkört den mot A/D-omvandlarna på grund av tidsbrist. Koden som utför initieringen går ut på att en port ska genera nödvändiga kontrollsignaler, klocka samt 16st initieringsbitar.

8 bitars databuss

KLOCKA

EZ-USB

Interrupt Databuss

USB KABEL KOPPLINGSDÄCK

EZ-USB

DEVELOPMENT

CARD

(22)

Vid uppstarten av programmet i EZ-USB:n ställde koden sig i en loop där den väntade på att något skulle bli nedskickat till den. Data som skickas till A/D- omvandlaren består av 2st byte (16 bitar). För att förenkla för EZ-USB:n skickade vi ner 16st byte från dll-filen där varje byte antingen var fylld med ettor eller nollor. Varje byte representerar en bit i inititeringskoden.

Exempelvis om bit 2 i initieringskoden är 0 så blir hela byte 2 som skickas ner

från PC:n 0. Kommandon som inte gjorde något fick läggas till så att man fick

en puls som hade symmetrin 50 % hög och 50 % låg.

(23)

7. DLL-fil

För att LabView skall kunna kommunicera med EZ-USB skrev vi en dll-fil.

För att kommunicera med EZ-USB:n använder PC:n en driver. Drivrutinen utför instruktioner som den får i form av program skrivna i kod. Koden skrivs i programmeringsspråket C. LabView kan inte tolka C kod, LabView kan dock ropa på funktioner i en dll-fil som innehåller C-kod. Eftersom det var första gången vi skrev ett program som jobbar mot en driver så medförde det en del utmaningar. Vi är mycket tacksamma mot Bengt-Arne Fjellner som alltid ställt upp och förklarat om metoder som används för att anropa en driver. Innan vi skrev dll-filen studerade vi medföljande programkod till ett program som utförde hämtning av data från USB:n

(http://www.cypress.com/usb/usbappnotes.html#performance ).

utvecklar program. Instabiliteten kunde leda till vissa omstartningsprocesser.

Det var till en början en ganska svårtolkad kod. Koden anropade drivrutinen via Windows. Kod som är skriven för att användas i ett operativsystem är mycket speciell. För att tolka koden korrekt fick vi lära oss om hur program som jobbar mot ett operativsystem är skrivet. Efter flera gånger hos Bengt- Arne Fjellner samt lite böcker från biblioteket så lyckades vi lista ut hur koden var uppbyggd. Koden innehöll mestadels kod som inte hade något med

drivrutinsanropet att göra. Den ”onödiga” koden innehöll olika typer av

Windows anrop t.ex. fönsterstorlek på programmet. Efter åtskilliga timmar

lyckades vi plocka fram det väsentliga ur exempelkoden. Med det väsentliga

från koden som grund började vi att skriva vår dll-fil. Att skriva en dll-fil är

inte speciellt svårt. Man kan säga att en dll-fil består av funktioner som andra

program kan ropa på. Att programmera en dll-fil skiljer sig inte så mycket från

att programmera ett vanligt C program.

(24)

Vi startade utvecklingen av dll-filen med att skriva ett program som öppnade drivrutinen till EZ-USB enheten. Det klarade vi av utan problem. Sedan fortsatte vi med att skriva ett program som hämtar data från EZ-USB, där uppstod problem. Datat kom in alldeles för sakta (50kB/s mot vårt mål

750kbit/s). Felsökning inleddes och vi analyserade hur ofta EZ-USB läste från databussen. Vi såg att den läste av databussen i skurar. Den läste av databussen med hög hastighet men sedan väntade den några millisekunder innan den

Efter lite hjälp av ett forum på Internet (http://www.usb.org) hittade vi felet.

När vi i vår dll-fil ropade efter data från EZ-USB så ropade vi efter 64 byte.

PC:n frågar med några millisekunders mellanrum om EZ-USB:n har något att sända. Om EZ-USB:n hade något att sända tog PC:n enbart emot 64 byte. När vi ändrade i dll-filen så att den frågade efter 1024 byte per gång så steg

hastigheten ända till 1,7Mbit/s. Nu frågade PC:n efter 1024 byte och EZ-USB skickade 16*64 byte innan den blev tvungen att vänta på PC:n några

millisekunder.

Nu när vi kunde ta emot data med en hög hastighet via USB så saknade vi förmågan att kunna skicka data till EZ-USB:n. Tack vare våra tidigare erfarenheter så gick det smärtfritt att skicka data till USB:n. Vi löste det i dll- filen med en liknade kod som när vi skickade koden. När man ropar på en extern enhet i Windows använder man en så kallad IOCTL (Input Output COnTroL).

BOOL DeviceIoControl(

HANDLE hDevice, // handle till enheten

DWORD dwIoControlCode, // operationskod som enheterna ska utföra.

LPVOID lpInBuffer, // pekare till buffer med indata DWORD nInBufferSize, // storlek på indata

LPVOID lpOutBuffer, // pekare till buffer som tar emot utdata

DWORD nOutBufferSize, // storlek på utdata

LPDWORD lpBytesReturned, // pekare till variabel som räknar antalet utkommande byte.

// byte count

LPOVERLAPPED lpOverlapped // pekare till överlappad struktur för asynkron operation

);

(25)

innehåller data mellan EZ-USB och PC:n. Med programkoden menas den kod som man oftast får bränna in i ett ROM minne t.ex. Microchips pic-

processorer. Men i en EZ-USB kommer koden via USB-kabeln, bra tänkt av ingenjörerna på Cypress. Nedladdningen av programkoden via en USB kabel medför att det är enkelt att uppgradera programvaran i framtiden.

Försök gjorde också att få ner koden via en speciell drivrutin gjordes också.

När man trycker in EZ-USB:ns USB kabel hittar Windows EZ-USB:n. Den speciella drivrutinen laddar ner data till EZ-USB:ns minne. Efter

nedladdningen av programkoden simulerar EZ-USB:n en utryckning av USB- kabeln. När den simulerar en intryckning igen så frågar EZ-USB:n efter den riktiga drivrutinen. EZ-USB:n frågar alltså först efter en drivrutin som laddar ner koden kopplar upp sig på nytt och frågar efter den ”riktiga” drivrutinen.

För att göra en drivrutin krävs Windows Driver Development Kit (DDK). Det visade sig vara mycket svårt att få DDK att fungera. När vi installerade DDK genererades mängder av felmeddelanden . Vi skrev e-mail till Cypress och talade om det för dem. Svaret blev att de inte förstod hur det kunde inträffa.

När vi fått svaret bestämde vi oss för att försöka andra, i våra ögon mindre

(26)

7.1 Översikt av koden

Dll-filen och dess huvuduppgifter 1. Öppnar drivrutinen

2. Sätter interface mot EZ-USB 3. Tar in mätdata

4. Stänger drivrutinen

I den medföljande koden finns flera funktioner som inte används men som använts för att försöka ladda ner koden till EZ-USB:n via dll-filen. Men nedladdning via dll-filen fick vi inte utförd korrekt därför används ett externt program för det. Det skall dock vara möjligt att ladda ner koden via dll-filen utan att behöva ropa på ett program som gör det. Dll-koden innehåller också en testrutin som inte använts än. Testrutinen kontrollerar att dom tre först bitarna i var fjärde byte är likadana. A/D omvandlarna skickar 22 bitar data och 10 kontrollbitar. Tre av dom 10 bitarna talar om vilket chip dom kommer ifrån. Vi använder bara ett chip när vi testkör så därför ska dom vara likadana hela tiden.

Är de tre bitarna inte likadana så kommer ett felmeddelande att genereras.

(27)

8. LabView

LabView är det program som presenterar mätdata för oss. Det vi jobbade minst med var LabView. Vi gjorde inga avancerade LabView scheman, dom är relativt enkla och vi hade ju goda kunskaper om LabView sedan tidigare.

Vårat LabView program består av fyra delar.

1 Öppnar driver

2 Skickar initieringsdata till drivrutinen

3 Tar emot mätdata från drivrutinen. Mäter också hur snabb bithastigheten är. Hastigheten mäts genom att titta hur länge det tar att hämta läsa en 4 När mätningarna är klara stänger programmet drivrutinen.

Vi lade också till en graf som ritade ut indata men den påverkade

bithastigheten negativt (halverade) så vi tog bort den igen. Med tanke på att den påverkade bithastigheten har vi tänkt oss göra så mycket av sorteringen av data i dll-filen. Efter sorteringen så kan mätdatat presenteras i LabView.

För att mäta data med våran mätutrustning behöver man absolut inte vara

ingenjör. Det enda man behöver göra är att trycka in USB-kontakten , starta

LabView och trycka på play. Mycket enkelt, alla kan göra det.

(28)

9. Övergripande om USB

USB Universal Serial Bus är en typ av kommunikationsinterface mellan datorer och till exempel möss, skrivare, scanners m.m. Det var fyra av världens största företag inom mjuk- och hårdvara: Compaq, Intel, Microsoft och NEC som i början av 1990-talet kom överens om en ny standard för snabb, seriell

USB består av fyra trådar. En positiv och en negativ signalledare, samt de två återstående som är +5 volt och jord för strömförsörjning av små

effektförbrukare. USB kan försörja enheter med maximalt 500mA. Maximal överföringshastighet är 12Mbit/s. Det har också kommit en nyare version av USB som kallas USB 2.0 den klarar av hastigheter på 480Mbit/s.

Systemet kan också bestå av bara en t.ex. USB-anpassad skrivare kopplade till en PC, eller också ett flertal USB-enheter kopplade via USB-hubbar till en PC.

Inkoppling av enheter är mycket enkel man behöver inte ens slå av PC:n, och den känner automatiskt av den nyinkopplade hårdvaran och börjar leta efter dess drivrutiner.

Signalnivåerna i signalledningarna skiftar hela tiden enligt ett differentierat mönster och det är då spänningsskillnaden överstiger 3 V som en etta

detekteras. Inkodad i signalerna ligger även klocksignalen som är kodad enligt NRZI som betyder att ingen förändring är en nolla och förändring är en etta.

All data skickas i ”paket” som föregås av några protokollfält. Först av dessa ska ett SYNC-fält på 8 bitar skickas som synkroniserar de båda enheternas klockor.

Efter detta sync-fält kommer ett PID-fält, vilket är identifieringsfältet, även

detta på 8 bitar. Identifieringsfältet innehåller informationen om typ av paket

som följer, paketets format, och typ av felhantering i paketet. Alltihop avslutas

med EOP som signalerar att paketet är slut. Bitordningen i paket är att LSB

alltid kommer först och MSB sist.

(29)

10. Spänningsmatning

De olika spänningar som behövs i systemet är följande:

+5V, matning till de flesta kretsarna – 5V, negativ matning till AD7716

+2,5V, referensspänning till AD7716 och matning till signalförstärkning – 2,5V, matning till signalförstärkning

Hela systemet är tänkt att kunna matas från USB-kabeln som har en

strömförsörjningskabel som kan lämna upp till 500mA och har en spänning på +5V. För att skapa negativ spänning används en spänningsomvandlare

MAX660 som även kan användas till spänningsinverterare. Genom en enkel

spänningsdelning med två lika store resistorer skapas spänningarna +2,5V

respektive –2,5V, efter spänningsdelningen kopplas även en spänningsföljare

in för att ej belasta spänningsdelningskopplingen.

(30)

11. Litteraturförteckning

Titel Författare Förläggare Årtal ISBN

WIN32

Programming API BIBLE

Richard Simon Michael Gouker Brian Barney

The Waite group 1995 1-57169-009-3

The EZ-USB Technical

Reference manual

Cypress Cypress 1999 -

Universal Serial Bus System Architecture

Don Anderson Addison-Wesley 1997 0-201-46137-4

ELFA katalog nr.

48

Elfa AB Stibo graphic 1999 91-88032-22-1

Electronic Devices Thomas L. Floyd Prentice Hall 1999 0-13-973769-3 Digital

Fundamentals

Thomas L. Floyd Prentice Hall 1997 0-13-573478-9

VHDL för konstruktion

Lennart Lindh Stefan Sjöholm

Studentlitteratur 1994

ISRN Utrustning för

mätning av vibrationer i terränggående fordon

Tobias Lagander Fredrik Brännström

Examensarbete 2000 LTU-HIP-EX--

00/36--SE

(31)

BILAGA 1 PALCE PROGRAM

(32)

--Palce program för handskakning vid datasändning mellan A/D-omvandlare (AD7716) och EZ-USB --Av: Fredrik Lindberg & Mats Eriksson

--Luleå tekniska universitet, Institutionen i Skellefteå library ieee;

use ieee.std_logic_1164.all;

entity Interface is

port(DRDY, CASCOUT, SCLK : in std_logic; --Definierar ingångar CASCIN, RFS : out std_logic); --Definierar utgångar attribute loc : string;

attribute loc of SCLK : signal is "P1";

attribute loc of DRDY : signal is "P2";

attribute loc of CASCOUT : signal is "P3";

attribute loc of RFS : signal is "P15";

attribute loc of CASCIN : signal is "P21";

end;

architecture Beteende of Interface is

subtype statetype is integer range 0 to 3; --Deklarerar states signal state, nextstate : statetype;

begin

process (state, CASCOUT, DRDY, SCLK) begin

case state is

when 0 => CASCIN <= '0'; RFS <= '1';--Stå kvar i detta state tills DRDY går låg, RFS ligger hög if DRDY = '1' then

nextstate <= 0;

elsif DRDY = '0' then nextstate <= 1;

end if;

when 1 => nextstate <= 2; CASCIN <= '1'; RFS <= '1'; --Skickar en signal på CASCIN when 2 => nextstate <= 3; CASCIN <= '0'; RFS <= '1';

when 3 => CASCIN <= '0'; RFS <= '0'; --Ligger i detta state medan AD7716 skickar data, --lägger RFS låg under tiden

if CASCOUT = '0' then

nextstate <= 3; --Så länge som CASCOUT ligger låg så står den --kvar i state 3

elsif CASCOUT = '1' then --När CASCOUT går hög nextstate <= 0; --hoppar den tillbaka till state 0 end if;

end case;

if rising_edge(SCLK) then --Hoppar till nästa state vid positiv flank på SCLK state <= nextstate;

end if;

end process;

end Beteende;

(33)

--Av: Fredrik Lindberg & Mats Eriksson

--Luleå tekniska universitet, Institutionen i Skellefteå library ieee;

use ieee.std_logic_1164.all;

entity Krets is

port(brytare, clk, tfs2, fc0, fc1, fc2 : in std_logic; --Definierar ingångar sdata, tfs, invtfs : out std_logic); --Definierar utgångar

attribute loc : string; --Bestämmer bennummer

attribute loc of clk : signal is "P1"; --Ingångar attribute loc of brytare : signal is "P2";

attribute loc of tfs2 : signal is "P4";

attribute loc of fc0 : signal is "P9";

attribute loc of fc1 : signal is "P10";

attribute loc of fc2 : signal is "P11";

attribute loc of tfs : signal is "P21"; --Utgångar attribute loc of sdata : signal is "P22";

attribute loc of invtfs : signal is "P23";

end;

architecture Beteende of Krets is subtype statetype is integer range 0 to 18;

signal state, nextstate : statetype;

begin

invtfs <= not tfs2; --Bygla tfs till tfs2, inverterar tfs, egentligen onödigt...

process(state, clk, brytare, fc0, fc1, fc2) begin

case state is

when 0 => sdata <= '-'; tfs <= '1'; --Ligger i detta state tills brytaren trycks in, sdata dont care if brytare = '0' then

nextstate <= 0;

elsif brytare = '1' then nextstate <= 1;

end if;

when 1 => nextstate <= 2; sdata <= '0'; tfs <= '0'; --Bit 0, 0, Valid word when 2 => nextstate <= 3; sdata <= '0'; tfs <= '0; --Bit 1, x

when 3 => nextstate <= 4; sdata <= '0'; tfs <= '0'; --Bit 2, x when 4 => nextstate <= 5; sdata <= '0'; tfs <= '0'; --Bit 3, x when 5 => nextstate <= 6; sdata <= '0'; tfs <= '0'; --Bit 4, x

when 6 => nextstate <= 7; sdata <= '0'; tfs <= '0'; --Bit 5, DOUT1, kontrollerar D2 when 7 => nextstate <= 8; sdata <= '1'; tfs <= '0'; --Bit 6, DOUT2, kontrollerar D1 when 8 => nextstate <= 9; sdata <= fc0; tfs <= '0'; --Bit 7, FC0, Brytfrekvens when 9 => sdata <= '-'; tfs <= '1'; --Låga byten skickad, lägg TFS låg

if brytare = '1' then --Vänta till brytaren släpps upp nextstate <= 9; --Hoppa då till state 10 elsif brytare = '0' then --och skicka höga byten

nextstate <= 10;

end if;

when 10 => nextstate <= 11; sdata <= '1'; tfs <= '0'; --Bit 8, 1, Valid word when 11 => nextstate <= 12; sdata <= fc1; tfs <= '0'; --Bit 9, FC1, Brytfrekvens when 12 => nextstate <= 13; sdata <= fc2; tfs <= '0'; --Bit 10, FC2, Brytfrekvens when 13 => nextstate <= 14; sdata <= '1'; tfs <= '0'; --Bit 11, M0, Ignorera adressbitar when 14 => nextstate <= 15; sdata <= '0'; tfs <= '0'; --Bit 12, A0, Adressbit

when 15 => nextstate <= 16; sdata <= '0'; tfs <= '0'; --Bit 13, A1, Adressbit

when 16 => nextstate <= 17; sdata <= '0'; tfs <= '0'; --Bit 14, A2, Adressbit

(34)

end case;

if rising_edge(clk) then --Hoppar till nästa state vid positiv flank på klockan state <= nextstate;

end if;

end process;

end Beteende;

--När kretsen får en positiv flank på ingången brytare så skickas den 1:a byten iväg --och när en negativ flank kommer skickas den 2:a iväg

--Det var ju betydligt smidigare att göra detta med en

--det med två skiftregister och massor med andra kretsar som vi gjorde först...

(35)

--Av: Fredrik Lindberg & Mats Eriksson

--Luleå tekniska universitet, Institutionen i Skellefteå library ieee;

use ieee.std_logic_1164.all;

entity Readstrobe is

port(CLK, strobein : in std_logic; --Deklarerar ingångar strobeut : out std_logic); --Deklarerar utgångar end;

architecture Beteende of Readstrobe is subtype statetype is integer range 0 to 3;

signal state, nextstate : statetype;

begin

process (state, CLK, strobein) begin

case state is

when 0 => strobeut <= '0'; --Ligger i state 0 och väntar på strobein if strobein = '1' then --Om signal kommer på strobin

nextstate <= 1; --Gå till state 1 elsif strobein = '0' then --Om ej signal

nextstate <= 0; --Ligg kvar i state 0 end if;

when 1 => nextstate <= 2; strobeut <= '1'; --Lägg strobeut hög i två klockcykler when 2 => nextstate <= 3; strobeut <= '1';

when 3 => nextstate <= 0; strobeut <= '0'; --Lägg strobeut låg end case;

if rising_edge(CLK) then --Hoppa till nästa state på positiv flank på CLK state <= nextstate;

end if;

end process;

end Beteende;

(36)

BILAGA 2 EZ-USB PROGRAM

(37)

Lagg upp startadress

Initiera ”turbo mode”

Initiera port A och C

Vanta på initieringsdata som ska skickas till A/D

Initiera A/D

Ta in 63 byte data från A/D via databussen

Ladda pipan för sändning. Ta in 64 byte igen

Kolla att pipan är tom Vänta på första signal

Ta in en byte

Vänta på signal

(38)

$NOMOD51 ;tabort forutbestamda 8051 registers

;$nolist

$INCLUDE (REG320.INC)

$include (ezregs.inc) ; NAME bulkfxfr

;

ISEG AT 80H ; stack stack: ds 20

CSEG AT 0 ; absolute Segment at Address 0 LJMP start ; Hoppa over interrupt vektorena0

; ---

; org 200H

start: mov SP,#STACK-1 ; stack

;

;;

mov a,CKCON

anl a,#11111000b ; snabbaste MOVX cycles--b2b1b0=000 mov CKCON,a

mov dptr,#FASTXFR

mov a,#01000000b ; b7 0 ingen snabb ISO

; b6 1 aktivera snabb BULK

; b5 0 FRD# aktivt lag

; b43 00 1 clk FRD# strobe

; b2 0 FWR# aktivt lag movx @dptr,a

;

;

; valj Pa5 till turbo transfer strobe

;

;setb uisbcs.7 ; alternate mode 1 mov dptr,#PORTACFG movx a,@dptr

orl a,#00110000b ; frd och fwr movx @dptr,a

mov dptr,#OEA

mov a,#11001111b ; 1 = ut. 1 betyder att det blir en utågng movx @dptr,a

mov dptr,#OUTA ; 3 instruktioncykler

mov a,#11111111b ; 2 instruktionscykler

movx @dptr,a ; 2 instruktioncykler

(39)

mov dptr,#OUTC

mov a,#11111111b ; 1 = 5 V movx @dptr,a

;

; Polla ingangen tills initiering paborjas

;

inloop: mov dptr,#OUT2CS movx a,@dptr

jb acc.1,inloop ; EP2OUT is busy++keep looping

;

; Borja inititeringen

;

mov dptr,#OUTA ; 3 cycles

mov a,#00000000b ; dags for inititering (TFS) ligger lag vid initiering movx @dptr,a ; 2 cycles

; Hamtar in data fran PC:n. Gor en OR pa det med #01110000 vilket gor att datat kommer

; ut pa bitarna 0-3. Bitarna 4-6 ar genererar klocksignalen. Bit 7 lagger sig lag under initiering.

; Samma procedur gors 16 ganger. Detta skullle kunna ske med en loop men det gora att klockfrekvensen

; blir lagre. Vi efterstravar sa hog klockfrekvens som mojligt.

mov dptr, #OUT2BUF ; Hamtar in byte nr 1 som kommit in fran PC:n movx a,@dptr

orl a,#01110000b ; 2 cycles ger initieringsrekvens pa 24 cycles => 250kHz

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

; 4 stycken dummys har lagts till så att utsignalen blir symmetrisk

nop ; dummy 1 cycles

mov r6, 2 ; dummy 2 cycles mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+1 ; 3 cycles

movx a,@dptr ; 2 cycles

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+2 movx a,@dptr

orl a,#01110000b ; 2 cycles

(40)

movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+3 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+4 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+5 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles

mov r6 ,2 ; dummy 2 cycles

(41)

nop ; 1 cycles mov r6, 2 ; dummy 2 cycles

mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+7 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+8 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+9 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+10 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles

(42)

nop ; 1 cycles mov r6, 2 ; dummy 2 cycles

mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+11 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cy cles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+12 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+13 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles

mov r6 ,2 ; dummy 2 cycles

anl a,#00001111b ; 2 cycles

mov dptr,#OUTC ; 3 cycles

(43)

mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

mov dptr, #OUT2BUF+15 movx a,@dptr

orl a,#01110000b ; 2 cycles

;mov a, r6

mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

nop ; 1 cycles

mov r6, 2 ; dummy 2 cycles mov r6 ,2 ; dummy 2 cycles anl a,#00001111b ; 2 cycles mov dptr,#OUTC ; 3 cycles movx @dptr,a ; 2 cycles

; Lagger PORT C hog mov dptr,#OUTC

mov a,#11111111b ; 1 = 5 V movx @dptr,a

mov dptr,#OUTA ; 3 cycles

mov a,#11111111b ;Slut med inititering (TFS hog ) movx @dptr,a ; 2 cycles

;;;;;;;;;;;; MATLOOP ;;;;;;;;;;;;;;;;;;;;;;;;;;

mov dptr,#AUTOPTRH ; initialisera autopointer till pipa 2 IN2BUF.

;Laser in hoga adressen till ;“turbo mode”

mov a,#HIGH(IN4BUF) movx @dptr,a

loop:

mov r7,#63 ;Start the filling of ep 4 ; Lagger 64 till register som anvands for nerrrakning mov dptr,#AUTOPTRL ; initialisera autopointer till pipa 2 IN2BUF

;Laser in laga adressen till ;“turbo mode”

mov a,#LOW(IN4BUF) movx @dptr,a

w1: mov dptr,#PINSC ; poll the interrupt Lagger sig och vantar pa att interrupt movx a, @dptr ; denna koll tar 9 st instruktionscyklar

jnb acc.3,w1

wa: mov dptr,#IN4CS ; poll the EP4-IN Status

; Kollar om pipan ar ledig skrivning maste goras nar den ar ledig movx a,@dptr

jb acc.1,wa ; hog ? Fortsatt loopa

mov dptr,#AUTODATA ; anvander nu IN2BUF som en FIFO

movx @dptr,a; Denna rutin laser in det som finns pa databussen ”turbo transfer”

(44)

; Nu hoppar den in i en rutin som laser in data fran databussen efter att den blivit last en gang for varje ; ; ;

; gang som pipan ska fyllas. Man gor detta for att pipan inte behovar kollas efter att man kollat den en ; ;

; gang. Pipan rymmer 64 byte.

w4: mov dptr,#PINSC ; polla interrupt movx a, @dptr

jnb acc.3,w4

mov dptr,#AUTODATA ; anvander nu IN2BUF som en FIFO movx @dptr,a

djnz r7, w4; fyll pipan sa den har 64 byte

mov dptr,#IN4BC ; Tala om att pipan ar redo for sandning mov a,#64

movx @dptr,a ;Ladda pipan sa den kan skicka det till pc:n sjmp loop; Hoppa tillbaka till borjan

END

(45)

BILAGA 3 DLL PROGRAM

(46)

Flöde i dll.

Man kan säga att –dll innhåller tre stycken funktioner som anropas. Det är inte ett måste att anropa dessa funktioner så därför kallar vi det inte ett flödesschema.

Öppnar driver

Lägger interface mot EZ-USB

Stoppar EZ-USB

Tankar ned kod till den

Startar den

Sänder data som ska initiera A/D:na

Hämtar data från EZ-USB

Stänger driver.

(47)

/*

* Dll med funktioner som utfor kommunikation med EZ-USB.

*/

//---include---

#define MAX_FILE_SIZE (1024*8)

#define WINDOWS_LEAN_AND_MEAN

#include <windows.h>

#include <malloc.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include "ezusbsys.h"

//#include <usb100.h>

#include <assert.h>

#include <process.h>

#include <winioctl.h>

#include " main.h"

#include " resource.h"

#include " mysql.h"

//--- varibler ---

// Anvants for att testa om det gar att tanka ner koden till EZ-USB som en buffer fran dll-filen.

/*INTEL_HEX_RECORD buffer[] = { 3,

0x0, 0,

{0x02,0x02,0x00}, 16,

0x200, 0,

{0x75,0x81,0x7f,0xe5,0x8e,0x54,0xf8,0xf5,0x8e,0x90,0x7f,0xe2,0x74,0x40,0xf0,0x90}, 16,

0x210, 0,

{0x7f,0x93,0xe0,0x44,0x30,0xf0,0x90,0x7f,0x9c,0x74,0xcf,0xf0,0x90,0x7f,0x96,0x74}, 16,

0x220, 0,

{0xff,0xf0,0x90,0x7f,0x95,0xe0,0x44,0x08,0xf0,0x90,0x7f,0x9e,0x74,0xf7,0xf0,0x90}, 16,

0x230, 0,

{0x7f,0x98,0x74,0xff,0xf0,0x90,0x7f,0xc8,0xe0,0x20,0xe1,0xf9,0x90,0x7f,0x96,0x74}, 16,

0x240, 0,

{0x00,0xf0,0x90,0x7d,0xc0,0xe0,0x44,0x70,0x90,0x7f,0x98,0xf0,0x00,0xae,0x02,0xae}, 16,

0x250, 0,

{0x02,0xae,0x02,0x54,0x0f,0x90,0x7f,0x98,0xf0,0x90,0x7d,0xc1,0xe0,0x44,0x70,0x90}, 16,

0x260,

0,

(48)

0x270, 0,

{0xc2,0xe0,0x44,0x70,0x90,0x7f,0x98,0xf0,0x00,0xae,0x02,0xae,0x02,0x54,0x0f,0x90}, 16,

0x280, 0,

{0x7f,0x98,0xf0,0x90,0x7d,0xc3,0xe0,0x44,0x70,0x90,0x7f,0x98,0xf0,0x00,0xae,0x02}, 16,

0x290, 0,

{0xae,0x02,0x54,0x0f,0x90,0x7f,0x98,0xf0,0x90,0x7d,0xc4,0xe0,0x44,0x70,0x90,0x7f}, 16,

0x2a0, 0,

{0x98,0xf0,0x00,0xae,0x02,0xae,0x02,0x54,0x0f,0x90,0x7f,0x98,0xf0,0x90,0x7d,0xc5}, 16,

0x2b0, 0,

{0xe0,0x44,0x70,0x90,0x7f,0x98,0xf0,0x00,0xae,0x02,0xae,0x02,0x54,0x0f,0x90,0x7f}, 16,

0x2c0, 0,

{0x98,0xf0,0x90,0x7d,0xc6,0xe0,0x44,0x70,0x90,0x7f,0x98,0xf0,0x00,0xae,0x02,0xae}, 16,

0x2d0, 0,

{0x02,0x54,0x0f,0x90,0x7f,0x98,0xf0,0x90,0x7d,0xc7,0xe0,0x44,0x70,0x90,0x7f,0x98}, 16,

0x2e0, 0,

{0xf0,0x00,0xae,0x02,0xae,0x02,0x54,0x0f,0x90,0x7f,0x98,0xf0,0x90,0x7d,0xc8,0xe0}, 16,

0x2f0, 0,

{0x44,0x70,0x90,0x7f,0x98,0xf0,0x00,0xae,0x02,0xae,0x02,0x54,0x0f,0x90,0x7f,0x98}, 16,

0x300, 0,

{0xf0,0x90,0x7d,0xc9,0xe0,0x44,0x70,0x90,0x7f,0x98,0xf0,0x00,0xae,0x02,0xae,0x02}, 16,

0x310, 0,

{0x54,0x0f,0x90,0x7f,0x98,0xf0,0x90,0x7d,0xca,0xe0,0x44,0x70,0x90,0x7f,0x98,0xf0}, 16,

0x320, 0,

{0x00,0xae,0x02,0xae,0x02,0x54,0x0f,0x90,0x7f,0x98,0xf0,0x90,0x7d,0xcb,0xe0,0x44}, 16,

0x330, 0,

{0x70,0x90,0x7f,0x98,0xf0,0x00,0xae,0x02,0xae,0x02,0x54,0x0f,0x90,0x7f,0x98,0xf0}, 16,

0x340,

0,

(49)

{0xf0,0x90,0x7d,0xce,0xe0,0x44,0x70,0x90,0x7f,0x98,0xf0,0x00,0xae,0x02,0xae,0x02}, 16,

0x379, 0,

{0x54,0x0f,0x90,0x7f,0x98,0xf0,0x90,0x7d,0xcf,0xe0,0x44,0x70,0x90,0x7f,0x98,0xf0}, 16,

0x389, 0,

{0x00,0xae,0x02,0xae,0x02,0x54,0x0f,0x90,0x7f,0x98,0xf0,0x90,0x7f,0x98,0x74,0xff}, 16,

0x399, 0,

{0xf0,0x90,0x7f,0x96,0x74,0xff,0xf0,0x90,0x7f,0xe3,0x74,0x7d,0xf0,0x7f,0x3f,0x90}, 16,

0x3a9, 0,

{0x7f,0xe4,0x74,0x00,0xf0,0x90,0x7f,0x9b,0xe0,0x20,0xe3,0xf9,0x90,0x7f,0xbc,0xe0}, 16,

0x3b9, 0,

{0x20,0xe1,0xf9,0x90,0x7f,0xe5,0xf0,0x90,0x7f,0x9b,0xe0,0x20,0xe3,0xf9,0x90,0x7f}, 12,

0x3c9, 0,

{0xe5,0xf0,0xdf,0xf3,0x90,0x7f,0xbd,0x74,0x40,0xf0,0x80,0xd1}, 0,

0x0, 1, {0}

};

*/

int numread = 0;

unsigned char buffer[MAX_FILE_SIZE];

char DownloadFilename[256] = "ezbulk.hex";// "ali2001.c" ; FILE *fp;

// Vissa ar inte I bruk just nu HANDLE hDevice = NULL;

int p,a;

int svar = 0;

char devname[64] ="Ezusb-0";

UCHAR outPattern, inPattern;

UCHAR outBuffer[64], inBuffer[4096];//1024 BULK_TRANSFER_CONTROL bulkControl;

SET_INTERFACE_IN interfaceControl;

ANCHOR_DOWNLOAD_CONTROL downloadControl;

VENDOR_REQUEST_IN myRequest;

BOOLEAN bResult = FALSE;

WORD outPacketSize = 16 , inPacketSize = 4096;//1024;//64; // 1(8) byte ska skickas iväg WORD adress = 0x0000, size200 = 469, size0 = 3 ; //size = 469;

int nBytes = 0;

int i, test, testsvar;

ULONG pipe = 7;

UCHAR inter, alt;

//--- BOOL WINAPI DllEntryPoint(

HINSTANCE hinstDLL, // handle till dll:en

DWORD fdwReason, // varfor man kallar dll

(50)

{

// Dummy - måste finnas för annars kommer visual att ta bort // floating-point supporten

double t;

for (t = 0; t < 2.0; t += 1.0) ; // OK

return 1;

}

//--- Initiering och Connect --- /* Ansluter till drivern

*

* In: Inget

*

* return : ett ifall det gick bra, annars noll.

*/

int open_driver() {

char completeDeviceName[64] = "";

char pcMsg[64] = "";

strcat (completeDeviceName,"\\\\.\\");

strcat (completeDeviceName, devname);

s = 1;

hDevice = CreateFile( completeDeviceName, GENERIC_WRITE,

FILE_SHARE_WRITE, NULL,

OPEN_EXISTING, 0,

NULL);

if (hDevice == INVALID_HANDLE_VALUE) { return (12);

} else {

// Lagger interface mot EZ-USB inter = 0;

alt = 1;

interfaceControl.interfaceNum = inter;

interfaceControl.alternateSetting = alt;

bResult = DeviceIoControl (hDevice, // 0

IOCTL_Ezusb_SETINTERFACE, // 1

(51)

// Kod som forsoker att tanka ner kallkoden till EZ-USB

/* myRequest.bRequest = 0xA0;

myRequest.wValue = 0x7F92;

myRequest.wIndex = 0x00;

myRequest.wLength = 0x01;

myRequest.bData = 1; //reset hold myRequest.direction = 0x00;

// Stannar EZ-USB for nedtanking av kod bResult = DeviceIoControl (hDevice,

IOCTL_Ezusb_VENDOR_REQUEST,

&myRequest,

sizeof(VENDOR_REQUEST_IN), NULL,

0,

(unsigned long *)&nBytes, NULL);

if(bResult != TRUE) return 5;//

// Laser in koden I en buffer

if ((fp = fopen(DownloadFilename,"rb")) != NULL) {

numread = fread(buffer,sizeof(char),MAX_FILE_SIZE,fp);

fclose(fp);

} else

return 9;//svar // Tankar ner koden till given adress

downloadControl.Offset = adress;

bResult = DeviceIoControl (hDevice,

IOCTL_EZUSB_ANCHOR_DOWNLOAD,

&downloadControl,

sizeof(ANCHOR_DOWNLOAD_CONTROL), buffer,

numread,

(unsigned long *)&nBytes, NULL);

// Sparkar igang EZ-USB igen

myRequest.bRequest = 0xA0;

myRequest.wValue = 0x7F92;

myRequest.wIndex = 0x00;

myRequest.wLength = 0x01;

myRequest.bData = 0; //reset release myRequest.direction = 0x00;

bResult = DeviceIoControl (hDevice,

IOCTL_Ezusb_VENDOR_REQUEST,

&myRequest,

sizeof(VENDOR_REQUEST_IN), NULL,

0,

(52)

if(bResult != TRUE)

return 5; // Error nummer 5 // Slut pa nedtanknigsforsoket */

}

return 1 // Om allt gick bra skicka ett tillbaka }

//--- Skickar data till EZ-USB med bulk --- /* Skickar bulk data till usb

*

* In: Inget

*

* return : ett ifall det gick bra, annars noll.

*/

int send_bulk(int usbdata) {

pipe = 2; // Vilken pipa som ska utfora sandingen bulkControl.pipeNum = pipe;

outBuffer[0] = usbdata;

// Perform the BULK OUT

bResult = DeviceIoControl(hDevice, // 0 IOCTL_EZUSB_BULK_WRITE, // 1

&bulkControl, // 2 pekare

sizeof(BULK_TRANSFER_CONTROL), // 3

&outBuffer[0], // 4 buffer med data ut

outPacketSize, // 5 byte utdata

&nBytes, // 6

NULL); // 7

if(bResult != TRUE) return 0;

return 1;

}

(53)

//--- Tar emot data fran EZ-USB med bulk --- /* Tar emot bulk data fran usb

*

* In: Inget

*

* return : ett ifall det gick bra, annars noll.

*/

int recive_bulk(char * data {

pipe = 3;

bulkControl.pipeNum = pipe;

bResult = DeviceIoControl (hDevice, // 0

IOCTL_EZUSB_BULK_READ, // 1

&bulkControl, // 2 pipnummer

sizeof(BULK_TRANSFER_CONTROL), // 3

&inBuffer[0], // 4 buffer

inPacketSize, // 5 storlek pa buffer

&nBytes, // 6

NULL); // 7

svar = (int)inBuffer[0];

/*//testloop for att kolla om det ar ratt foljd pa datat. Var fjarde byte innehaller tre likadan bitar. Om det ej ar sa kommer ett felmeddelande att visas.

for (i=0; i <= 1023; i++ ) {

if (i == 0 ) {

test = (int)inBuffer[0];

testsvar = ( test & 0x07 ); // 0x07 = 00000111b }

i = i+4;

test = (int)inBuffer[i];

if ( test != testsvar ) return i;

}*/

strcpy(data,inBuffer);

return svar;

}

//--- close_driver --- /*

* Stänger drivern

*

(54)

int close_driver() {

CloseHandle (hDevice);

return 1;

}

(55)

BILAGA 4 LABVIEW SCHEMAN

(56)

Flödesschema över LabView

Visar vilka kommandom som skickas till –dll filen

Öppna driver

Skicka initieringsdata

Ta emot data till stopp trycks ner.

Om stopp intryckt

stäng drivern.

(57)
(58)
(59)
(60)
(61)

BILAGA 5 KOPPLINGSSCHEMAN

(62)
(63)
(64)
(65)
(66)
(67)

References

Related documents

Skickat: den 30 mars 2012 17:24 Till: Olof Junesjö Kommunkontoret Ämne: Workshop.

Genom att använda två värdkontroller-chipset fördelade över två portar istället för fyra dedikerar detta 4-ports PCIe till USB 3.1-kort upp till 10 Gbps för varje uppsättning

• If you use an audio source/ hifi system which lacks a connection for a record player (RIAA), set the [ PHONO EQ / THRU ON ] switch (15) to PHONO EQ. The record player connection

Med stöd för USB PD 3.0 (upp till 60 W), ger USB Type-C-multiportadaptern dig möjligheten att strömförse och ladda din bärbara dator, samt strömförse din kringutrustning, när du

Denna USB-C-kabel klarar av den dagliga påfrestningen av att ladda och synkronisera dina mobila enheter.. Den robusta kabeln är kompatibel med dina Thunderbolt 3 portar och är ett

- När avspelningen slutar så stiger tonarmen upp från skivytan och återvänder till sin hållare..

Denna 4-portars USB 3.0-hubb förvandlar din bärbara eller stationära dators USB-A-port till två vanliga USB-A-portar - en USB-A snabbladdnings port och en USB-C™-port.. Hubb

Utöka anslutningen till din USB-C bärbara dator med den nya generationen USB-C Gen 2 hubb med 10 Gbit/s stöd för ökad bandbredd till anslutna enheter och..