15-szegmenses vákuum fluoreszcens kijelző (VFD) vezérlése

Egy SANYO DVD-DX60 típusú lejátszó vákuum fluoreszcens kijelzőjét vezéreltem ATmega324P mikrovezérlővel:

Figyelmeztetés: a DVD lejátszó belsejében 230V-os feszültség van, ami életveszélyes! Csak az üzemeltesse nyitott burkolattal, aki biztos a dolgában!
A VFD kijelző üvegből van, óvatosan kell vele bánni. Az üvegtestből általában kilóg egy kis csonk, ami ha letörik, megszűnik a vákuum és használhatatlan lesz a kijelző. A fűtőszál (filament) ugyancsak érzékeny: ha leejtjük, elszakadhat, ha túl nagy áramot kap, akkor is tönkremehet.
Áttekintő kép a szétszedett DVD lejátszóról, a mikrovezérlőről és az USB-soros illesztőről:
SANYO DVD-DX60 belülről
A lejátszó eredeti uPD16311 kompatibilis VFD kontrollerét használtam fel. Az uPD1631x vezérlőket a NEC gyártja, de számtalan klón is létezik; például AD312, PT6311, PT6312, stb. További adatlapok itt találhatók. A legtöbb VFD-vel készült DVD lejátszóban ilyen vezérlő van. A 312 és 311 végű IC-k között csak apró különbség van a vezérlés szempontjából: a 311-es több szegmenst tud meghajtani, több memóriája és több lába is van.
A DVD kijelzője általában külön panelra van szerelve az uPD IC-vel és néhány mikrokapcsolóval, LED-del, infravevővel együtt. Általában két kábelköteg megy ehhez a panelhoz: az egyik a tápfeszültségeket a másik pedig a vezérlőjeleket viszi (STB, CLK, DATA). A MCU-n így kötöttem be ezeket a vezetékeket: PC0→CLK, PC1→DATA (DOUT, DIN), PC2→STROBE (lásd vfd.h).
Kijelző panel bekötése
Tápellátás gyanánt szükség van 5V egyenfeszültségre a kontroller IC-nek, kb. 1..3 V-os váltakozófeszültségre a kijelző fűtőszálának és DC -24 V-ra a szegmensek felvillantásához. De ez utóbbi a vezérlő IC-hez van bekötve. A DVD lejátszó tápegységének paneljén ezek a feszültségeket fel is szokták tüntetni, ha nincsenek, érdemes kimérni. A kísérletezés elején persze célszerű a DVD lejátszó saját tápegységét használni. (Sőt, ha megépítendő készülékünk belefér a DVD dobozába, érdemes abba szerelni: így megspórolhatjuk az előlapi gombok kialakítását is.)
Az STB, CLK és DATA jelek egy kétirányú soros interfészt valósítanak meg, ami az SPI-hoz hasonlít. A DATA vonal a VFD kontroller DIN és DOUT lába egymással összekötve. Ezt mindenféle baj nélkül meg lehet tenni, mert csak bizonyos parancsok után kezdi az IC vezérelni (GND-re húzni) a DOUT lábat. A láb egyébkét nyitott drain-ű, ha szétválasztanánk a DOUT és DIN kivezetéseket, akkor egy felhúzóellenállással tápfeszültségre kellene kötni. A STB (strobe) a chip selectnek felel meg, ennek megfelelően a VFD vezérlő akkor fogad vagy küld adatokat, ha a STB alacsony szinten van. A CLK pedig a soros átvitel órajele, maximum 1 MHz lehet a frekvenciája.
Egy bájt elküldése körülbelül így néz ki, ha szoftveresen (bit-banging) állítjuk a lábakat:

  1. a STB-ot alacsony szintre állítjuk (utána várjunk 1 µs-ot),
  2. a CLK-ot alacsony szintre állítjuk (és utána várjunk 500 ns-ot),
  3. a DATA vonalat magas (1) vagy alacsony (0) szintre állítjuk attól függően milyen bitet akarunk küldeni (majd várjunk 500 ns-ot),
  4. a CLK-ot magas szintre állítjuk, (ismételjük a 2. ponttól a lépéseket még hétszer)
  5. a STB-ot magas szintre állítjuk (de előtte várjunk 1 µs-ot).

uPD16311 és uPD16312 soros adatátvitel
A fenti adatátvitel -- a STB vezérlés kivételével -- a VFD_writeByte() függvényben van implementálva. Figyeljük meg, hogy az első elküldött bit a b0 vagyis a legkisebb helyiértékű bit (LSB)! Több bájt átvitele esetén is a STB jel maradjon alacsony szinten. Ha adat olvasás parancsot küldünk, ami után adatot kell vennünk, akkor a DATA vonalat bemenetként kell konfigurálni és azelőtt kell lekérdezni állapotát, mielőtt a CLK-ot magas szintre állítanánk. Egy byte olvasása a VFD_readByte() funkcióban van. Ezt használja például a VFD_readKeyData() függvény, amivel a mátrixba kötött billentyűk állapotát lehet lekérdezni.
Az alábbi ábrán a 0b10001011 parancs elküldése látható, ami 10/16-os kitöltési tényezőt és a kijelző bekapcsolását állítja be a display control command segítségével:
Adatátvitel példa uPD16311-es vezérlővel
A szaggatott vonallal az órajel felfutó élét jelöltem meg, akkor vesz mintát az uPD1631x-es kontroller és állapítja meg, hogy a vett adat 0 vagy 1.
A kijelző összes szegmensének bekapcsolásához a következő parancsokat kell használni (részleteket lásd az IC adatlapján):

  • Display mode setting command: például 8 digit, 20 szegmens. De ki kell kísérletezni, hogy a kijelző melyik módban működik jól.
  • Display control command: kitöltés lehet 14/16 (legvilágosabb betűket eredményezi) és képernyő BEKAPCSOLÁSA.
  • Data setting command: írás az adat memórába és a cím növelése eggyel minden írás után, normál működési mód.
  • Address setting command: az elkövetkező írások címe (0) és 22 vagy 48 bájt 0xFF.

Az első két parancs a VFD_init() függvényben van megvalósítva. A második kettő pedig a VFD_writeDispMem(), VFD_writeDispMemBuf(), VFD_all() és VFD_clear() függvényekben.
Magasabb szintű ASCII ill. hexadecimális karaktereket megjelenítő függvények a vfd_dx60.c fájlban találhatók: VFD_printNumber(), VFD_printStr(), VFD_printChr().
Az ASCII karakterek megjelenítéséhez 15-szegmenssel gazdálkodhattam. Így néz ki az ABC első néhány betűje:

 -----    -----    -----    -----    -----    -----    ----- 
|     |     |  |  |           |  |  |        |        |      
 --.--      .--               .      --.      --.         -- 
|     |     |  |  |           |  |  |        |        |     |
          -----    -----    -----    -----             ----- 

A 32..127-es kódú számokat megrajzoltam a vfd_dx60_font.txt fájlban. Ezt a fájlt pedig egy genfont.py Python script konvertálja át fordítható C fájllá: vfd_dx60_drawchar.c.

Az elkészült forráskódok innen tölthetők le:
lp:vfd
~ivanovp_vfd_trunk.tgz
A bazaar verziókezelőt használom a forráskódok tárolásához.