Miskolci Egyetem Gépészmérnöki és Informatikai Kar Villamosmérnöki Intézet Elektrotechnikai-Elektronikai Intézeti Tanszék Villamosmérnöki szak Elektronikai tervezés és gyártás szakirány Olcsó digitális oszcilloszkóp megvalósítása STM32 mikrovezérlő segítségével Szakdolgozat Tősér Tibor II8RJT 2014 1
1. A szakdolgozat módosítása: szükséges nem szükséges (a megfelelő rész aláhúzandó) Miskolc, tervezésvezető aláírása 2. A tervezést legalább 4 alkalommal ellenőriztem: tervezésvezető aláírása 3. A szakdolgozat beadható nem adható be Miskolc, konzulens aláírása 4. A szakdolgozat tervezésvezető aláírása szövegoldalt, db külön mellékelt rajzot, egyéb mellékletet tartalmaz. 5. A szakdolgozat bírálatra bocsátható nem bocsátható A bíráló neve:.. Miskolc, tanszékvezető aláírása 6. Osztályzat: a bíráló javaslata:.... a tanszék javaslata:.... a Záróvizsga Bizottság döntése:.... Miskolc,... a Záróvizsga Bizottság elnökének aláírása 2
Eredetiségi nyilatkozat Alulírott Tősér Tibor (neptun kód: II8RJT) a Miskolci Egyetem Gépészmérnöki és Informatikai Karának végzős szakos hallgatója ezennel büntetőjogi és fegyelmi felelősségem tudatában nyilatkozom és aláírásommal igazolom, hogy az Olcsó digitális oszcilloszkóp megvalósítása STM32 mikrovezérlő segítségével című komplex feladatom/ szakdolgozatom/ diplomamunkám1 saját, önálló munkám; az abban hivatkozott szakirodalom felhasználása a forráskezelés szabályi szerint történt. Tudomásul veszem, hogy plágiumnak számít: - szószerinti idézet közlése idézőjel és hivatkozás megjelölése nélkül; - tartalmi idézet hivatkozás megjelölése nélkül; - más publikált gondolatainak saját gondolatként való feltüntetése. Alulírott kijelentem, hogy a plágium fogalmát megismertem, és tudomásul veszem, hogy plágium esetén a szakdolgozat visszavonásra kerül. Miskolc, hallgató aláírása 1 Megfelelő rész aláhúzandó 3
Tartalomjegyzék 1. Bevezetés...5 2. Oszcilloszkóp működése és felépítése...6 2.1. Általános jellemzői...6 2.2. Csoportosítása...6 2.3. Felépítése...7 2.4. Megjelenítési üzemmódok...9 2.5. Főbb Műszaki paraméterek...9 3. Digitális tárolós oszcilloszkópok...10 4. Oszcilloszkóp hardware...11 4.1. STMF4DISCOVERY...11 4.2. STM32F4DIS-BB és STM32F4DIS-LCD...12 5. STM32F407VGT6...13 5.1. Áttekintés...13 5.2. Felépítése...13 5.3. Boot módok...14 5.4. Rendszer órajel...15 5.5. Általános célú lábak (GPIOs)...16 5.6. Analóg-digitális átalakító (ADC)...16 5.7. Időzítők (Timers)...16 6. Digitális Oszcilloszkóp vezérlő program...17 6.1. Áttekintés...17 6.2. IAR EWARM...19 6.3. Forráskód...20 6.3.1. scope.c...20 6.3.2. main.c...28 6.3.3. scope_ui.c...36 6.4. Tesztelés...36 7. Javaslat digitális tárolós oszcilloszkóp megvalósítására...39 7.1. Áttekintés...39 7.2. STM32F103C8T6...40 7.3. Elvi kapcsolási rajz...40 7.4. Alkatrészlista...42 7.5. Alkatrészek funkciói...42 7.6. NYÁK terv...44 7.6.1. Top layey...45 7.6.2. Bottom layer...46 7.6.3. STM32F103C8T6 Próbapanelhez...46 8. Összefoglalás...47 9. Summary...47 10. Irodalomjegyzék...48 4
1. Bevezetés Az ipar számos területén kiemelt fontossággal bír a méréstechnika melynek révén pontos adatokhoz juthatunk a mérendő mennyiségek tulajdonságairól. Egyaránt a gyártás és a fejlesztés folyamán szükség van a mérésekből, tesztelésekből származó adatokra amelyek alapján biztosítható az, hogy az előállított termék megfeleljen az elvárt minőségi szintnek. A mért adatok alapján lehet következtetni a szükséges változtatásokra. Mérni nem csak a már kész terméket lehet hanem gyártás közben is lehetséges, sőt elvárt a gyártásközi mérés. A gyártás minőségében meghatározó szerepet tölt be a gyártó berendezés melynek folyamatos vizsgálata szintén kötelező. Azt, hogy mit kell megmérni a prototípuson, illetve a már gyártásban lévő terméken azt a fejlesztőmérnök dönti el. A mérendő paraméter megmérése, a mérési hiba kiszámítása, a mért érték értelmezése a tesztmérnök feladata. A méréstechnika területén rengeteg mérőműszer és mérési eljárás áll a mérnökök rendelkezésére amelyek közül egy rendkívül fontos és elterjedt műszer az oszcilloszkóp. Szakdolgozatom témája ezért egy digitális tárolós oszcilloszkóp megvalósítása mely elsősorban hangfrekvenciás mérésekre alkalmas. Cél egy alacsony fogyasztású és kis költségvetésű oszcilloszkóp készítése. Hogy ezen céloknak megfeleljen választásom az ARM processzort tartalmazó STmicroelectronics által gyártott mikrovezérlőre esett. A nagy fokú integráltságának köszönhetően a külső alkatrészek száma minimalizálható, a nyomtatott áramkör mérete ehhez igazodva szintén minimális tovább csökkentve a gyártás költségét. A szakdolgozatom második és harmadik fejezetében általánosságban esik szó az analóg és digitális oszcilloszkópok felépítéséről, működési elvéről, fontosabb műszaki paramétereiről. A negyediktől a hatodik fejezetig a megvalósított oszcilloszkóp hardverjét és szoftverjét ismertetem. Végül javaslatot teszek az oszcilloszkóp egyedi megvalósítására. 5
2. Oszcilloszkóp működése és felépítése 2.1. Általános jellemzői Az oszcilloszkóp az elektronikai méréstechnika leggyakrabban használt speciális feszültségmérő eszköze. Nagy bemeneti impedanciával rendelkezik ezért a mérendő körbe párhuzamosan kell bekötni. Közvetlenül feszültség idő függvényt, valamint fázishelyzetet lehet megjeleníteni a képernyőjén vagy az oszcilloszkópra kötött számítógép monitorán. A készülék azon tulajdonsága, hogy kirajzolja a mérendő jelet lényegesen több információt hordoz mint például a multiméterek számértékes kijelzése. Közvetlen vagy közvetett módon mérhető mennyiségek: 1. egyenfeszültség 2. váltakozó feszültség 3. frekvencia 4. idő 5. fázis, fáziskülönbség 6. egyenáram 7. váltakozó áram Oszcilloszkópos vizsgálattal megfigyelhető a jelalak torzulása, közvetett módon mérhető a jel egyen és váltakozó áramú komponense. Több csatornás készülékek eseten lehetőség van a különböző jelek (kettő de lehet több is) összehasonlítására. 2.2. Csoportosítása Felépítés alapján: 1. Többsugaras: a katódsugárcsőben több egymástól független elektronágyú van. 2. Többcsatornás: a katódsugárcsőben csak egy elektronágyú van ami az emberi szem hiányosságait kihasználva rajzolja ki egy időben a 6
legalább két jelet. Jelfeldolgozás alapján: Időbeliség alapján: Tárolóképesség alapján: Mintavételezés alapján: Időalapok száma alapján: 2.3. 1. Analóg 2. Digitális 1. Valós idejű 2. Nem valós idejű 1. Tároló 2. Nem tároló 1. Valós idejű 2. Véletlen idejű 3. Ekvivalens idejű 1. Egy időalapos 2. Két időalapos [2] Felépítése 2.1. ábra. Kétcsatornás oszcilloszkóp blokkvázlata [1] 7
A CH1 és CH2 bemeneti csatornákra BNC csatlakozójú mérővezetékkel lehet csatlakozni ahonnan a jel egy választókapcsolóra jut. AC állásban egy kondenzátor kiszűri a jel egyen komponensét. DC állás esetén a jel változatlanul halad tovább. GND állásban az oszcilloszkóp bemenete le van földelve. A választókapcsoló kinagyított kapcsolási rajzát a 2.2 ábra mutatja. 2.2. ábra A választókapcsoló után a jel a bementi osztóra (Attenuátor) kerül ahol a jel fokozatokban és folyamatosan is osztható. A folyamatos osztót potenciométerrel vezérelhetjük, a fokozatos osztó pedig 1-2-5 lépésekben osztja a jelet. Mértékegysége a V/Div. A csatornánkénti vertikális erősítő offset-jével a jelek vertikális helyzetét lehet befolyásolni. Mivel a jeleket döntő többségében az idő függvényében vizsgáljuk ezért szükség van a horizontális erősítőre. Leggyakrabban lineárisan növekvő úgynevezett fűrészfog jelet alkalmaznak az idő leképezéséhez. A fűrész jel generátor be van építve az oszcilloszkópba, de lehetőség van más vezérlő jelet is használni amit az EXT bemenetre lehet kapcsolni. Bizonyos esetekben az oszcilloszkóp képernyőjén megjelenő jel futni látszik ami nagyban megnehezíti a jelalak vizsgálatát. Ebben az esetben triggerelésre (szinkronizálás) van szükség. A triggerelés lényege, hogy a fűrészfeszültség csak akkor indul újra amikor a vizsgált jel ugyan akkora nagyságú és ugyan abban a fázisban van. Ekkor a képernyőre egymásra rajzolódnak a jelalakok így megszűnik a futás jelensége. [1] 8
2.4. Megjelenítési üzemmódok ALT (Alternate) üzemmódban teljes jelalakokat rajzol ki az oszcilloszkóp a képernyőre így egymás után jeleníti meg a teljes jelalakokat. CHOP (Chopper) üzemmódban az elektronsugár igen nagy frekvencián (100kHz 1MHz között) váltogatva rajzolja ki a két jel pontjait, így jelenítve meg a két jelet egyszerre. [1] 2.5. Főbb Műszaki paraméterek Sávszélesség: A sávszélesség adott csillapításhoz tartozó alsó és felső határfrekvenciák közötti frekvenciatartomány ahol szinuszos jel esetén a jel alakhűen jelenik meg. A határfrekvenciákhoz tartozó csillapítás értéke 3dB. Az oszcilloszkópok alsó határfrekvenciája 0 MHz (a nem tároló rendszerű oszcilloszkópoknál ez az érték az emberi szem miatt 20Hz) felső határfrekvenciája körülbelül 200 MHz-ig terjed, de ez az érték kitolható 1-5 GHz-ig. Feszültség mérés esetén 3%-os hibával a felső határfrekvencia harmadáig lehetséges a mérés. Bemeneti impedancia: Ahhoz, hogy az oszcilloszkóp feszültség méréskor ne terhelje a mérendő áramkört nagy bemeneti impedancia szükséges. Ezért a bemenetek 1 MΩ nagyságú ellenállással rendelkeznek. Zavarvédelmi okokból árnyékolt kábel használata szükséges. Érzékenység: Az érzékenység az a feszültség érték, amely az oszcilloszkóp bemenetére kapcsolva a képernyőn egy osztásnyi (DIV) függőleges sugárkitérést hoz létre. Mértékegysége a V/DIV. Értéke általában 1 mv/div és 20 mv/div között mozog de bemeneti osztóval ez az érték kitolható 5V/DIV és 20V/DIV közötti értékre. Időalap: Az időeltérítés sebessége (time base) azt befolyásolja, hogy egy egységnyi utat mennyi idő alatt ír le a fénysugár. Mértékegysége a s/div, 9
általános értéke 2ns/DIV-től 50s/DIV-ig terjed. Triggerelés forrása: INT amikor a vizsgált jel indítja a fűrészjelet. EXT amikor kívülről, külön erre a célra szolgáló bemenetről vezéreljük a fűrészjel indítását. LINE amikor a hálózati feszültséget használjuk fel az indításra. [2] 3. Digitális tárolós oszcilloszkópok A digitális oszcilloszkópoknak köszönhetően a mérés alsó határfrekvenciája gyakorlatilag nulla az eddigi 20Hz-hez képest. Ez a mérendő jelet mintavételezi, kvantálja és a memóriába helyezi. A jel először a jelkondicionáló áramkörön halad keresztül majd az A/D átalakítóba jut ahonnan a memóriába kerül. Ahhoz hogy a jelet megjelenítsük az oszcilloszkóp képernyőjén a memóriában lévő adatok alapján vissza kell állítani az eredeti analóg jelalakot, így amit a képernyőn látunk nem a vizsgált jel folytonos megjelenítése. Minden digitális oszcilloszkóp képes analóg üzemmódban működni. Ekkor a jel megkerüli az A/D és D/A átalakítót. [1] 3.1. ábra. DSO (Digital Storage Oscilloscope) álltalános felépítése [1] 10
4. 4.1. Oszcilloszkóp hardware STMF4DISCOVERY Az oszcilloszkóp hardware-jéül a STM32F4DISCOVERY fejlesztői kártya szolgál mely viszonylag alacsony áron kínál lehetőséget ARM processzort tartalmazó MCU (Micro Controller Unit) programozására. A fejlesztői kártya az STM32F407VGT6 mikrokontrolleren alapszik amelynek processzora ARM Cortex-M4 32 bites, 168 MHz órajelű. 1 Mbyte flash memóriával és 192 Kbyte SRAM-al rendelkezik. A szakdolgozat kapcsán fontos még megemlíteni, hogy rendelkezik 17 időzítővel, valamint 3 analóg-digitális átalakítóval. A discovery board programozása az ST-LINK/V2 eszközzel lehetséges mely bele van építve a kártyába. Segítségével USB kábelen keresztül PC-ről programozhatunk, valamint debuggolhatunk. A PC oldali szoftvernek az IAR Embedded Workbench for ARM-ot választottam mivel ez tartalmazza a szükséges toolchain-t, debug eszközt. 4.2.STM32F4DISCOVERY ábra. Hardver blokkdiagram [7] [7] 4.1. ábra. felső nézete 11
4.2. STM32F4DIS-BB és STM32F4DIS-LCD Az STM32F4DIS-BB egy kiegészítő panel amelyet az STM32F4DISCOVERY fejlesztői kártyához készítettek. Célja, hogy a már meglévőket további funkciókkal egészítse ki: soros port, USB, Ethernet, CAN, SPI, I2C, GPIO, kamera, LCD kijelző és érintő képernyő interfész. A STM32F4DIS-BB és az STM32F4DISCOVERY együtt használva szolgál alapul a digitális oszcilloszkóp prototípusának megvalósításához. Az oszcilloszkópnak szüksége van egy kijelzőre, ezt a célt egy további kiegészítő STM32F4DIS-LCD biztosítja. 4.3. ábra. STM32F4DIS-BB interfészek [8] SSD2119 a kiegészítő kijelző neve. Ez egy 320x240 pixel felbontású színes (RGB) TFT LCD kijelző. Integrálva tartalmaz 172800 byte GDDRAM-ot (Graphic Display Data RAM) amelyen keresztül van összekötve a kijelző és az MCU. 12
5. STM32F407VGT6 5.1. Áttekintés Az STM32F407VGT6 mikrovezérlő egy 32 bites ARM Cortex-M4 processzor magon alapszik. A Cortex-M4 gyakorlatilag egy Cortex-M3 DSP-vel (Digital Signal Processor) és FPU-val (Floating-point Unit) kiegészítve. Az ARM processzorok jellemzője az alacsony fogyasztás ezért népszerű a beágyazott rendszerek körében. Egyszerűsített utasításkészlettel rendelkezik (Thumb-2), így nagyobb kódsűrűség és kisebb futási idő érhető el. Alacsony árának köszönhetően igen népszerű az STM32 mikrovezérlő család. [2] 5.2. Felépítése 1 Mbyte flash memóra és 192 Kbyte SRAM 1.8 V 3.6 V tápfeszültség Belső 16 MHz és 32 khz, valamint opcionális külső 4 MHz 26 MHz oszcillátor Három 12 bites 2.4 MSPS analóg-digitális átalakító (7.2 MSPS triple interleaved módban) 12 darab 12 bites időzítő és két 32 bites időzítő debug mód: soros porton keresztül (SWD) valamint JTAG interfészen keresztül 5V tűrő GPIO lábak kommunikációs interfészek: I2C, USART, SPI, CAN, USB 2.0 13
5.1. ábra. STM32F40x blokkdiagram 5.3. Boot módok Az MCU induláskor a boot lábak konfigurációja határozza meg, hogy melyik memória területről töltse be a futtatni kívánt kódot. Három lehetséges variáció van: Flash memóriából, rendszer memóriából vagy az SRAM-ból. A boot loader a rendszer memóriában van. Arra használjuk, hogy a Flash memória tartalmát felül tudjuk írni vagy törölni. USART-on és USB-n keresztül egyaránt programozhatjuk az MCU-t. [6] 14
5.2. ábra. Boot módok [10] 5.4. Rendszer órajel Induláskor vagy az MCU újraindítása után a 16 MHz-es belső oszcillátor az alapértelmezett órajel generátor. Az alapértelmezett RC oszcillátor gyárilag trimmerelt, hogy 1%-os pontosságot elérjen el a teljes működési hőmérsékleti skálán. Az alkalmazás azután rendszer órajelként egyaránt kiválaszthatja az RC oszcillátort vagy egy külső 4 MHz 26 MHz-es oszcillátort. Az külső órajelet ellenőrizhetjük, hogy van e benne hiba. Ha a rendszer hibát észlel automatikusan visszavált a belső RC oszcillátora és egy szoftver interrupt-ot generál ha ez engedélyezett. Az órajel generátor egy PLL bemenete mely a működési frekvenciát 168 MHz-re tudja felszorozni. Az alábbi ábrán látható egy Excel táblázat melyben grafikus formában adhatjuk meg az egyes perifériákhoz tartozó működési frekvenciákat. A fájl kimenete egy forrás fájl amit később felhasználhatunk saját projektünkben. [6] 5.3. ábra. Órajel konfigurációs Excel táblázat 15
5.5. Általános célú lábak (GPIOs) Minden egyes GPIO láb beállítható kimenetként vagy bemenetként, illetve aktiválható az általa képviselt alternatív funkció. Ilyen alternatív funkciók lehetnek az egyes kommunikációs portok (USART, USB) vagy a belső perifériákhoz tartozó ki, illetve bemenetek (ADC, DAC). A legtöbb GPIO láb rendelkezik analóg vagy digitális alternatív funkcióval. Az összes GPIO láb működési frekvenciáját lehet változtatni, hogy jobban illeszkedjenek az aktuális felhasználásukhoz (pl.: kevesebb zajt termeljen; kevesebb legyen az energia felvétele). A ki és bemeneti jel maximálisan 84 MHz frekvencián váltakozhat. [6] 5.6. Analóg-digitális átalakító (ADC) A mikrokontroller három egymástól független, 12 bites analóg-digitális átalakítót tartalmaz melyek 16 külső csatornán osztoznak. A konverzió lehet single-shot vagy scan módú. Scan módban a konverzió automatikusan hajtódik végre a kiválasztott analóg bemeneteken. További két funkcióval lehetséges módosítani az ADC működését: Simultaneous sample and hold: ekkor az egyes ADC-k egymástól függetlenül, egyidejűleg működnek. Ekkor 2.4 MSPS a mintavételi sűrűség. Interleaved sample and hold: Az ADC-k időben elosztva működnek, egymás után veszik a mintákat ugyan abból a jelből. A mintavételezhető jelek száma lecsökken de a mintavételi sűrűség megnövekszik (akár 7.2 MSPS). A megfelelő analóg-digitális átalakítás szinkronizálásához az MCU TIM1, TIM2, TIM3, TIM4, TIM5, vagy TIM8 időzítőjét kell felhasználni. [6] 5.7. Időzítők (Timers) Az STM32F407xx eszközök két advanced-control-, kilenc általános célú-, két alap- és két watchdog időzítőt tartalmaz. Advanced-control időzítők (TIM1, TIM8): Elsősorban PWM igénylő 16
feladatoknál alkalmazzák bár lehet őket általános célú időzítőként is használni. Három fázisú PWM generátorként működnek. Az advanced-control és az általános célú időzítők szinkronizálhatóak, hogy események láncolása is létrehozható legyen. Általános célú időzítők (TIM2 TIM5): TIM2, TIM5: 32 bites fel és le számolón, valamint egy 16 bites előosztón alapszik. TIM3 és TIM4: 16 bites fel és le számolón, valamint egy 16 bites előosztón alapszik. Általános célú időzítők (TIM9 TIM14): 16 bites fel és le számolón, valamint egy 16 bites előosztón alapszik. Alap időzítők (TIM6 és TIM7): Ezeket az időzítőket elsősorban digitális-analóg átalakítók triggerjeként, valamint jelalak generálásra alkalmazzák. Watchdog időzítő: Egy 12 bites lefelé számlálón és egy 8 bites előosztón alapul. Egy különálló, belső RC oszcillátorról működik így biztosítva függetlenségét a fő órajeltől. Használható arra, hogy egy esetleges probléma esetén újra indítsa az eszközt vagy timeout management-re is hansználható. [6] 6. 6.1. Digitális Oszcilloszkóp vezérlő program Áttekintés Az oszcilloszkóp szoftverjének megírásához az IAR Embedded Workbench for ARM (EWARM) nevű programot választottam. Az EWARM-ban C nyelven írtam az MCU forráskódját. Az STMicroelectronics és az IAR egyaránt adott ki példaprogramokat amelyeket kiinduló pontnak használtam fel saját projektem megvalósításához. 17
6.1. ábra. Az oszcilloszkóp vezérlő programjának folyamat ábrája A fenti ábrán látható az oszcilloszkóp program működésének blokkvázlata. Első lépésként az STM32F4DISCOVERY bekapcsolása vagy újraindítása után a konfigurációs beállítások kerülnek elvégzésre. Ilyen beállítások az analóg-digitális konverter, időzítők, kijelző, grafikus interfész inicializálása. Azok a függvények amelyek ezeket a beállításokat végzik csak egyszer futnak le. A beállítások után a program három párhuzamos ágon fut tovább. A és B csatornákhoz tartozó mintavételezés időtartamát hogy mekkora időintervallumot digitalizálunk a vizsgálandó jelből külön-külön lehet állítani, valamint a két csatorna közös mintavételi idejét. Mind a három ágat külön időzítő és a hozzá tartozó interrupt kezelő függvény vezérli. 18
Amint az egyik csatorna időalapja letelik az addig begyűjtött minták kirajzolásra kerülnek az LCD kijelzőre és addig látszódik a képernyőn amíg újból le nem telik az időalap és új képpontok kerülnek kirajzolásra. 6.2. IAR EWARM Az MCU vezérlő programjának megírását az IAR Embedded Workbench for ARM 6.40.2.3992 nevű és verziószámú integrált fejlesztői környezetben végeztem. IAR EWARM támogatja a főbb gyártók által gyártott ARM magos MCU-kat és processzorokat. Előnye, hogy egy szoftver tartalmazza a projekt kezelőt, fordítót és debugger eszközt. A program kezelő felülete három részre van felosztva (négy ha debuggolunk): a forráskód szerkesztő; projekt összesítő és a log ami információkat közöl a fordítási folyamatról. Az oszcilloszkóp projektje három nagyobb részre oszlik: A hardver alap vezérlő függvényei: startup_stm32fxx.s, stm32f4_discovery.c, stm32f4_discovery_lcd.c A perifériákat vezérlő függvények: STM32F4xx_StdPeriph_Driver mappa tartalma. A felhasználó által írt függvények: Az User mappa tartalma. 6.2. ábra. IAR Embedded Workbench for ARM 19
6.3. Forráskód 6.3.1. scope.c A scope.c fájl tartalmazza a konfigurációs beállításokhoz szükséges függvények definícióit. Elsőként az időzítők beállítását végeztem el. Ezek a függvények felelősek a mintavételi frekvencia beállításáért, valamint a mintavételezés idejének beállításáért. Ezekre a feladatokra a TIM2, TIM3 és TIM5 időzítőket használtam fel mivel ezek szinkronizálhatók az analóg-digitális átalakítóval. A timer modul mellett az interrupt vezérlést (NVIC) is biztosítani kell, hogy az időzítők meghívhassák azokat az interrupt kezelő függvényeket amelyek elvégzik a grafikonok kirajzolását. Az egyes perifériák, illetve funkciók inicializálása struktúrákon keresztül történik melyek paraméterei határozzák meg a perifériák és funkciók tulajdonságait. Ezek a struktúrák megtalálhatóak a gyártó által elkészített forrás fájlokban. Az egyes perifériáknak külön-külön kell engedélyezni az órajelet így ezt minden egyes alkalommal el kell végezni. Ezen módszer előnye, hogy az MCU azon részeit amelyekre nincs szükség nem is aktiváljuk így csökkentve a mikrokontroller fogyasztását. Hátránya, hogy a kód amit írunk bonyolultabb lesz, valamint maga az MCU is. Első ilyen függvény a config_timing_a( ) melynek feladata A csatorna időalapjának beállítása. void config_timing_a(void) /* A csatorna (piros) */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* Elsőként engedélyezem az APB1-es busz órajelét majd definiálnom a két struktúrát */ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; /* A TIM_Prescaler értékkel osztom le az alap órajelet 1 MHz-re majd TIM_Period-nál beállított minden 1000-es érték felel meg 1 ms-nak illetve minden 1-es érték 1μs-nak. Ez jelen esetben 65000 tehát 65 ms ideig veszünk mintát a vizsgálandó jelből az A 20
csatornán. */ /* A TIM_Prescaler és a TIM_Period értékei esetén azért van ott mínusz egy mert alapértelmezésként a fordító hozzá ad ezekhez az értékekhez egyet, hogy elkerülje a nullával való osztást, illetve a nulla idejű ismétlési időket. */ TIM_TimeBaseStructure.TIM_Prescaler = 16-1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 65000-1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); /* Az NVIC beállítása: meg kell adni melyik timer használja ezt az interrupt csatornát, valamint a prioritást végül engedélyezzük a csatornát */ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Időzítő engedélyezése. Ekkor indul el a számlálás */ TIM_Cmd(TIM2, ENABLE); A második függvény a konfigurációs beállítást végző függvények listájában a config_timing_b( ). Felépítése megegyezik config_timing_a( ) függvénnyel azzal a lényeges különbséggel, hogy ez esetben a TIM5 időzítőt használom, valamint külön interrupt csatornát így a két csatorna teljesen függetlenül tudja a megszakításait kezelni. Abban az esetben ha két megszakítás kérés érkezik egyszerre akkor az NVIC struktúrában megadott prioritás dönti el a sorrendet így elkerülhetjük a megszakítás megszakítását. A nullás érték jelenti a legnagyobb prioritást. void config_timing_b(void) /* B csatorna (sárga) */ 21
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseStructure.TIM_Prescaler = 16-1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 10000-1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM5, ENABLE); Következő függvény a config_sampling_timing( ) ami mintavételi frekvencia beállítását végzi el. Ennél a TIM3-as időzítőt használom, valamint a TIM3_IRQn interrupt csatornát. void config_sampling_timing(void) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; 22
TIM_TimeBaseStructure.TIM_Prescaler = 16-1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 110-1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM3, ENABLE); A következő függvény a config_chanel_a_b( ) feladata aktiválni a két külön csatornához tartozó analóg-digitális átalakítót, valamint azokat a lábakat amelyek felhasználhatóak az átalakítók bemeneteként. Ha az STM32F4DISCOVERY-t a kiegészítő alaplappal (STM32F4DIS-BB) és kijelzővel (STM32F4DIS-LCD) használjuk oda kell figyelni az esetleges funkció és lábkiosztási ütközésekre. A kijelző érintő képernyős funkcióira használja a discovery board analóg-digitális átalakítóit. Megoldásként szolgál ha nem inicializáljuk a kijelző ezen funkcióját vagy olyan átalakítót választunk melyet nem használ az LCD. void config_chanel_a_b(void) /* Az MCU C portjának engedélyezése, az ADC1 és ADC2 engedélyezése */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 RCC_APB2Periph_ADC2, ENABLE); 23
/* Szükséges struktúrák létrehozása. */ GPIO_InitTypeDef GPIO_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_InitTypeDef ADC_InitStructure; /* A C port 0-ás és 1-es lábának engedélyezése. Mivel bemenetként szolgálnak a két analóg-digitális átalakító számára ezért nem digitális hanem analóg módban üzemelnek és nem rendelkeznek le vagy fel húzó ellenállással. */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Az ADC tulajdonságainak meghatározása: egymástól függetlenül működnek; DMA kikapcsolása; 12 bites felbontáson; egymásután automatikusan elvégzett konverziók száma */ ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 1; /* ADC1 és ADC2 esetén ugyan azt a struktúrát használom mivel ugyan olyan 24
beállításokkal rendelkező analóg-digitális átalakítókat akarok használni. */ /* ADC1 esetén a Channel 10-et, ADC2 esetén a Chanel 11-et használtam mert ezek a csatornák vannak a PC0, illetve a PC1 GPIO lábakhoz rendelve. */ ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_144Cycles); ADC_Init(ADC2, &ADC_InitStructure); ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_144Cycles); /* A két analóg-digitális átalakító engedélyezése. */ ADC_Cmd(ADC1, ENABLE); ADC_Cmd(ADC2, ENABLE); Az MCU-ban használt analóg-digitális átalakítók fokozatos közelítésű átalakítók így annyi lépésben végzi el az átalakítást amekkora a felbontása. Esetünkben 12 lépést jelent tehát legalább 12 órajelet várni kell mielőtt kiolvassuk az átalakítás értékét. Abból a célból, hogy a fenti követelménynek megfeleljen a program az alábbi két függvény gondoskodik. int adc_convert_a(void) /* ADC_SoftwareStartConv(ADCx) elindítja a konverziót a paraméterként megadott analóg-digitális átalakító esetén. */ ADC_SoftwareStartConv(ADC1); /* Addig várakozik a program míg ADC_FLAG_EOC értéke RESET értéket fel nem veszi. ADC_FLAG_EOC-ból az EOC jelentése End Of Conversion. */ while(adc_getflagstatus(adc1, ADC_FLAG_EOC) == RESET); /* Amikor az átalakítás véget ért a konverzió értéke a függvény visszatérési értéke. */ return ADC_GetConversionValue(ADC1); 25
int adc_convert_b(void) ADC_SoftwareStartConv(ADC2); while(adc_getflagstatus(adc2, ADC_FLAG_EOC) == RESET); return ADC_GetConversionValue(ADC2); Az oszcilloszkóp rendelkezik saját maga által generált 1 Khz-es négyszögjellel amihez az időzítőt és a GPIO lábat az alábbi függvény generálja. void config_square_wave(void) RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Az A port 7-es lábát használom a négyszögjel kimeneteként. */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); TIM_TimeBaseStructure.TIM_Prescaler = 16-1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 1000-1; // x[ms] TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); 26
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM4, ENABLE); Az oszcilloszkóp készítésének korai szakaszában a soros portot használtam az analógdigitális átalakító értékeinek kiíratására. Továbbá remek debuggolási lehetőséget adott, hogy olyan információkat is kiírassak amiket nem akartam, hogy megjelenjenek az oszcilloszkóp kijelzőjén. A soros port kommunikációját az alábbi függvény inicializálja. void usart_conf(void) USART_InitTypeDef USART_InitStructure; /* USARTx configured as follow: - BaudRate = 115200 baud - Word Length = 8 Bits - One Stop Bit - No parity - Hardware flow control disabled (RTS and CTS signals) - Receive and transmit enabled */ USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; 27
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx USART_Mode_Tx; STM_EVAL_COMInit(COM1, &USART_InitStructure); 6.3.2. main.c A main.c forrásfájlban foglalnak helyet azok a függvények és változok amik vezérlik az inicializált perifériákat. Az oszcilloszkóp két csatornás de csak az A csatorna forráskódját írom le és elemzem működését mivel a B csatorna ezzel teljesen megegyező működési elvű csak a felhasznált változókban tér el. float q, y1, y2, arany; float v_a, v_b; float vmax_a, vmax_b; float vmin_a, vmin_b; float atlag_a, atlag_b; /* A ConvertedValue_A[] és ConvertedValue_B[] vektorok tartalmazzák az analógdigitális átalakító álltal generált számértékeket. */ int ConvertedValue_A[2000], ConvertedValue_B[2000]; int dots_a[2000], dots_b[2000], delete_a[2000], delete_b[2000], x_a[2000]; int x_b[2000]; int x1, x2, i, j, a, b, x; uint8_t text[50]; /* A kirajzolt grafikon egyenes vonalakból rajzoltatom ki de ha a grafikon legelső pontját is olyan függvénnyel rajzoltatnám ki ami vonalat rajzol akkor az LCD x=0 és y=0 koordinátájából egy egyenes vonalat húzna a grafikon tényleges kezdőpontjához. Eredmény képen mindig lenne a kijelzőn egy oda nem illő egyenes. Ezért volt szükség egy pont rajzoló függvényre ami a PutPixel( ). */ 28
static void PutPixel(int16_t x, int16_t y) if(x < 0 x > LCD_PIXEL_WIDTH-1 y < 0 y > LCD_PIXEL_HEIGHT-1) return; LCD_DrawLine(x, y, 1, LCD_DIR_HORIZONTAL); A main függvény tartalmazza a scope.c fájlban definiált függvények deklarációját, valamint egy üres while ciklust, hogy a program futása ne érjen véget hanem addig fusson míg a felhasználó meg nem szakítja. A mintavételezésért, adatok feldolgozásáért és a grafikon kirajzolásáért felelős függvények a main után vannak definiálva. Meghívásukért az interrupt kezelő függvények a felelősek így biztosítva, hogy minden folyamat a megfelelő időközök elteltével fusson le. int main(void) /* STM32f4_Discovery_LCD_Init() függvényt a gyártó definiálta. Feladata, hogy előkészítse az LCD kijelzőt a használatra. */ STM32f4_Discovery_LCD_Init(); config_chanel_a_b(); /* A create_ui() függvény állítja be a kijelző háttér színét, betű színét és méretét, valamint létrehozza a keretet amiben a grafikont láthatjuk. */ create_ui(); /* A soros portot jelenleg nem használom de a forráskódban benne maradt ki kommentelve arra az esetre ha szükség lenne rá. */ //usart_conf(); /* a és b változó számolja, hogy hányszor futott le a mintavételezés az aktuálisan beállított időalap esetén. */ a = 1; 29
b = 1; config_square_wave(); config_sampling_timing(); config_timing_a(); config_timing_b(); /* A program futásának ezen pontján minden szükséges periféria működik és a számlálók is elindultak. */ while (1) /* graph_a( ) függvény végzi azokat a műveleteket amik grafikonná alakítják át az analóg-digitális átalakító által generált számértékeket. Az alábbi grafikon szemlélteti, hogy milyen arányosítási műveleteket kell elvégezni ahhoz, hogy a változó mintaszámú jeleket megfelelően ábrázoljuk a kijelzőn. y koordináta=( ADC értéke ) 236 4095 x koordináta=89+( i edik elem ) 229 a Az x koordináta értékéhez azért adok hozzá 89-et mert 0 89 pixel a kiírt feszültség értékeknek van fenntartva így a grafikont el kell tolni. */ 6.3. ábra. Az oszcilloszkóp kijelzője és az ábrázolt mennyiségek közötti viszony 30
void graph_a(void) v_a = 0; /* v_a változó tartalmazza az aktuálisan kirajzolt grafikon pillanatnyi feszültség értékét */ vmax_a = 0; /* vmax_a és vmin_a tárolják a pillanatnyi maximális és vmin_a = 3.30; minimális feszültség értékeket */ y1 = 0; /* Az A csatorna grafikonjának y koordinátája */ q = (3.3/4095.0); /* A q változóval arányosítom az analóg-digitális átalakító által generált számokat (amik 0 4095 közé esnek). Azért a 3.3-at osztom a 4095-el mert az feszültség intervallum amin dolgozik az átalakító 0 V 3.3 V */ atlag_a = 0; /* atlag_a tartalmazza az aktuálisan kirajzolt grafikon számtani középértékét. */ /* Az alábbi for-ciklus annyiszor fut le ahány mintavételezés volt az adott csatorna (jelen esetben A ) időalapja esetén. Minden egyes mintára kiszámolja a pillanatnyi feszültség értéket, maximális- és minimális feszültség értéket, valamint összeadja a pillanatnyi feszültség értékeket a for-ciklus utáni számtani középérték kiszámításához */ for(i=1; i<a; i++) /* Az alábbi két sor műveletei arányosítják az analóg-digitális átalakító értékeit a grafikon y tengelyéhez. Az arany változót 236-al szorzom mivel 236 pixel az y tengely. */ arany = ((float)convertedvalue_a[i])/4095.0; dots_a[i] = (arany*236); /* A for-ciklus további sorai számolják ki a kiírt feszültség értékeket. */ v_a = (q * (float)convertedvalue_a[i]), v_a = 3.30 - v_a; if(v_a > vmax_a) vmax_a = v_a; if(v_a < vmin_a) vmin_a = v_a; atlag_a = atlag_a + v_a; 31
atlag_a = atlag_a / a; /* A számtani középérték kiszámítása */ /* feszültség értékek kiírása. A betűszín pirosra állítása, hogy könnyeben felismerhető legyen melyik értékek melyik grafikonhoz tartoznak. */ LCD_SetTextColor(LCD_COLOR_RED); sprintf((char*)text,"a csatorna"); LCD_DisplayStringLine(LINE(0),text); sprintf((char*)text,"atl: %1.2fV", atlag_a); LCD_DisplayStringLine(LINE(1),text); sprintf((char*)text,"max: %1.2fV", vmax_a); LCD_DisplayStringLine(LINE(2),text); sprintf((char*)text,"min: %1.2fV", vmin_a); LCD_DisplayStringLine(LINE(3),text); /* Az alábbi do-while ciklus számítja ki, hogy melyik y koordináta melyik x koordinátához lesz hozzá rendelve. A j változó 89 318 intervallumon halad végig. 318-89 = 229 mivel az x tengely 229 pixel hosszú. delete_a[i] és x_a[i] a grafikon y és x koordinátáit tárolja másodlagosan a későbbi törlés miatt. */ i=1; j = 89; y2 = 0; x2 = 0; do y1 = dots_a[i]; delete_a[i] = y1; /* Itt történik az x-tengelyhez való arányosítás. Mivel a változó (hogy hány mintából áll a mintavételezett jel) beállításoktól függ így mérésenként változhat a 229 pixel széles xtengelyre kirajzolandó minták száma. */ arany = (float)i / (float)a; 32
x1 = (arany * 229) + 89; x_a[i] = x1; i++; /* Abban az esetben ha az aktuális x koordináta megegyezik j értékével akkor azt ábrázolja a függvény a kijelzőn majd megvizsgálja a következő x koordinátát. Ameddig x1=j addig j nem lép tovább. Amint x1 értéke nagyobb mint j, a függvény tudja, hogy nem tartozik több y koordináta a j által szimbolizált x koordináta értékéhez és a következő j értékre ugrik. */ if(x1==j) if(x2 && y2 == 0) PutPixel(x1,y1); if(x2 y2 > 0) LCD_DrawUniLine(x1,y1,x2,y2); x2=x1; y2=y1; else j++; if(x2 && y2 == 0) PutPixel(x1,y1); if(x2 y2 > 0) LCD_DrawUniLine(x1,y1,x2,y2); x2=x1; y2=y1; while(j<318); /* A grafikon törlése esetében nem a teljes képernyőt törlöm majd újra kirajzolom hanem a korábban kirajzolt grafikont újra kirajzoltatom de most sárga vagy piros helyett feketével. Ez a folyamat segít elkerülni a képernyő villódzását. Később láthatjuk, hogy technikailag a törlés van előbb és csak azután a kirajzolás mert így a képernyőn marad a grafikon a következő kirajzolásig. Ennek hatására a grafikon folyamatosan változik a 33
képernyőn és nem villog. A delete_graph_a( ) működési elvében megegyezik void graph_a( ) függvénnyel. */ void delete_graph_a(void) LCD_SetTextColor(LCD_COLOR_BLACK); i=1; j=89; x2 = 0; y2 = 0; do y1 = delete_a[i]; x1 = x_a[i]; i++; if(x1==j) if(x2 && y2 == 0) PutPixel(x1,y1); if(x2 y2 > 0) LCD_DrawUniLine(x1,y1,x2,y2); x2=x1; y2=y1; else j++; if(x2 && y2 == 0) PutPixel(x1,y1); if(x2 y2 > 0) LCD_DrawUniLine(x1,y1,x2,y2); x2=x1; y2=y1; while(j<318); 34
/* Az interrupt kezelő függvény. Ez hívja meg a grafikon törléséhez és kirajzolásához szükséges függvényeket. */ void TIM2_IRQHandler(void) if (TIM_GetITStatus(TIM2, TIM_IT_Update)!= RESET) delete_graph_a(); graph_a(); for(x=1; x<2001; x++) ConvertedValue_A[x] = 0; a=1; TIM_ClearITPendingBit(TIM2, TIM_IT_Update); /* A mintavételezésért felelős interrupt kezelő függvény. */ void TIM3_IRQHandler(void) if (TIM_GetITStatus(TIM3, TIM_IT_Update)!= RESET) /* Itt történik a mintavételezés; a minta elmentése; minták számának meghatározása. */ ConvertedValue_A[a] = adc_convert_a(); a++; ConvertedValue_B[b] = adc_convert_b(); b++; TIM_ClearITPendingBit(TIM3, TIM_IT_Update); 35
/* Az A port 7-es lábának az időzítő által beállított frekvencián történő kapcsolgatása. Így előállítva a szükséges négyszög jelet. */ void TIM4_IRQHandler(void) if (TIM_GetITStatus(TIM4, TIM_IT_Update)!= RESET) GPIO_ToggleBits(GPIOA, GPIO_Pin_7); TIM_ClearITPendingBit(TIM4, TIM_IT_Update); 6.3.3. scope_ui.c void create_ui(void) LCD_SetBackColor(LCD_COLOR_BLACK); LCD_SetTextColor(LCD_COLOR_WHITE); LCD_SetFont(&Font8x12); LCD_DrawRect(88,2,230,236); 6.4. Tesztelés A tesztelés célja, hogy láthassuk a fontosabb program modulokat működés közben. A mérésnél az STM32DISCOVERY által generált 1 KHz-es négyszögjelet használtam fel. A jelalak feszültségét egy feszültségosztóval csökkentettem mert a kiadott jel 3.3 Vos ezért teljesen kitöltötte az oszcilloszkóp képernyőjét. Az osztónak köszönhetően a jelalak könnyebben kiértékelhető. Ezzel párhuzamosan rá volt kötve egy másik, gyári oszcilloszkóp mint egy referenciaként. Az A (piros színű jelalak) csatornára kötöttem a négyszögjelet, B (sárga színű jelalak) csatornára pedig egy 1.5 V-os ceruza elemet egyenfeszültség mérésének céljából. 36
6.4. ábra. Az összeállított mérés Mérési paraméterek A csatorna: PC0; B csatorna: PC1; Négyszögjel kimenete: PA7 Mintavételezés gyakorisága [μs] Vizsgált időtartam A csatorna esetén [ms] Vizsgált időtartam B csatorna esetén [ms] Kirajzolt Jelalak képpontok száma ábrájának A csatorna száma esetén 100 20 20 200 6.5 500 20 60 40 6.6 100 40 40 400 6.7 500 40 60 80 6.8 100 65 40 650 6.9 500 65 60 130 6.10 6.5. ábra 6.6. ábra 37
6.7. ábra 6.9. ábra 6.8. ábra 6.10. ábra A mérések során két paraméter változik: a mintavételezés gyakorisága és a vizsgált időtartam. Elsősorban A csatornára koncentráltam mert a négyszögjelen keresztül szemléletesebb az oszcilloszkóp működése. A mintavételezés gyakorisága 100 μs és 500 μs között váltakozik ugyan azon időalapok setén (20 ms, 40 ms, 65ms). Ezen felosztás célja, hogy különböző számú mintavételek esetén hogyan változik, illetve torzul a jelalak. 100 μs esetén a jelalak megfelelő, növekvő időalapoknál több periódust rajzol ki az oszcilloszkóp. 500 μs-os mintavételezés esetén azonban már fellép az aliasing jelensége mivel a mintavételek száma alacsony. A B csatorna jele kis mintaszámok esetén rövidül. Ez azért van mert a vezérlő program nem igazítja a képernyőhöz az egyenfeszültség grafikonját azon célból, hogy láthassuk a kevesebb képpontból való kirajzolás hatását. 38
7. 7.1. Javaslat digitális tárolós oszcilloszkóp megvalósítására Áttekintés Az STM32F4DISCOVERY remek lehetőség, hogy könnyeben készítsünk prototípust projektünkhöz, mivel az MCU egy olyan környezetbe van építve ami számos kiegészítőt tartalmaz mint például a kamera, LCD kijelző, kommunikációs portok. Felprogramozása célprogramok segítségével csupán egy-két kattintás. A hardverrel szintén nem kell foglalkoznunk ugyanis az MCU el van látva minden kiegészítő áramkörrel és kivezetésekkel, hogy minél egyszerűbben beilleszthessük saját áramkörünkbe. Ezen tulajdonságai miatt esett a választásom a fejlesztői kártyára továbbá azért mert így elkerülhető egy jelentős probléma forrás. Egy újonnan megtervezett és legyártatott még korábban ki nem próbált áramkörre programot írni számos hiba lehetőséget tartalmaz és nehéz megállapítani, hogy hardveres vagy szoftveres a probléma. Az STM32F4DISCOVERY használatának számos előnye van ugyanakkor jellegéből adódóan nem alkalmas, hogy egy kész projektbe illesszük be. Teljesítménye nem biztos, hogy megegyezik a kívánttal. A cél, hogy olyan MCU-t válasszunk ami annyi perifériát (ADC, időzítő, kommunikációs port) tartalmaz és olyan számítási kapacitással rendelkezik amennyire szükségünk van így kerülve el a ki nem használt hardver többlet költségét. Továbbá a fejlesztői kártya méretéből és kialakításából adódóan nem alkalmazkodik a környezethez melyben használjuk. Ebben a fejezetben teszek javaslatot digitális tárolós oszcilloszkóp hardverjének megvalósítására. Az alacsony fogyasztású MCU lehetővé teszi, hogy az oszcilloszkópot az USB portról tápláljuk így megspórolva egy plusz tápegység beépítését. Az USB 5 V-ja és 500 ma-es árama elegendő az áramkör meghajtásához. Két bemeneti csatornája SPI interfészen keresztül állítható erősítésű műveleti erősítőn keresztül csatlakozik az MCU-hoz. Ezen megoldáshoz nem tartozik saját kijelző, az oszcilloszkóp a számítógépre küldené ki a mintavételezés eredményét és ott egy célprogram jelenítené meg a kirajzolandó jelet. 39
7.2. STM32F103C8T6 Az MCU kiválasztás szempontjai: Nagy sebességű analóg-digitális átalakítót tartalmazzon integrálva. Elegendően nagy programmemória és RAM. Kommunikációs interfész a PC felé: legalább USART de a DSO teljes potenciáljának kihasználásához szükséges az USB kommunikációs protokoll használata. Legalább négy általános célú időzítő. STM32F103C8T6 főbb paraméterei: 7.3. két 12 bites 1 μs analóg-digitális átalakító 64 Kbyte programmemória, 20 Kbyte SRAM három USART és egy USB 2.0 full-speed interface hét 16 bites időzítő Elvi kapcsolási rajz A DSO kapcsolási rajzát az NI Multisim 12.0-ban készítettem el amely tartalmazza az iparban használt szabványokat, valamint SPICE szimulációs környezettel van kiegészítve. Előnye, hogy egy lépésben, kompatibilitási hibák nélkül átkonvertálható az elméleti kapcsolási rajz az NI Ultiboard nevű fejlesztő környezetbe amely a National Instruments NYÁK tervező programja. 40
7.1. ábra. A megvalósítási javaslat elvi kapcsolási rajza: MCU, USB csatlakozó, SWD, A és B csatorna, külső oszcillátor. 7.2. ábra. A fenti kapcsolási rajz kiegészítése: a tápegység és szűrő kondenzátorok. 41
7.4. Alkatrészlista Leírás RefDes Láblenyomat Ár [ HUF ] Kondenzátor, 100 nf 5% C1, C2, C3, C4, C8 0402 3 Kondenzátor, 10 nf 5% C5 0402 3 Kondenzátor, 10 μf 5% C6 0402 3 Kondenzátor, 1 μf 5% C7 0402 3 Kondenzátor, 30 pf C9, C10 0402 3 Kondenzátor, 4.7 μf C11 0402 3 Kondenzátor, 10 μf C12, C15, C16 0402 3 Kondenzátor, 0.1 μf 5% C13, C14 0402 3 USB csatlakozó, UX60-MB5ST J2 HIROSE/UX60 300 -MB-5ST HDR csatlakozó, HDR2x5 J3 HDR2x5 250 Ellenállás, 1.5 kω R1 0402 10 Ellenállás, 10 kω R2, R3 0402 10 1-pozíciós mikrokapcsoló S1 Saját készítésű 200 2-pozíciós csúszó kapcsoló S2, S3 Saját készítésű 200 MCU, STM32F103C8T6 U1 LQFP48 1000 Oszcillátor, FOXSDLF/080-20 U2 Saját készítésű 150 Feszültség stabilizátor, MCP 1825S-3302E/DB U3 SOT-223 110 Műveleti erősítő, MCP6S91 U4, U5 SOIC-8 215 A feltüntetett árak csak közelítő jellegűek, gyártónként és típusokként változik az ár. Ezen közelítés alapján a végösszeg 2469 HUF a felhasznált alkatrészek esetében. Ehhez jön még a NYÁK és annak legyártásának költsége, a műanyag tok, valamint a vezetékek ára. Pontos árajánlat kérése nélkül nehéz megmondani a végösszeget de ezekkel a költségekkel együtt sem haladja meg a 10000 HUF-ot így az olcsósági szempont teljesül. 7.5. Alkatrészek funkciói A főbb áramköri elemekhez tartozó kiegészítő alkatrészek értékei a gyártó által az 42
adatlapokban javasolt értékein használtam. C1, C2, C3, C4, C8: zajszűrő kondenzátorok a mikrokontroller 3.3 V-os tápfeszültségéhez. MCP 1825S-3302E/DB, C11, C12: zajszűrő kondenzátorok. A feszültség stabilizátor maximális 6 V-os bemeneti feszültsége és fix 3.3 V-os kimeneti feszültsége, valamint 500 ma-es kimeneti árama megfelelő, hogy az MCU-nak előállítsa a megfelelő tápellátást az USB-ről táplálva. HDR2x5: SWD-n keresztül biztosít debuggolási lehetőséget. UX60-MB-5ST, R1: Az USB csatlakozó ami biztosítja a tápellátást, valamint ezen keresztül kommunikál az oszcilloszkóp a PC-vel. Az ellenállás segítségével állítható be, hogy milyen sebességen szeretnénk használni az USB portot. Ez jelen esetben full-speed azaz 2.0 MCP6S91, C13, C14, C15, C16: Nyolc lépésben 1 32 között állítható az erősítése. Maximálisan 18 Mhz a sávszélessége így nem korlátozza az analógdigitális átalakító sávszélességét. Az ha a műveleti erősítő olyan frekvenciájú jeleket is tovább enged amiket az analóg-digitális átalakító nem tud feldolgozni zavarhatja az átalakítás minőségét így indokolt lehet egy aluláteresztő szűrő beépítése. A kondenzátorok zajszűrő szerepet töltenek be. C5, C7: Az MCU analóg tápfeszültség bemenetének szolgálnak zajszűréssel. Ezen bemenet feszültsége határozza meg az analóg-digitális átalakítás felső feszültség határát. FOXSDLF/080-20, C9, C10: A gyártó által javasolt 8 MHz-es oszcillátor. C9 és C10 értéke 30 pf amit az Stmicroelectronics javasol bár a 20 / 25 pf-os kondenzátorok jobban illeszkednek a választott oszcillátorhoz a számítások alapján. (CL-CS = CL1 x CL2; CL= 20 pf, CS=10 pf így számolva CL1= CL2= 20 pf) S1, C8: A mikrokapcsolóval lehet az MCU-t újraindítani. C8 szerepe, hogy elkerüljük a kapcsoló prellegését. S2, R2: BOOT1 láb feszültségét állíthatjuk a kívánt értékre így beállítva a bootolás módját. S3, R3: BOOT0 láb feszültségét állíthatjuk a kívánt értékre így beállítva a bootolás módját. 43
7.6. NYÁK terv A NYÁK-ot úgy terveztem meg, hogy elférjen az alábbi képeken látható, előre legyártott műanyag tokban. A NYÁK mérete így 74 mm x 30 mm lett tehát a kis méret követelménynek megfelel. NYÁK tervezés szempontjai: Az oszcillátor és az MCU táplábához minél közelebb kerüljenek a szűrő kondenzátorok így biztosítva a megfelelő szűrést. Az analóg-digitális átalakító referencia feszültségére külön szűrő kondenzátorokat rakni. Bár az STM32F103C8T6 LQFP48 tokozású típusnál nincs külön kivezetve a referencia feszültség de az MCU-n belül össze van kötve Vdda lábbal így ahhoz közel kerültek a plusz szűrő kondenzátorok. A jelvezetékek a lehető legrövidebbek, hogy minél kevesebb külső zajt vegyenek fel, valamint a köztük lévő terület ki van töltve föld potenciálú réz területtel, hogy a gyorsan váltakozó digitális jelek által termelt zaj ne jelenhessen meg a szomszédos jelvezetéken. A technika szépséghibája jelen esetben, hogy az analóg és digitális alkatrészek ugyan azt a föld réteget és tápvezetéket használják így ezeken keresztül terjedhet a zaj. 44
7.6.1. Top layey 7.3. ábra. Top layer - az alkatrészoldal és jelvezetékek 7.6.2. Bottom layer 7.4. ábra. Bottom layer - tápvezetékek és azok a jelvezetők melyeket nem tudtam elvezetni a top layer-en 7.6.3. STM32F103C8T6 Próbapanelhez Elkészítettem az MCU olyan változatát ami minden külső alkatrészt nélkülöz így ültethető be próbapanelbe a későbbi prototípus készítéséhez. 45
7.6. ábra. Az MCU beültetve próbapanelbe 8. 7.5. ábra. A két elkészült példány Összefoglalás Szakdolgozatom célkitűzése egy alacsony költségvetésű digitális oszcilloszkóp megtervezése volt mely alkalmas hangfrekvenciás mérések elvégzésére. A felhasznált, ARM processzort tartalmazó MCU az egész projekt lelke mely olcsón kapható és integrálva tartalmazza mindazt amire szükségem volt a digitális oszcilloszkóp elkészítéséhez. Számtalan előnye mellett azonban tartalmaz hátrányokat is melyek megnehezítették szakdolgozatom elkészítését. Ilyen negatívum az MCU bonyolultsága, a hosszú tanulási szakasz. Könnyebbség azonban, hogy egy igen elterjedt processzor típusról van szó így számos területen felhasználható a megszerzett tapasztalat. Egy digitális oszcilloszkóp elkészítése számos szakterületet magába foglal mint a nagy frekvenciás analóg és digitális áramkörök tervezése, mikrovezérlő programozása, USB kommunikáció, valamint a PC oldali program elkészítése Windowsra vagy akár Linux alapú rendszerre. Ezen szakterületek együttesen alkotják egy ilyen mérőműszer elkészítéséhez szükséges ismereteket. 9. Summary The main goal of my thesis was the develop of a low cost digital oscilloscope wich can measure audio frequency signals. The digital oscilloscope built around an MCU wich is based on an ARM prcoessor. This MCU is cheap and it has the capability to be the core of my digital oscilloscope. It has a lot of advanteges but there are disadvanteges too. For 46