HTML

Műszer

Hobby és amatőr elektronika, műszerépítés a XXI. században

Címkék

Friss topikok

  • Nite: @fromi: Ha egy bejegyzéssel kapcsolatos kérdésed van, akkor jobb odaírni kommentbe, mert esetleg m... (2010.11.26. 15:17) FAQ

Licenc

Creative Commons Licenc

DDS Jelgenerátor

Nite 2012.09.03. 15:02

Végre-valahára elkészült az első béta verziója a függvénygenerátoromnak, ha valakit érdekel, nyugodtan megépítheti vagy felhasználhatja az itt leírtakat a saját projektjeiben.
A DDS jelgenerátorok egy D/A átalakító segítségével állítják elő a kimenetükön a kívánt jelalakokat, az elvről bővebben már írtam egyszer itt.

A most bemutatásra kerülő DDS jelgenerátor paraméterei:

- 200 MSPS
- 2 kbyte sample memória
- 0.01 Hz - 50 MHz frekvencia, 0.01 Hz felbontással
- Torzítás < 0.5% (8 bit/minta)
- Jel/zaj viszony > 30 dB (reconstruction filter nélkül, ez még később jobb lesz)
- 50 Ohm kimenet
- Max. +-6V kimenet
- +-2.5V DC offset
- Phase -90° - +90°

- Sin, Cos, háromszög, négyszög, zaj jelalakok generálása tetszőleges kitöltési tényezővel (háromszögből fűrész, négyszögből impulzus)
- Trigger és digital data output
- Tetszőleges sweep a frekvenciatartományon belül
- AM/FM/Phase moduláció előkészítés (a szoftver még nem tudja)

Címkék: dds jelgenerator

Szólj hozzá!

A DSO és a Trigger

Nite 2012.08.10. 13:53

  Bármilyen oszcilloszkóp lelke a trigger, enélkül csak bámulhatnánk a képernyőn futó jelalakokat, folyton lemaradnánk arról az eseményről ami érdekel minket, vagy hosszasan keresgélhetnénk a felhalmozott adatkupacban. A minimális funkciója egy triggernek arról gondoskodni, hogy az analóg szkópok képernyőjen az elektronsugár mindíg ugyanabból a fázisából kezdje el a bejövő jelet felrajzolni, így szemmel is látható csíkot kapva, de a digitális szkópok erre rátesznek még egy lapáttal, és elintézik, hogy tényleg csak azt lássuk, ami érdekel minket. Érdemes megkülönböztetni az analóg triggerelési módokat a digitálistól, mivel ezeket külön áramkörök biztosítják, és más lehetőségeink vannak a paraméterezéseikre is.

 

  Analóg trigger

  Az analóg trigger gyakorlatilag egy komparátor, ami összehasonlítja a bejövő jel szintjét egy előre beállított értékkel. Amikor a jel alulról vagy felülről átlépi a trigger szintet, akkor generálódik a trigger jelzés, ami elindítja az elektronsugár végigfutását a képernyőn, vagy a digitális formájának a tárolását. Minden analóg trigger paraméterezhető, hogy ez a trigger szint hol legyen, és hogy lefutó vagy felfutó él indítsa-e el a triggert. Ezen kívül érdekes lehet még azt beállítani, hogy az esetleg vizsgált több bejövő jel közül melyiket vegye alapul a trigger áramkör, AC vagy DC csatolást alkalmazzon, illetve szoktak még a trigger jel elé különböző low pass és high pass filtereket bekapcsolni, hogy az esetleg nem kívánt túl alacsony vagy magas frekvenciájú zavarjelek ne generáljanak hibás trigger jelzést. A trigger áramkör bemenetét szokás külön is kivezetni a szkópokon, hogy a mérendő jelektől független trigger jellel is lehessen vezérelni.

  Az analóg trigger nagy előnye, hogy a digitális szkópunk belső órajelétől teljesen aszinkron módon képes trigger jelzést generálni, amit felhasználhatunk mondjuk a már ismertetett ETS megvalósításához. Hátránya viszont, hogy a felsorolt módozatainál és paramétereinél többet csak bonyolult elektronikával lehet megvalósítani, nagyságrendekkel pontatlanabbul, mint digitális triggerrel.

 

  Digitális trigger

  A digitális trigger a digitális szkópoknál azt használja ki, hogy a bejövő jelet a csatorna ADC-je folyamatosan a legnagyobb mintavételezési sebességen digitális jellé alakítja, és azt egy digitális feldolgozó áramkörnek (pl. FPGA) továbbítja. Itt aztán a jelen bármilyen művelet végezhető a trigger indításához. Pár gyakran használt digitális trigger mód:

- Él triggerelés. Nagyjából ugyanúgy működik, mint az analóg trigger esetében. Az FPGA-ban beállítunk egy értéket, amit ha a jel átlép, triggert generálunk. Ahhoz, hogy tudjuk, lefutó vagy felfutó élt látunk-e, az aktuális minta értékéből kivonhatjuk az előző minta értékét, és az eredmény előjele alapján dönthetünk, hogy kell-e triggerelni. Fontos előnye a digitális él triggerelésnek, hogy az aktuális és az előző minta különbsége megadja az él meredekségét, így ezt is beállíthatjuk mint trigger paramétert.

- Pozitív vagy negatív impulzus trigger. A felfutó vagy a lefutó élt észlelve az FPGA-ban elindítunk egy számlálót, amivel mérhetjük a következő lefutó vagy felfutó él érkezéséig eltelt időt. A trigger jelzés indításának paramétere lehet az, ha ez az idő a beállítottnál kisebb vagy nagyobb, vagy valamilyen határból kilóg.

- Runt pulse trigger. A felfutó vagy a lefutó él után meghatározott idővel megvizsgáljuk a bejövő jelet, és ha egy beállított szint alatt vagy felett marad, akkor indítjuk a triggert.

- Trigger rearm delay. Beállítható, hogy a trigger jelzés után mekkora időnek kell minimum eltelnie, mire az FPGA a következő triggert keresni kezdi. Ez akkor hasznos funkció, ha bonyolult jelalakot vizsgálunk, és a jelsorozaton belül több ponton is élesedne a triggerünk.

- nth trigger. Beállítható, hogy a trigger rearm delay lejárta után (vagy az utolsó trigger eseménytől számított bizonyos idő után) ne közvetlenül az első trigger feltétel generáljon jelzést, hanem az n-edik.

- Trigger több csatornáról. Mivel az FPGA egyszerre az összes csatorna bejövő jelét nyomonköveti, az egyes csatornák triggerjelei különböző logikai feltételekkel kombinálhatóak.

- Összetett trigger. Az eddig felsorolt trigger feltételeket különböző logikai műveletekkel kombinálhatjuk, hogy a végleges trigger eseményt megkapjuk.

- Pre-trigger, post-trigger, és késleltetett időalap. Mivel az FPGA a bejövő jeleket folyamatosan a memóriába menti, a trigger jel beérkezésekor dönthetünk úgy is, hogy ezzel fejezzük be a mérést ahelyett hogy indítanánk. Így a memóriában a trigger előtti eseményeket fogjuk találni. Azt is beállíthatjuk, hogy a trigger jel beérkezése után mekkora időt várjunk a mérés befejezéséig. Ez az idő akár nagyobb is lehet, mint amíg a memória betelik, ilyenkor a memória már a trigger eseményt sem fogja tartalmazni. Dönthetünk úgy is, hogy a trigger jel után bizonyos idővel más időalapra váltunk, majd ezután valamennyivel fejezzük be a mérést, ez a késleltetett időalap működése. Ilyenkor a bejövő jel egy meghatározott részletét vizsgálhatjuk meg jobb felbontásban.

- Protokoll trigger. A bejövő jelet első lépésben meghatározott protokoll szerint értelmezzük (pl. ISP, I2C, CAN, LIN, USB, videójel), és a protokoll értelmezése során keletkező eseményekre triggerelünk (pl. start frame, stop frame, stb)

  Láthatjuk, hogy a digitális trigger nagy előnye, hogy igen összetett feltételrendszerrel kiszűrhetjük azokat az eseményeket, amikre tényleg kíváncsiak vagyunk. A fent leírt feltételek mind egyszerűen megvalósíthatók (a protokoll trigger kivételével) elemi logikai áramkörökkel (komparátor, számláló, stb), amiket az FPGA-nk amúgy is tartalmaz. Hátránya, hogy a bejövő jelen történt eseményekről akkor fog csak értesülni, amikor a belső órajellel szinkron az ADC feldolgozta azt. Ha a bejövő jelen két órajel között gyors változás történik, abból nem is fogunk látni semmit (vagyis erre is van módszer elvileg, egy külső, órajel független latch segítségével). Ebből következik, hogy ETS-t sem lehet digitális triggerrel megvalósítani.

Címkék: trigger dso

Szólj hozzá!

Equivalent Time Sampling - mi ez, hogy működik, és jó-e ez nekünk...

Nite 2012.08.06. 16:29

 Valószínüleg akik digitális oszcilloszkópokat nézegettek már, találkoztak ezzel a bűvös kifejezéssel, manapság nem is nagyon lehet olyan szkópot venni amire nem írnák rá hogy sample rate: 100MSPS, equivalent time sampling (vagy ETS): 1GSPS vagy akár hazudhatnak mégnagyobbat is, mondjuk 10GSPS. Ettől aztán az egyszeri júzernek megindul egyből a nyálelválasztása. Annyi valószínüleg mindenkinek eszébe jut az ETS működéséről, hogy ezt a rengeteg sample-t nem a mérendő jel egy periódusa alatt szedi össze a műszer, hanem 10-100 periódus alatt, vagyis az egész nem használható, ha a bejövő jelünk nem periódikus.

 A rutinosabbak vetnek egy pillantást az analog bandwidth paraméterére is a műszernek, ugyanis az hótziher, hogy az ide leírtnál nagyobb frekvenciájú jelet soha az életben nem fognak mérni a szkópjukkal, az valahol a bemeneti erősítőnél el fog veszni. Általában egy bénább szkóp paraméterei úgy néznek ki, hogy 100MSPS real time, 200MHz analog bandwidth, 1GSPS equivalent sampling - ebből már lehet tudni, hogy vagy kínaiak, vagy hobbisták csinálták (tisztelet a kivételnek). Nade mit is jelent ez?

- 200MHz jelnél a bemenet csillapítása -3dB, vagyis ekkora frekvenciát ráakaszthatunk a szkópra.

- A szkóp legfeljebb 100 millió jelet rögzít egy másodperc alatt, vagyis a 200MHz-s jelünkből real time módban semmit sem fogunk látni. Ahhoz hogy valami fogalmunk legyen arról, mi történik a bemeneten, legfeljebb 25MHz körüli jelet szabad mérnünk, ennek egy periódusából 4 mintát vesz a gép (vagyis arról, hogy akkor ez most szinusz, négyszög, vagy háromszög, gőzünk sem lesz, csak hogy valami változik). Egy 10MHz körüli jelnek már az alakját is megbecsülhetjük nagyjából az alapján a 10 pont alapján, amit a szkópunk rögzített.

- Ha a bejövő jelünk viszont periódikus, akkor ráuszíthatjuk az ETS-t, ami 10 periódus alatt összeszed a jelünkből 10x annyi mintát, mint real time módban. Így a 200MHz-s jel egy periódusára is jutni fog 5 minta, amiből már láthatjuk, hogy legalább mozog...

 

Na jó de hogy csinálja?

 Marha egyszerű, mondok egy hasonlatot. Kimész a Hungaroringre, és videót szeretnél készíteni arról ahogy egy versenyautó befordul a célegyenesbe, de nincs kamerád csak fényképezőgéped. Mit csinálsz?

- először is kell egy trigger, mondjuk legyen az, ahogy az autó eléri a kanyar elejét. A legelső körben lefényképezed az autót itt.

- a második körben a trigger után (vagyis amikor az autó elérte a kanyar elejét) vársz még 0.1 másodpercet, és csak azután fényképezed le.

- a harmadik körben 0.2 másodpercet vársz a trigger után.

...

- mire a huszadik kört is megtette az autó, te már 2 másodpercet vártál a kép elkészítésével, és mehetsz haza a húsz fényképeddel. Otthon egymás után rakod őket, és filmet készítesz belőle. A filmen megcsodálhatod, ahogy az autó befordult a kanyarba.

 Látható, hogy ehhez az kell, hogy az autó lehetőleg minden körben ugyanazon az íven menjen, az ilyen hibajelek mint pl előzés nem jelennek meg a kis ETS filmeden.

Hogy néz ez ki elektronikában? Kb így:

 Fent a "Gate" jel a trigger, mint látjuk akkor keletkezik, amikor a jelünk felfelé menet átlépi a nullát (középső vonalat). Az "Out" jel minden periódusban delta D idővel később készül, így a bejövő jelet különböző fázaisaiban kapja el (piros pöttyök). Ha ezt elég sokáig csináljuk, majd a piros pöttyöket egymás után rajzoljuk, megkapjuk a bejövő jel alakját.

 

Serial ETS vs Random ETS

 A fent leírt módszer a Serial ETS-t mutatja be. Röviden tehát annyi a serial ETS lényege, hogy a trigger után meghatározott, pici, pontos időegységeket vár szépen növekvő sorrendben, és így járja be a bejövő jelet.

 Van az ETS-nek egy másik formája is, a random, amit megérteni kicsit nehezebb, a hardvere viszont egyszerűbb tud lenni. A random ETS megértéséhez azt kell látnunk, hogy a bejövő jelünk által indított trigger általában nem esik egybe azzal a pillanattal, amikor az ADC mintát vesz a jelünkből.

 Miért? Ez egyszerű, azért mert az ADC általában egy meghatározott órajelről fut folyamatosan, amit nem nagyon fogunk módosítgatni, általában ez a szkóp legnagyobb real time mintavételi sebessége, mondjuk 100MSPS esetén 100MHz. Ez akkor is így van, ha mondjuk egy 50Hz-es jelet vizsgálunk éppen, ugyanis az ADC-knek van egy minimum frekvenciája amin hajlandóak működni (mondjuk egy 100MSPS ADC-nál ez olyan 20MSPS), mivel a sample and hold áramkör nem képes a vett mintát a végtelenségig tartani. Kis frekvenciás jelek vizsgálatánál azokat a mintákat amik nem kellenek (mert mondjuk nem férnének be a memóriába amúgy sem) a szkóp eldobja.

 Szóval van egy órajelünk, ami odabent ketyeg az ADC mellett a szkópban. Egyszercsak beesik egy trigger, hogy a bejövő jelünk átlépte a trigger szintet. Mikor vesz mintát a jelből az ADC? Amikor a saját órajele legközelebb felfutó élen lesz, tehát n1 idő elteltével. A következő periódusnál megint beesik egy trigger, és az ettől teljesen aszinkron ADC vesz belőle egy mintát n2 idő elteltével. Majd a harmadik periódusban n3 elteltével, stb.

 Hogy lesz ebből ETS? Ha megvan a mintánk mondjuk 20 periódusra, és emellett felírtuk n1...n20 értékét, akkor a 20 mintát sorba tudjuk rendezni a legkisebb n-től a legnagyobbig, és kész is a jelünk, valahogy így:

 

Megvalósítás

 Vegyük először a serial ETS-t, ez a pontosabb de bonyolultabb módszer. Ehhez az ADC mintavételi órajelét tologatni kell a triggerhez képest meghatározott időkkel. Látnunk kell, hogy mivel fogalmunk sincs, hogy a trigger mikor fog beesni, nem tudunk folyamatosan mintavételezni mint a random esetben (ezért a serial ETS-nél a trigger előtti jelek nem vizsgálhatók). Amikor viszont bejött a trigger, nagyon pontosan időzítenünk kell, majd ellőni az ADC-t - ez a módszer nagyon hasonlít a fenti fényképes analógiára. Egyszerűnek tűnik, de hirtelen jó  megoldást nem is tudnék mondani, hogy ennyi fajta órajelet hogyan lehetne szinkronizálni a triggerhez amatőr körülmények között.

 Jóval egyszerűbb a random ETS, ahol az ADC folyamatosan futhat, épp csak az eltelt időt kell megmérni a trigger és az azt követő mintavétel között. Ezt ne úgy képzeljük el, mint az időmérést általában, hogy a triggerkor elindítunk egy countert, és megnézzük az értékét a mintavételkor - ehhez iszonyat órajelen kéne futnia a számlálónknak. Sokkal inkább úgy szokták megoldani a dolgot, hogy a trigger jelével elkezdenek egy kis kondit tölteni, és a benti órajel következő felfutó élére két ADC is mintát vesz: az egyik a bejövő jelből, a másik pedig a kis kondin lévő feszültségből, mely az eltelt idővel pont arányos. Ezt az értéket hozzácsapják a vett mintákhoz, és a mintavétel végén ez alapján sorba állítják őket.

 Szkóp építéskor nem biztos hogy csak az ETS miatt két ADC-t akarunk használni egy csatornához, van más megoldás is barkács ETS-re: a trigger ugyanúgy tölteni kezdi a kis kondit R ellenálláson keresztül, majd az órajel bejöttekor elkezdjük kisütni 20R ellenálláson keresztül, ami elvileg 20x annyi ideig fog tartani. Hogy mikor ér a 0-ra, azt egy komparátorral vizsgálhatjuk, és ennek a lassabb jelnek a hosszát már mérhetjük számlálóval.

 A random ETS előnye, hogy a trigger előtti mintákat is felhasználhatjuk, hátránya viszont, hogy ha a bejövő jelünk és az ADC órajelének frekvenciája megegyezik, vagy egymás harmónikusai, akkor az egész elvünk nem fog működni, mivel a triggertől mérve mindig ugyanannyi idő elteltével fog indulni az ADC. Ennek kiküszöbölésére találták ki az ADC Clock Dither-t, ami a bejövő jel két periódusa között megváltoztatja az ADC órajelének a fázisát mondjuk egy PLL-el, így ezek a jelek is mérhetőek lesznek.

 

Jó ez nekünk?

Szerk.: pár dolognak utána néztem és eszerint módosítottam az írást

 Röviden: igen is meg nem is.

 Ez leginkább azoknak a marhanagy cégeknek jó, akik oszcilloszkópokat gyártanak, és el tudják őket adni félmillió forintért. Ennek megértéséhez nézzük meg, hogy működik egy olyan ADC, amit a boltban megvehetsz.

 Minden ADC elején van egy sample and hold áramkör, ami mintát vesz a bejövő jelből, és addig megőrzi a felvett értéket, amíg a konverter fokozat kisilabizálja a digitális értékét. Ez nagyon-nagyon-nagyon leegyszerűsítve így néz ki:

 A ctrl1 és ctrl2 kapcsolók felváltva működnek. Amikor ctrl1 zárva van és ctrl2 nyitva, akkor az áramkör mintát vesz a bejövő jelből. A következő fázisban ctrl1 lesz nyitva, ctrl2 zárva, ilyenkor a kimeneten megjelenik a vett minta. A jelenleg megvásárolható ADC-k úgy működnek, hogy a bejövő órajel felfutó élére mintát vesznek, a lefutó élre tartani kezdik azt, és konvertálják digitális jellé.

 Ez azt is jelenti, hogy két ADC-t simán párhuzamosan lehet kötni, ha az egyik órajelét invertáljuk. Ilyenkor amíg az egyik konvertál, addig a másik mintát vesz, és vica versa - két db 100MSPS ADC-ből csináltunk egy 200MSPS-est, hurrá.

 Ugyanakkor az is tuti, hogy amíg az ADC-nk mintát vesz, addig a bejövő jelnek bármiféle nagyon gyors változását a mintavételező kondik integrálni fogják, a mintavételi idő tartamán keresztül - ami ugye az órajel fél periódusa. Ez olyan, mintha a fenti versenyautós-fényképezős analógiánkat sötétben kéne megoldanunk, vaku nélkül, 1 másodperces záridővel: lesz ugyan 20 képünk, de mindegyik tök homályos, és tippünk se lesz a végén, hogy hol is volt az autó a kanyarban. Ha az elektromos jeleket ábrázoló képeket nézed, nagyon szép piros meg fekete pöttyöt rajzolt oda a mintavételhez a készítőjük, csakhogy azok nem pöttyök, hanem csíkok lesznek, amiken belül a jel változásáról halvány gőzünk sem lehet.

 A tanulság annyi, hogy ETS kivitelezéséhez nem elég egy gyors ADC - kell hozzá egy sokkal de sokkal gyorsabb sample and hold áramkör is. Ilyet pedig eddig még nem láttam boltban, meg kell szépen építeni. Ha azt vesszük, hogy 500MSPS-es ADC még kapható, sőt, ha valaki nagyon akar, szerezhet magának 1GSPS-est is, szerintem sokkal jobban jár mindenki ha nem kezd neki sample and hold építgetésének. 100ps alatt mintát venni egy jelből? Úgy, hogy még csak műszered sincs, amivel megnézhetnéd, hogy működik-e az áramköröd?

 Horror. (egyszer esküszöm nekilátok :)

 Mi az a frekvencia, ameddig a sample and hold áramkör követni tudja a bejövő jel változásait? Az ADC adatlapján ezt is megtaláljuk, "analog input bandwidth" címszó alatt. Egy ilyen primitív ADC-nél, mint mondjuk az ADS830, ez speciel 300MHz (nem is rossz egy 60MSPS-es konvertertől). Ha ez alatt marad a jelünk, akkor használhatunk ETS-t arra, hogy feltérképezzük. ETS nélkül ezzel az ADC-vel legfeljebb 15-20 MHz-es jelek vizsgálhatók. Ha feltételezzük, hogy a jelünk periódikus, ETS-el a mintavételnek könnyen elérhető a 10-20szorosa is, tehát akár a 200MHz sem feltétlenül marad álom.

Címkék: ets dso equivalent time sampling

Szólj hozzá!

Előre!

Nite 2012.07.28. 20:04

Kis heads-up: megterveztem a DDS Jelgenerátorom, és meg is építettem, rettenetes anyázások közepette, kb. 1 hónap alatt. Mikkel szerencsétlenkedtem?

- A NYÁK nagyon szép lett, teljesen új koncepcióval dolgoztam, épp csak 120 via lett rajta. Na ezeket mire mind beforrasztottam, azt hittem megőszülök. Ha megengedhetném magamnak, vagy gyártatnám a paneljaimat, vagy valami rendes furatfémezési módszer után néznék...

- Amivel nem volt baj, az a 0.2 vezető - 0.2 szigetelő szélesség, 2 oldalon. a két oldal között kb 0.2mm elcsúszást sikerült összehoznom, kicsit vigyázni kellett a fúróval. Ja, a nagy vigyázás közben el is törtem egy fúróhegyet...

- Az üres részeket kitöltöttem telefölddel, ez bekúszott az SMD cuccok lába közé, és marha könnyen rövidre záródott forrasztás közben - na ezt a hibát nem követem el újra.

- Az FPGA kapott maga alá egy föld plane-t, amit olyan ügyesen körbevettem a tápvonalakkal, hogy teljesen elvágódott a rendes földemtől. A nyáktervező progim persze nem szólt, biztos volt még szerinte olyan 0.1mm valahol, ami nekem lemaródott. Hejj de fogtam a fejem amikor ezt észrevettem...

- A tápok szépen feléledtek (lassan már dc-dc konverterekkel álmodok), beraktam a PIC-et, bekapcsolom, semmi. Rengeteget gondolkoztam miért nem működik, aztán kiderült hogy a ledeket más lábra tettem, így jóhogy nem világítottak, az USB-n meg volt egy sense, amit nem kötöttem be (USB-ről kapja a tápot, nyilván van USB mire feltápászkodik), de a programból nem vettem ki, persze hogy nem indult. Szoftveres reszelgetés után már gyönyörű.

- Deviszont a PIC-en felcseréltem az I2C-hez az SCL és az SDA lábakat, szörnyen szidtam magam miatta, átmadzagoltam.

- Az FPGA ezek után már viszonylag fájdalommentesen bekerült, és szépen működött is. Forrasztás közben vagy összesen 20 lábát zártam össze, jó móka volt utána takarítani.

- Ekkor vettem észre, hogy olyan tokozású DAC-ot terveztem bele, ami nem volt itthon, úgyhogy rendelhettem a farnelltől (másnapra itt volt :D )

- Viszont egyszer már elbaltáztam az AD8000-es opamp lábkiosztását, és persze a rossz rajzról hoztam át a véglegesre, úgyhogy ezzel rengeteget szívtam mire bedrótoztam a helyére a kis lábnélküli smd szart.

- Egyébként kb a felénél vettem észre, hogy az egész elvi hibás, ha az FPGA-t a PIC mellé rakom és nem alá, minimálisan nagyobb panelon sokkal rövidebb tápokkal-földekkel megúsztam volna.

- Ettől teljesen függetlenül a DC-DC konverterek úgy zajonganak mint egy állat. A kimenő jelen olyan gyönyörű 50mVpp 1MHz zaj figyel hogy öröm nézni. Nagyon bíztam benne, hogy most így az előzőekből okulva, rendes NYÁKtervvel, szép széles teliföldekkel csökkenthető a zaj, de úgy tűnik nem. Ez kb azt is jelenti, hogy vissza a tervezőasztalhoz, vissza az analóg, melegedő, de legalább csendes tápokhoz, és replay!

 Hát ezzel megint elleszek egy hónapig nagyjából, ha két rétegen megvan a cucc, megtervezem négyrétegűre, és gyártatok belőle párat. Ez már nagyjából az első release verzió lesz, az alpha és a két béta után...

 Közben megrendeltem pár alkatrészt a DSO-mhoz is, aminek ugye a PIC és az FPGA része ugyanez lesz, csak az analóg bemenettől az ADC-ig kell megrajzolnom, kikísérletezni, mennyire használhatóak a relék, meg mindenféle elvetemült fícsörön gondolkozni mint pl. mintavételi sebesség duplázás két ADC-vel, meg analóg trigger, meg ETS, de ez már a jövő zenéje.

Szerk.: A lényeget nem is mondtam, megvan a 200 MSPS, vagyis 50MHz szinusz. Az FPGA, a DAC és az erősítők is nagyon jól viselik (csak a szkópommal nem tudom rendesen megmérni :) úgyhogy új táp kell csak és kész. Találtam egy ígéretes táp kapcsolást, talán még olyan vészesen meleg se lesz...

Szólj hozzá!

DDS jelgenerátor szoftver

Nite 2012.06.24. 10:44

 Hűha, elég régen nem jártam errefelé... Sajnos nem könnyű úgy szoftvert fejleszteni itthon, hogy közben ez a melóm is. Mire hazaérek, elég sokszor úgy vagyok vele, hogy ne is lássak inkább számítógépet. Persze egy PC alapú jelgenerátor lelke a szoftver, meg kell írni és kész, de ritkán volt hozzá elég ihletem. Olyannyira, hogy mostanra készült el.

 Íme, a DDS jelgenerátor PC-s felhasználói felülete:

 

 Nyilván lesz akit nem annyira a kép érdekel hanem a forráskód. Közben történtek változások a fejlesztés menetében is, a google code-ra költöztettem a cuccot:

 Innen lehet elérni.

 A PIC könyvtárban található a PIC-es firmware, a SignalGen-ben pedig a GUI. Persze nem mondom hogy nincsenek benne már hibák, meg TODO kezdetű kommentek, de ettől függetlenül tökéletesen használható. Nézzünk meg egy pár generált jelet is:

 

 Ez ilyen szinusz. Tud még koszinuszt is, illetve van rajta fázis állítási lehetőség, de ezeknek semmi értelme, amíg a szkóp erre triggerel. Majd a végleges hardverbe lehet hogy teszek trigger kimenetet is (ja és a fázis állításnak több értelme lesz ha teszek bele mondjuk fázis modulációt, de mivel nem foglalkozok olyasmivel amihez kéne, egyelőre nem sürgős).

 

 Tud persze háromszöget és négyszöget is, állítható duty cycle-el.

 

 Bocs, tudom, szörnyű a kép minősége

 


 Vicces módon duty cycle-t lehet állítani a szinusznál is, nagyon hülyén néz ki és értelme is kb annyi van :)
 (de pl tud generálni így ilyen egyenirányított szinusz jelet is, csak nincs képem hozzá)

 

 Nagyfrekvenciás zaj (kb 25MHz, 20mV) a négyszög tetején. Ez egyértelműen az FPGA és a DAC órajeléből jön, nagyon bízom benne, hogy a végleges panelon sokkal szebb lesz, illetve a szűrő a végén leszedi.

 

 Kisebb frekvenciás zaj, ez jön a tápból. Logisztikai okokból nem az új, zajtalanabb DC-DC-m hajtja, hanem a régi, de így sem túl vészes.

 

 Naés, a legnagyobb fícsör, a SWEEP! Ebben az üzemmódban a szkóp egyik csatornáját a generátor sweep kimenetére kell kötni, ahol a frekvenciával arányos fűrészjel jön ki. (akartam csinálni logaritmikusat is, de első körben úgy tűnt, nem fogja bírni a PIC a számítást. talán majd a jövőben) Az "external x deflection"-t beállítva kaphatunk ilyen szép ábrát. Középen a vastagabb csík a kurzor, aminek a pozíciója változtatható és leolvasható a GUI-ról.

 

 Egy kondi meg egy ellenállásból aluláteresztő szűrő? persze, tanítják, de élőben látni más. A kurzor olyan 3kHz-nél.

 

 Ez kb. uaz a szűrő, csak a képernyőn most nem 25kHz a vége, hanem 100kHz.

 Hát, kb ennyit tud most. Hogyan tovább?

 Nekilátok valószínüleg véglegesíteni a NYÁK-ot. Vagyis csak nagyjából. Első körben azért kicsit parázok, úgyhogy szétbontom táp - jelgen - végfok részekre az egészet. A jelgen részét nagyon érdemes egybe építeni, mert most a zaj nagy része (remélem) attól van benne, hogy 5-10 centis mazzagokon vannak összedrótozva a részegységek. Ha az FPGA, a PIC és a DAC-ok között inkább 1cm közeli lesz a távolság, bízom benne hogy ez javulni fog. A tápot külön fogom tenni, mert a tapasztalatok alapján lehet hogy nem sikerül eltalálnom (sokadjára sem) a NYÁK-ot hozzá, a végfoknál pedig majd a rekonstrukciós szűrőt kell méretezni elsősorban, amit nem tudok megtenni addig, amíg az FPGA nem ketyeg a végleges órajelén (ami olyan 200MHz körül lesz, ha minden jól megy).

 Ha ez megvan, azzal a prototípus el is készült. Aminek még nekifogok ha tényleg lesz időm, az az, hogy áttervezem az egészet 4 rétegű NYÁK-ra, csak mert kíváncsi vagyok mi lesz a különbség. Ezt persze a konyhában nem fogom legyártani, de vagy negyven helyet tudok ahol megcsinálják manapság, nem túl vészes áron.

Címkék: jelgenerator

Szólj hozzá!

DC-DC konverter, második felvonás

Nite 2011.05.01. 14:19

 Csak egy gyors helyzetjelentés: sikerült egy kicsit rendesebben megoldanom a DC-DC konverteremet, mostmár gyakorlatilag olyan kicsi zaj jön ki belőle, hogy az oszcilloszkópommal nem tudom pontosan megmérni (talán 5mV körül)...

 Hogy ezt hogy sikerült elérni? Szerencsére majd kiszúrta a szemem a Linear oldalán az LT3471-hez egy demo board. A mérnökök voltak olyan kedvesek és kapcsolási rajzzal illetve NYÁK-tervvel együtt felrakták a weboldalra, így már könnyen puskázhattam, hogy mit is rontottam el előzőleg. Sajnos nem annyira hobby szinten gondolkoztak, mert a demo panel 4 rétegű, ebből szerencsére 2 teli föld, a harmadik pedig csak két vezetéket tartalmaz a földön kívül, amik az enable jelet viszik. Nálam ez amúgy is VCC-re van kötve, úgyhogy meg tudtam oldani kétrétegű panelon is, hogy az egyik oldala csak föld legyen.

 A kapcsolási rajz semmit nem változott az előző bejegyzéshez képest, de most a +-6V-os részhez adok egy NYÁK tervet is ha valakit érdekelne. Ez a demo panel nagyjából lemásolva, kiirtva a felesleges részek, plusz szűrővel a végén, és összesen két rétegen megvalósítva.

 Egy dolgot tudok még tanácsolni annak aki megpróbálja beüzemelni: az elején viszonylag nagy áramot vesz fel (talán a végleges verzióban megoldom hogy ne egyszerre induljon a két kimenő feszültség). Hogy a készülő áramkör meg ne süljön, én az első próbánál moderált áramkorlátot állítok be a tápegységemen, mivel kb. 200mA-el terheltem, ezért olyan 500mA-t kapott. Hát ezzel nem fog elindulni, eszméletlen csúnya ahogy próbálkozik és rángatja az áramkorlátot. 700mA felett kell beállítani a korlátot, hogy elinduljon. utána a fogyasztása szépen visszaállt 200mA köré, ahogy terveztem.

 A tanulság annyi, hogy valószínűleg tényleg meg lehet hajtani ilyen tápegységgel egy DAC-t. Következő lépésként mostmár tényleg összerakom az egész jelgenerátoromat, és finomítok a hardveren meg a firmwaren.

Címkék: tapegyseg

Szólj hozzá!

Tápegység DC-DC konverterrel USB-ről

Nite 2011.04.04. 12:57

 Pár hét alatt csak eljutottam oda, hogy kipróbáljam, hogyan muzsikálnak a DC-DC konverteres tápegységek. Sikerült róluk pár szépet és jót olvasni, elvileg nem olyan zajosak, hogy nagyon elrontsák a jelgenerátoromat (pár száz uV körüli zajjal hitegettek). Hát, ez megint egy olyan lecke volt, amiből rengeteget tanultam.

 Nézzünk akkor pár kapcsolási rajzot (kicsit össze vannak nyomva, jelenítsd meg őket eredeti méretben). Az első képen egy boost és egy inverter van, ezzel állítom elő az analóg rész számára a +-6V-ot. Ki akartam próbálni, hogy ha utána kötök egy-egy LDO-t, akkor vajon a zaj mennyit csökken, így ezek is szerepelnek a kapcsolási rajzon.

 A második képen az FPGA tápellátása látszik, illetve ebben az IC-ben van egy beépített LDO is, ami most még egy 5V-os tápot ad, ha az ami az USB-ről jön nem lenne elég stabil vagy tiszta.

Néhány szóban hogy mi miért hol:

 A +-7V-ot egy LT3471 állítja elő, nem sokkal drágább mint egy sima inverting DC-DC, de legalább egyből kettő van benne, ami elvileg jól jön ha helyet kell megtakarítani. Mind a két kimenetén van egy ferrit szűrő, meg pár kondi amivel aluláteresztő szűrőt képeznek. Ezzel elvileg elérhető a uV-os zaj. A két LDO semmi különös, +-6V-ra vannak beállítva, adatlap szerint 1MHz-es ripple-t 20dB-el csillapítanak.

 Az FPGA tápját a TI és a Xilinx által kedvelt TPS75003 állítja elő, ebben semmi érdekes nincs, gyakorlatilag egy referencia áramkör.

Összerakva így néz ki:

  Ezzel jól elszórakoztam, még úgy is kb. két óra volt beültetni, ha azt a két órát nem számítom, amíg rájöttem, hogy az IC-ket hogy lehet beforrasztani. Arról ne is beszéljek, hogy a NYÁK-ot is csak második nekifutásra sikerült megcsinálnom, mert elsőre szarul hívtam elő.

 Hogy mit lehet két IC beforrasztáson ennyit tökölni? viszonylag egyszerű, ugyanis a kis cukiknak nincs lába.

Itt látszik, hogy mennyire (nem) lógnak ki a lábak.

Ennyi erővel forraszthatnék BGA-t is. Már az adatlap nézegetése közben is gyanakodtam hogy nem lesz egyszerű dolgom (a neve is QFN - Quad Flat No lead), de még bíztam benne, hogy azért egy picit talán kilóg, vagy legalább az oldalához hozzá lehet férni pákával. Hát nem.

 Ha nem sikerült volna beszereznem az Aoyue forrólevegős állomást, akkor még most is a fejemet vakarhatnám hogy mit csináljak vele.
- Első körben megpróbáltam egy pici forrasztópasztát tenni az érintkezőkre, és ráfújni a levegővel amíg beforrad. Ez a taktika nem jött be, mert egyszerűen kézzel képtelenség annyira egyenletesen alárakni a pasztát, hogy néhol ne emelje fel az IC-t amikor megolvad, és így máshol meg már nem fog érintkezni.
- Ez ugyanúgy előfordul, ha mindenhova csak egy minimális pasztát teszünk.
- Több pasztával kipróbálva gyorsan rá kellett ébrednem, hogy simán rövidrezárja a lábakat.
- A megoldás végül az lett, hogy viszonylag sok pasztát tettem alá, ami megolvadáskor szépen ráhúzza az IC érintkezőit a panel csíkjaira. Amikor kihűlt, lenyomtam az IC-t és felolvasztottam alatta az ónt. Ettől ami az IC alatt volt, teljesen kiült a lábak mellé kis gömbökben. Ott, ahol ez rövidrezárt két lábat, fel kellett takarítani. Ahol a takarítás nem sikerült teljesen, ott megint felolvasztani, hogy a feszültség visszahúzza.

 Ennyi tökölés után a második IC már elég gyorsan bent volt.

 És akkor most pár szóban arról, hogy miért is nem adok NYÁK tervet már megint az áramkörhöz. Azért, mert az én NYÁK-om sz*r lett!!!

 Olvastam persze, hogy mire kell figyelni ha az ember DC-DC táphoz NYÁK-ot tervez. Ugye először is, hogy ahol nagy áramok közlekednek, ott a rézcsík széles legyen. Kettőnek, hogy a nagy áramot vivő földet ne keverjük össze a kis áramokat vivő földdel. Valami blabla rémlik még a földnél minél rövidebb csíkokról, szórt kapacitásról meg induktivitásról, de könnyen lehet erről dumálni ha az embernek 4 rétegű a panelja, majdcsak működni fog valahogy. Persze.

Lényeg a lényeg, a kimenő jelem ilyen lett (az LDO-kon is meg a nyúlon is túl):

Tíz mV egy kocka, azok a 30mV-os tüskék különösen elszomorítottak.

 Csak érdekességképpen, a levegőben a tekercsek körül pár mm-re találtam ezt a szép jelet:

Aki még nem látott volna ilyet, a DC-DC kapcsoló jele így néz ki:

Ezen látszik, hogy honnan jött a zaj. A fel-le kapcsolásokból lesznek a szép kis tüskék, ahogy az a következőn látszik is. Ez még a szűrők előtti kimenet:

Itt még 100mV/Div, a szűrők után:

Ez gyakorlatilag majdnem ugyanaz, ami az LDO-kon kijön.

 És nem segít rajta semmi, se tekercs, se kis kondi, se nagy kondi, semmi. Van egy nagy földem a panel hátulján, és beleköltözött a zaj. Nagyon vicces, azt hinné az ember, hogy egy bazi nagy teliréz vezetőnek ha az egyik vége 0, akkor a másik vége is az lesz, és nem. Kezdhetem elölről.

 Azért mielőtt még nekilátok megint NYÁK-ot tervezni (mostmár talán kicsit jobban odafigyelve, mit mondanak az okosok a földről), kipróbálom, hogy ezzel a táppal hogy fog működni a jelgenerátor. Elvileg a kimeneti erősítőinek a PSRR-je 60dB körüli, ami nem rossz, bár azt tippelem a zajos földdel semmit se fognak tudni kezdeni.

 Vannak még opciók a tápellátásra:
- Maradhat a lineáris regulátoros megoldás. Nagy hibája, hogy +-6V-tól 1.2V-ig sokféle feszültség kell, így az IC-kből sok kell és nagyon fognak melegedni. A szimmetrikus táphoz pedig mindenképpen kell egy teljesítményerősítő, még ha az L165 túlkapás is. Hibrid megoldás lenne, ha az FPGA DC-DC konverterrel menne, az analóg áramkörök meg analóg tápról, de egyik esetben sem úszom meg a külső trafót és a melegedést.
- Az analóg tápot megpróbálhatom kis zajú charge pump-ok segítségével előállítani, de ehhez nem ártana pontosabb méréseket végezni, hogy mekkora áram is kell az analóg résznek, mert ezek maximum 50-100mA körül tudnak.
- A legjobb lenne ha rendbekapnám magam, és megcsinálnám rendesen a DC-DC konvertereknek a NYÁK-ot. Ezek kis helyet foglalnak, az egész áramkör el tud menni USB-ről vagy elemről (akkuról), és amennyivel az alkatrészek drágábbak, annyit spórolok azon hogy nem kell hozzá külső trafó.

 Összefoglalva a tanulságokat:
- QFN tokozást nem lehet pákával forrasztani
- Ha egyszer a föld zajos, azt onnan semmivel se lehet kiirtani
- Épp ezért érdemes marhára figyelni, hogy eleve ne is kerüljön oda zaj

Mivel időközben elkészült a végerősítő modul a jelgenerátorhoz, egyelőre nem tudom mivel fogom folytatni az építést. Ha arra lesz érkezésem, akkor összedugom az egészet végre egy rendszerré, és elkezdem a szoftver-firmware részét kihegyezni, hogy azok a funkciók működjenek amiket tervezek. Ha esetleg hamarabb lesz kedvem NYÁK-ot tervezni, akkor lehet hogy folytatom a kalandozást a tápegységekkel is, és megpróbálom kireszelni belőle a zajt. Az mindenesetre látszik, hogy új áramkört már valószínűleg nem kell terveznem, csak a már meglévőket kell egy nagy panelre ráraknom és kész is a cucc.
 

 Update: Közben a +-6V-os résznek csináltam egy új panelt, eredmények itt.

Címkék: tapegyseg

Szólj hozzá!

USB-s digitális függvénygenerátor mag (2. rész)

Nite 2011.02.21. 11:01

(első rész itt: USB-s digitális függvénygenerátor mag (1. rész)

 A második, egyben egyelőre utolsó részben belinkelem a forráskódokat, pár képet, és kicsit elmélázok arról, hogyan tovább.

 Először is az FPGA pont ugyanazt a kódot használja, amit a DDS-nél annak idején már leírtam, így ahhoz nem adok újabb kódot.

 A PIC kódjai letölthetőek innen: PIC kód
 A PC-n futó dotNet kód pedig itt van: PC kód

 Ha valaki olvasta a programozható órajelgenerátort, annak nem lesz meglepetés ez a két szoftver, mivel az alapok ugyanazok.A PC szoftver júzer interfésze persze elég ronda, éppen csak azért dobtam össze, hogy lehessen tesztelni a működést. A frekvencia beállításakor minden esetben reseteli az FPGA-t egyelőre, a végleges verzióban csak egy "SET FREQ" utasítás lesz, amivel jóval gyorsabban lehet majd változtatni.

 A PIC-en futó kód is nagyjából a szokásos, USB csomagokra reagáló cucc, ami esetleg érdemes lehet egy kopi-pasztára az az MCP4725 I2C vezérlése (de ez se túl bonyolult).

Berakok pár képet arról, hogy milyen jelet sikerült generálni:

  Ezek a kimenő jelek olyan 1Vpp-sek, jól látszik főleg a négyszögjel tetején a zaj aránya. A generált frekvencia olyan 100kHz körüli.

 Van egy kép csak a zajról is nagyítva:

  Az amplitúdója olyan 6mVpp körüli, a nagyobb hullámok között eltelt idő megfelel az FPGA 25MHz-es órajelének kb. Igazából a jelgenerátor végleges verziójában ez egynek figyelmesebb NYÁK-tervezéssel eleve nem lesz ekkora, ráadásul egy aluláteresztő szűrővel különben is le lesznek csapva az ekkora frekvenciák (ld. reconstruction filter). Persze abban az órajel se 25MHz lesz, hanem ami a csövön kifér (remélhetőleg 200MHz).

 Ami ebből az áramkörből még hiányzik, az egy végerősítő. Abban kellene megoldani a kimenő jel szűrését és a szinteltolást. Egyelőre ez még csak papíron van meg nekem, de a következő lépés az lesz, hogy összerakom ezt is és kipróbálom. Ha minden jól megy, egybe lehet rajzolni a kapcsolási rajzot, rendes NYÁK-ot tervezni neki és kész is.

 Néhány gondolat arról, hogy merre van előre:

- Mivel a PIC és az FPGA elég gyorsan tudja állítani a kimenő jel frekvenciáját, viszonylag egyszerűen kivitelezhető egy sweep üzemmód. Érdemes még plusz egy lassú DAC-ot beletenni, hogy a sweepelés közben adja például egy szkópnak a trigger és a vízszintes eltérítés jelet. Mivel az egész teljesen szoftveresen megvalósítható, a sweep lehet lineáris vagy logaritmikus, sőt ha olyan kedvünk van, egyes részeit ki is nagyíthatjuk a képernyőn.

- A PIC-en van egy elég lassú A/D átalakító is, amivel azért hangfrekvenciás jeleket lehet éppen mintavételezni. Csak a kísérletezés kedvéért ezzel simán megoldható a kimenő jel amplitúdó, fázis, vagy frekvenciamodulálása.

- Jelenleg a teljes felhasználói interfészt a PC adja, de be kell lássuk, hogy egy kicsi pontmátrix kijelzővel, pár enkóderrel és mikrokapcsolóval a felület nagy része visszavihető a generátorhoz. Ezeknek a vezérléséhez pedig adott a PIC, ami úgyis ideje nagy részében unatkozik.

- A tápegység jelenleg ronda és meleg, egyelőre ötlet szinten felmerült bennem hogy kapcsolóüzemű tápokkal helyettesítsem, és olvastam pár cikket ami szerint talán az analóg rész számára sem lesz így nagyon zajos. Elég pöpec lenne, mert ebben az esetben könnyen elmehetne szimplán az USB-n kapott tápról, nem kellene neki külön tápegység, sőt akár elemről vagy akksiról is mehetne (bár ehhez szerintem túl sokat fogyaszt...) Valószínűleg kigyúrom magam a témában és építek pár tesztáramkört.

- Úgy tűnik, a 200MSPS egyelőre az otthoni hobby körülmények között elérhető maximum, de persze ez csak az FPGA-n és a DAC-on múlik, a technika fejlődik, nincs kizárva hogy feljebb lehet ezt még tornázni. Most még az 1-2GHz-s álomgenerátorok elkészítésének legnagyobb korlátja, hogy BGA tokozású FPGA kell hozzá, és kettőnél több rétegű NYÁK, ami nem kivitelezhető átlagembereknek.

- Egyébként a szemfülesek már észrevették, hogy van egy felesleges alkatrész a kapcsolási rajzokon, mégpedig a PIC. Ugyanis az erősebb (és mégsem BGA) FPGA-kon marha egyszerűen implementálható egy soft processor, ami simán át tudja venni a PIC szerepét. Ez azért is lehet jó poén, mert akkor végülis az 5V-os tápot teljesen ki lehet hagyni, kevesebb alkatrész, kevesebb fogyasztás, mindenki örül.

- Gondolom az sem újdonság, hogy a digitális oszcilloszkóp gyakorlatilag egy nagyon hasonló áramkör, csak visszafelé. Bízom benne, hogy előbb-utóbb el tudok kezdeni azzal is foglalkozni.

Ennyit mára a tudomány és technika újdonságaiból, ahogy azt látjátok az elkövetkező pár évben nem fogok unatkozni, annyi mindenen töröm a fejem.

 

Címkék: jelgenerator

Szólj hozzá!

USB-s digitális függvénygenerátor mag (1. rész)

Nite 2011.02.16. 10:16

 Ahogy ígértem, folytatódik a DDS függvénygenerátor saga, ebben a bejegyzésben a kapcsolási rajzokkal. Előre bocsánatot kérek hogy nem lettek a legszebbek, magamnak csak összedobáltam a NYÁK-tervezéshez és nem volt időm rendesen megrajzolni őket, de azért remélem ki lehet rajtuk igazodni. Egyelőre még mindig ott tart a dolog, hogy NYÁK tervet nem áll módomban betenni, mert nekem is ezek az áramkörök csak különböző kísérleti paneleken vannak készen. Az sem véletlen, hogy egyelőre csak egy "mag" amit leírok, mert elég sok hasznos funkcionalitás hiányzik belőle. A következő lépés lesz a hiányzó funkciók beépítése és tesztelése, azután ha minden jól működik, akkor összerakom egybe az egész áramkört, és lehet neki rendes NYÁK-ot tervezni.

 Kezdjük akkor először is a tápegységgel.

 

  Ahogy az látszik, irgalmatlanul sok féle táp kell ennek a szerencsétlen áramkörnek. Az FPGA-hoz 1.2V és 3.3V, a PIC-nek és a többi digitális kütyünek 5V, és a kimeneti erősítőknek +-6V. Kicsit egyszerűsödne a helyzet, ha elhagynánk az 5V-os vonalat, és a PIC-et meg a DACokat is 3.3V-ról hajtanánk. A megoldás hátránya az, hogy ebben az esetben egyik sem tudna teljes sebességén üzemelni, a DAC például csak 165 MSPS-t tudna 200 helyett. A kimenő jel esetében cél volt, hogy legalább a TTL jelszintet tudja, ehhez meg nem elég az 5V-os táp, csak ha a végerősító rail-to-rail lenne, de azok viszont vagy nem elég gyorsak vagy túl drágák, úgyhogy ezért kell a +-6V. Ha nem Xilinx cucc lenne az FPGA, lehet hogy találnék olyat, aminek nem kell az 1.2V sem (de most ehhez vannak fejlesztő eszközeim).

 Az összes áramkör amit ez a táp hajt, nem eszik többet 600mA-nél, és mégis az L165 úgy melegszik hogy a végleges verzióban mindenképpen hűtőborda kell rá. Persze a legjobb megoldás az lenne, ha találnék egy megfelelő táp manager IC-t, de azok közül ami eleget tudna az elég drága, úgyhogy majd meglátjuk.

  A PIC és környéke nem tartalmaz semmi meglepetést. Van rajta néhány láb, amit még ebben az áramkörben nem kötöttem be (AnalogIn, x10, x1), csak tervezek. Így viszont a LED-ek osztoznak a programozó lábakon, ezt egy jumperrel oldottam meg egyelőre. Vigyázat, innen hiányzik, de az FPGA felé menő lábakra kell sorosan egy-egy 300 Ohm körüli ellenállás, mert az FPGA nem eszik 5V-ot.

 Az FPGA és környéke ismerős lesz a Spartan próbapanelből:

  A táp és az órajel generátor,

 A kimenetek és a bemenetek,

 Ez meg a JTAG csatlakozó és környéke, meg Vref-ek.

 Ahogy említettem az előző bejegyzésben, a gyors DAC-nak egy lassabb adja a referenciát, hogy így lehessen változtatni a kimenő jel amplitudóját.

 Bocs, itt a tápcsatlakozókat máshogy jelöltem, mert igazából egy másik lapról vágtam ki de ne menjünk bele. A lényeg, hogy ez az MCP4725 a Microchipnek egy olcsó I2C-s D/A konvertere, a föld és a tápfeszültség között ad kimenő jelet. Ez egyelőre simán rá van kötve a DAC908 RefIn bemenetére, de a végleges kapcsolási rajzban majd meg kell oldani egy feszültségosztóval a rendes szinteket (ld. DAC908 adatlap).

 A lényeg pedig a DAC908 és környéke:

 (Az OPA690 bemenetei azért vannak keresztbe, mert mint említettem eredetileg szarul rajzoltam meg aztán így volt időm javítani :)

 A DAC908 digitális része 3.3V-on ketyeg, így egy az egyben viszi az FPGA kimenete. Az analóg része 5V-os, hogy a 200MSPS meglegyen (nem próbáltam, de remélem ezen múlik). Az OPA690-re pont úgy van kötve, ahogy azt az adatlapon írják, nincs benne nagy trükk. Ezzel a kapcsolással a kimeneten olyan 3Vpp-s jel tud kijönni maximum.

 Berakok még egy képet a dzsumbujról, ahogy ez az egész az asztalomon kinéz:

Van pár mazzag, nem csoda hogy még picit zajos szegény.

 A szoftverek a következő bejegyzésre maradnak, igyekszem őket jövő hétre gatyába rázni. Várható még pár kép a kimenő jelről, és pár gondolat arról, hogy hogyan és merre tovább.

Címkék: jelgenerator

Szólj hozzá!

Átállás SMD-re

Nite 2011.02.07. 13:23

 Ismét hosszabb szünet után írok csak, aminek leginkább technikai (és persze ugyanakkor pénzügyi) okai vannak megint. Történt ugyanis, hogy az FPGA próbapanel megépítése és a DDS kód beletöltése után kipróbáltam, hogy mennyire is generál emészthető jelet ez a DDS.

 Rákötöttem hát az FPGA panelt a szokásos USB-s PIC-emre (aki egy 18F4550), a kimeneteit pedig egy D/A átalakítóra (THS5641A, 8bit 100MSPS), és megnéztem hogy mi jön ki belőle. Sajnos nem sok jó, például ezek:

  - Az FPGA órajele ugye eredetileg nálam 25 MHz volt, gondoltam hogy úgyis 100MSPS-t tud a DAC, akkor nem lesz baj ha legalább 2x-es szorzót állítok be az FPGA belső órajelére. Igen ám, de az 50 MHz-es 3.3V-os órajel nagy része a 15 centis szalagkábelen, amivel vissza volt kötve a próbapanelre, egyszerűen eltünt... Vissza kellett hát vegyem 25MHz-re, hogy valami értelmes jelalakot lássak. Persze erre számítottam többé-kevésbé, mindig mondom hogy az ember próbapanelen ne mérjen sávszélességet :)
  - Ami nagyon ronda volt, az a DAC kimenetén kieső jel. Ugyan fel lehetett ismerni, hogy az FPGA most éppen szinuszt küldene, de hatalmas zaj volt rajta körülbelül az FPGA órajelének harmónikusaival, gondolom nem tett jót az egésznek, hogy össze kellett földelni a próbapanelt ezzel a zajos digitális jószággal. A DAC-on ugyan külön van táp és föld a digitális és az analóg résznek, de próbapanelon semmit sem érek vele.
  - És még egy dolog: A DAC kimenetén a nagyobb váltásoknál (pl. 0x7F-0x80) akkora jitter volt, mint egy ház. Ez nagyrészt szerintem azért sikerült így, mert az SMD IC-t megint kb. 2 centis drótdarabokkal forrasztottam be egy foglalatba, és így tettem be a próbapanelba. Szerencsétlennek a legközelebbi szűrőkondik így vagy 3 centire voltak, nyilván nem tudott egészséges jelet kiadni magából.

 Ezek ellenére a kísérletet sikeresnek könyveltem el, több tapasztalatot is leszűrve belőle. A működési elv jó, mert a DDS kimenetén a frekvencia és a jelalak felismerhető volt. És kiderült, hogy ha tovább akarok lépni, le kell jönnöm a dugaszolós panelról.

 Oké, a PIC az maradhat rajta, úgyis teljesen digitális, eddig is elvolt ott. Az FPGA-nak már van saját panelja, akkor építsünk össze egyet a DAC-nak is, lehetőleg egy előerősítővel együtt a kimenetére, hogy az onnan kieső jelet már tovább tudjam vinni egy később megépített végerősítő panelra. A DAC-nak még egy dolog kell, mégpedig a referencia, amit eleve egy másik, olcsó, lassú DAC-al akartam neki előállítani, hogy a kiemnő jel amplitudója változtatható legyen. A lassú DAC-kat egy külön panelra rakom, hogy a PIC-re rá tudjam kötni külön is őket. Ja és igen, a DAC-nak kell 3.3V, 5V, az erősítőnek jó lenne +-6V, úgyhogy csinálnom kell egy külön tápot is amire ezeket rádugdoshatom.

 És lőn: három NYÁK, ebből a tápegység leginkább klasszikus "lábas" (through-hole) alkatrészekkel, a többi viszont a csatlakozókat leszámítva teljesen SMD. Ezzel aztán egy egészen új gondot sikerült magamra szabadítanom. A NYÁK-ok még elég jól sikerültek, lassan kezd rutinom lenni a 0.2-0.3 vezetőszélességű kétoldalas panelok készítésében, de a beültetés nem volt egy diadalmenet.
- Először is kiderült, hogy az SMD alkatrészeket beszerelni majdnem 2x gyorsabb, mint a hagyományosakat, főleg mert nem kell a panelt forgatni, a lábakat méretre vágni stb. Csak bekentem egyszerre 4-5 alkatrész lábainak helyét forrasztópasztával (ilyen kis fecskendőből kinyomhatóm van most), felpakolom őket, aztán egy pillanat alatt beforradnak ha hozzájuk ér a páka.
- Sajnos elsőre jó ötletnek tűnt az SMD alkatrészek alatt vezető csíkot húzni, hogy ne legyen annyi VIA a panelon, később aztán ez fatálisnak bizonyult: mivel otthoni körülmények között majdnem képtelenség hőálló szigetelő lakkot felvinni ezekre (a lábak kimaszkolásával), ezért aztán tuti hogy sikerül összeforrasztani egy lábat egy ilyen csíkkal. Igen, az IC alatt. Igen, ez csak akkor derül ki amikor már mind a hat lába be van forrasztva.

 Mi a túrót lehet ilyenkor csinálni? Teljesen esélytelen pákával kiforrasztani egy ilyen gombostűfejnyi baszt, aminek pont elég lába van ahhoz, hogy mire az utolsó kiolvadna, az első már visszahül... És ha ki is veszem, simán lehet hogy másodjára se sikerül rendesen beforrasztani. Ami hirtelen eszembe jutott az egynek a hőlégfúvó. és már láttam is magam előtt, ahogy a légnyomástól szanaszét repül az összes eddig beforrasztott alkatrész, és a hőtől ropogósra sül a NYÁK is. Lehetne még gázos páka hőlégfúvó üzemmódban, ezzel már hallottam hogy emberek sikeresen szereltek SMD alkatrészeket.

 A legtutibb mindenképpen egy forrólevegős forrasztóállomás lenne, főleg ha a későbbiekben többet akarok SMD-vel foglalkozni, de ezek horror árakon vannak nem? Hát, lehet használtan venni e-bay-ről, ha az embernek szerencséje van, vagy vesz egy kínait, pl. az Aoyue-től, ami ugyan nem a legjobb minőségű, de elég jól működik. Összekuporgattam a kis zsetonjaimat, és végülis az utóbbi megoldás mellett döntöttem, főleg hogy némi internetbúvárkodás után kiderült, hogy az Aoyue nem is gyárt akkora szarokat.

 Ennél jobb beruházásom elég régen nem volt, ugyanis ezzel már körülbelül 5 másodperc múlva kint volt a kis IC, feltakarítottam alatta, és mehetett is vissza. A forrólevegő másik nagy előnye, hogy a forrasztópasztát egy nagyobb környéken felolvasztja, ami így a felületi feszültségtől rácuppan a rézfelületekre és nehezebben zár össze olyasmit amit nem kellene neki. Azt is volt szerencsém megtapasztalni párszor, amikor egy ferdén felrakott alkatrészt kis melegítés után az ón a helyére igazít... Ezerszer jobb egy ilyen cuccal dolgozni SMD alkatrészeken, mint pákával ökörködni. Annyi kis trükkre kellett még rájönnöm, hogy az alkatrészek egyik lábát érdemesebb pákával beforrasztani, mielőtt a forrólevegővel rámegyek. Ez azért van, mert marhára remeg a bal kezem és nem tudom mindig egy helyben fogni az alkatrészt amíg a forrólevegő megolvasztja a pasztát, ha meg egyáltalán nem fogom, könnyen alákap a levegő és elfordítja.

 Azért nem is én csináltam volna ha nem rontok el egy csomó mindent még gyakorlatilag a kapcsolási rajz és a NYÁK tervezés szintjén.
- Ugye van vagy öt IC a tápegységben, a különböző feszültségek előállításához - stabilizálásához. Na ezeknek a lábkiosztását nem néztem át elég alaposan amikor a modelleket készítettem hozzájuk, a fene gondolta volna hogy ugyanannak a kínai gyártónak az 1.2V-os és a 3.3V-os stabilizátorának tök más a kiosztása.
- Ráadásul sikerült egy rossz kapcsolási rajzról dolgoznom az L165 környékén, így nem működött elsőre (pedig csak az adatlapból kellett volna kimásolni a jót).
- A D/A előerősítőjének meg fordítva kötöttem a + és a - lábát, ezt miután észrevettem, a rezet lekapartam a panelról és sima drótokat forrasztottam a helyére.
- pár tantál kondit sikerült fejjel lefele beszerelnem, ugyanis a kapcsolási rajzon rossz modellt választva a beültetési rajzon nem látszott, melyik a pozitív vége, és már csak akkor vettem észre amikor marhára melegedtek szegények.

 Ezeket a kisebb bénázásokat leszámítva a panelok elkészültek, és össze is kötöttem mindent mindennel, hogy végre kiderüljön, milyen ronda jel jön ki belőle. Legnagyobb megdöbbenésemre gyönyörű jelalakok fogadtak, éppen csak egy pici nagyfrekvenciás zajjal, de erről majd a következő bejegyzésben írok részletesen.
 

Címkék: smd

Szólj hozzá!

VHDL gyorstalpaló 2: DDS

Nite 2010.08.02. 12:17

 Még mindig a DDS-ről írok, mivel szabadidőmben mostanában ez foglalkoztat. Ha valaki végigböngészi a Xilinx IP-ket, gyorsan talál egy DDS-t közöttük, mégis inkább úgy voltam vele, hogy megírom a sajátomat. Ennek oka leginkább a Xilinx DDS hiányosságaiban keresendő: például szerettem volna tetszőleges hullámformát generálni, illetve a dither-t ki-be kapcsolni, ahogy azt a generált jelalak megkívánja (ez még a kódban nem szerepel). Eredetileg kicsit több melóra számítottam vele, de mint kiderült, annyira egyszerű, hogy az egész kódot beírhatom ide. Minden részét nem fogom mégsem bemásolni, a generált fájlokat amúgy is jobb, ha mindenki legenerálja magának.

 A DDS projekt a következő elemekből épül fel:

 - Clock: A Xilinx Clock IP-je építette fel az órajel előállításához szükséges paramétereket. Nekem a panelomon 25MHz-es órajel van, a DA átalakítóm 50MHz-et bír, így egy kétszeres szorzót tettem bele mindössze.
 - Ram: Ez is egy IP, mégpedig egy 2048 byte-os memória, amiben a jelalakot tároljuk.
 - Random: A dither előállításához szükséges pszeudo-random generátor. Sajnos a Xilinx IP-i közül kivették, ezért meg kellett írni.
 - DDSMain: A DDS implementációja.
 - testbench: A teszteléshez szükséges jeleket előállító kód.

 A forráskódokat innen lehet letölteni.

 Nézzük akkor meg a kódokat, először is a véletlen szám generátort:
 
entity random is
port (
      clk : in std_logic;
      random_num : out std_logic_vector (31 downto 0)   --output vector           
    );
end random;
 Nincs túlbonyolítva, az órajel minden ciklusára egy 32 bájtos véletlen számot állít elő.

architecture Behavioral of random is
begin

    process(clk)
        variable rand_temp : std_logic_vector(31 downto 0) := "10111010111110001011101011111000";
        variable temp : std_logic := '0';
    begin
   
        if(rising_edge(clk)) then
            temp := rand_temp(31) xor rand_temp(21);
            temp := temp xor rand_temp(1);
            temp := temp xor rand_temp(0);
            rand_temp(31 downto 1) := rand_temp(30 downto 0);
            rand_temp(0) := temp;
        end if;
        random_num <= rand_temp;
   
    end process;
   
end Behavioral;
 Mint az látszik, ez egy egyszerű LFSR, a régi Xilinx IP dokumentációja itt található. Ebben van egy táblázat, amiből kideríthető, hogy 32 bites hossznál melyik biteket célszerű XOR-olni, hogy a vélelen szám generálás a legkésőbb kezdjen ismétlődni.

 A DDS kódja:

entity ddsmain is
    Port ( ClkIn : in  STD_LOGIC;
           Rst : in  STD_LOGIC;
           ClkOut : out  STD_LOGIC;
           DataOut : out  STD_LOGIC_VECTOR (7 downto 0);
           DataIn : in  STD_LOGIC_VECTOR (7 downto 0);
           Addr : in  STD_LOGIC_VECTOR (3 downto 0);
           ManClk : in  STD_LOGIC;
              WriteClk : in  STD_LOGIC;
           ClkSel : in  STD_LOGIC);
end ddsmain; 
 Fussunk végig a bemeneteken és kimeneteken:

- ClkIn: A bemenő órajel, mint említettem 25 MHz
- ManClk: Bemenő órajel, ha nem a 25MHz-es jelet akarjuk használni
- ClkSel: Ezzel választhatunk a ClkIn vagy a ManClk közül
- Rst: Reset
- ClkOut: Kimenő órajel a DA átalakítóhoz
- DataOut: Kimenő adat a DA átalakítóhoz
- DataIn: Bemenő adat a DDS programozásához
- Addr: A programozandó regiszter címe
- WriteClk: A programozáshoz szükséges órajel

 A DDS paramétereinek beállítása ahhoz hasonlóan történik, mintha regiszterekbe írnánk az értékeket. Az Addr bemeneten kiválasztjuk a regisztert, a DataIn-be beírjuk az adatot, és a WriteClk ciklusával az adat beíródik.

process (WriteClk, Addr, DataIn)
    begin
   
        if rising_edge(WriteClk) then
            case Addr is
                when "0000" =>    freqbuf(7 downto 0) <= DataIn;
                when "0001" =>    freqbuf(15 downto 8) <= DataIn;
                when "0010" =>    freqbuf(23 downto 16) <= DataIn;
                when "0011" =>    freqbuf(29 downto 24) <= DataIn(5 downto 0); freqreg <= freqbuf;
                when "0100" =>    phasebuf(7 downto 0) <= DataIn;
                when "0101" =>    phasebuf(9 downto 8) <= DataIn(1 downto 0); phasereg <= phasebuf;
                when "0110" =>    ramaddrbuf(7 downto 0) <= DataIn;
                when "0111" =>    ramaddrbuf(10 downto 8) <= DataIn(2 downto 0); ramaddrreg <= ramaddrbuf;
                when "1000" =>    ramdatain <= DataIn;
                when "1001" =>    ramrst <= DataIn(0);
                when "1010" =>    ramwrite(0) <= DataIn(0);
                when others => NULL;
            end case;
        end if;
    end process;
  A következő címek vannak definiálva:

 - 0000 - 0011: A generálandó frekvencia, 4 bájton ábrázolva. Mivel a DDS fázisakkumulátora 32 bájtos, a frekvencia legfelső két bitjét nem használjuk (nem kapnánk értelmes jelalakot).
 - 0100 - 0101: 10 bites fázis regiszter
 - 0110 - 0111: 11 bites cím regiszter a RAM írásához
 - 1000: A RAM-ba írandó adat
 - 1001: A RAM törlése
 - 1010: csak a legalsó bitje használt, ha 1, akkor a RAM-ot írjuk, ha 0, akkor olvassuk.

 Kicsit előreszaladtunk, ha a kód elejét nézzük, az első lépés a külső modulok példányosítása:

        Inst_Clock: Clock PORT MAP(
        CLKIN_IN => ClkIn,
        CLKIN_IBUFG_OUT => bufo,
        CLK0_OUT => clk0,
        CLK2X_OUT => clk2
    );

    Inst_Ram: ram port map (
            clka => intclk,
            rsta => ramrst,
            wea => ramwrite,
            addra => ramaddr,
            dina => ramdatain,
            douta => DataOut
    );

    Inst_Rnd: random PORT MAP (
          clk => clk2,
          random_num => random_num
        );

 Ezzel gyakorlatilag bekötjük belső jelekre a moduljaink lábait.
 A következő részben az órajel előállításához szükséges műveletek jönnek:

     IBUFG_inst_ManClk : IBUFG
    generic map ( IBUF_DELAY_VALUE => "0", -- Specify the amount of added input delay for buffer, "0"-"16"
                        IOSTANDARD => "DEFAULT")
    port map (
        O => manclkbuf, -- Clock buffer output
        I => ManClk -- Clock buffer input (connect directly to top-level port)
    );         
   
    BUFGMUX_inst : BUFGMUX
    port map (
        O => intclk, -- Clock MUX output
        I0 => clk2, -- Clock0 input
        I1 => manclkbuf, -- Clock1 input
        S => ClkSel -- Clock select input
    );   
   
    ClkOut <= intclk;
 Létrehozunk egy Clock Buffert a ManClk számára is, mert az IP Wizard csak a ClkIn-nek csinálta meg. A Spartan3 kézikőnyvében van leírva, hogy mit miért és hogy kell csinálni.

 Egy BUFGMUX példány dönti el, hogy a ManClk vagy a ClkIn(x2) bemenetet használjuk órajelnek.

 Ezután már csak az a rész van hátra, ahol a DDS jelgenerálás végbemegy:

      process (intclk, Rst, ramwrite, freqreg, phasereg, random_num, phasedither, phasecrop, ramaddrreg)
    begin

        if rising_edge(intclk) then
            if (Rst = '1') then           
                phaseacc <= "00000000000000000000000000000000";
                phaseout <= "00000000000000000000000000000000";
            else
                if (ramwrite(0) = '0') then
                    phaseacc <= phaseacc + freqreg;
                    phaseout <= phaseacc + (phasereg * "1000000000000000000000");
                    phasedither <= phaseout + random_num(20 downto 0);
                    phasecrop <= phasedither(31 downto 21);
                    ramaddr <= phasecrop;
                else
                    ramaddr <= ramaddrreg;
                end if;
            end if;
        end if;
   
    end process;
  Az első rész a resetet végzi el, utána jön tulajdonképpen a jelgenerálás. Ez nem tér el a DDS-nél már leírt algoritmustól. A fázis akkumulátorhoz hozzáadjuk a frekvencia regisztert minden órajelciklusban, ehhez jön a fázis regiszter, a véletlen szám a ditherhez, végül az egészet akkorára vágjuk, hogy a RAM-ot meg lehessen vele címezni.

 A RAM kimenete van a DataOut-ra kötve, így a megcímzett memória tartalma kerül a kimenetre.

 Gyakorlatilag a DDS ennyiből áll. Érdemes még egy picit a teszteléshez használt kódon is átfutni, ugyanis ebben megnézhetjük, hogyan kell feltölteni a RAM-ot egy szinusz hullámmal:

    signal s: real;
    signal s2: real;
    signal si: real;
    signal intaddr: std_logic_vector(10 downto 0);
   
    ...
   
         -- Fill up RAM with sine
        DataIn <= "11111111";
        Addr <= "1010";
        wait for WriteClk_period;

        si <= 0.0;
        for i in 0 to 2048 loop
            intaddr <= conv_std_logic_vector(i,11);
            DataIn <= intaddr(7 downto 0);
            Addr <= "0110";
            wait for WriteClk_period;
            DataIn(2 downto 0) <= intaddr(10 downto 8);
            DataIn(7 downto 3) <= "00000";
            Addr <= "0111";
            wait for WriteClk_period;
           
            s <= sin((Math_pi / 1024.0) * si);
            s2 <= s * 127.5;
            si <= si + 1.0;
           
            DataIn <= conv_std_logic_vector(INTEGER(s2)+127, 8);
            Addr <= "1000";
           
            wait for WriteClk_period;
        end loop;

        DataIn <= "00000000";
        Addr <= "1010";
        wait for WriteClk_period;
        -- Fill End
  A szinusz hullám feltöltésének menete a következő:

 - Írásra állítjuk a RAM-ot
 - Egy ciklussal végigmegyünk a címeken, a "conv_std_logic_vector" segítségével alakíthatjuk a ciklusváltozónkat címmé
 - A címet beírjuk a DDS regiszterébe
 - A szinuszt a VHDL beépített függvényeivel kiszámoljuk. Ez a rész csak a teszt közben tud futni, az FPGA-ba nem programozható :)
 - Az "INTEGER" függvény alakítja egész számmá a "real"-t amiben a szinusz tárolva van, ezt szokás szerint a "conv_std_logic_vector" alakítja nyolc bites számmá, ami a RAM-ba írandó adat.
 - Az adatot beírjuk a RAM-ba
 - Ha az összes címre beírtuk az adatot, az írás módot kikapcsoljuk.

 Gyakorlatilag ennyi az egész. Ha a tesztet lefuttatjuk, nyomon követhetjük, ahogy a szinusz hullámot a DDS létrehozza. Ha a frekvenciát elég alacsonyra vesszük, azt is megnézhetjük, hogyan működik a dither.
 Jó szórakozást!        
 
 
 

Címkék: vhdl

Szólj hozzá!

Spartan-3AN FPGA próbapanel

Nite 2010.07.01. 15:22

 Nos, akkor lássuk szenvedéseim eredményét, a próbapanelt. Először is szeretném megemlíteni, hogy miért nem rakom be ide a NYÁK-tervet: nem szeretném ha azt bárki is megépítené. Ahogy az előző bejegyzésben írtam, sokat tanultam belőle, és másodjára teljesen másként csinálnám. Hogy akkor mégis mire jó ez az egész? A kapcsolási rajzok működnek, és kiindulási alapnak teljesen megfelelőek. Ha valaki arra kíváncsi, hogy mik azok a lábak, amiket egy FPGA-n minimum be kell kötni ahhoz, hogy működjön, akkor ebből a kapcsolásból nyugodtan ki tud indulni. Azokon a helyeken, ahol valamit ma már másképp csinálnék, majd írok pár sort.
 
 
 Nézzük akkor először is a tápegységet.
 
 
 
 
 Azt hiszem, ennél primitívebb tápegység kapcsolási rajzot nehezen lehetne találni. A 12V~ feszültséget egy kis tápegység adja, ennek a felét csapja le a D1. Ebből majd egy következő verzióban +-10 voltos szimmetrikus táp lesz, aztán meg még később kitalálom hogy hogyan legyen szimmetrikus anélkül hogy a trafót kinyírná :)
 A két stabilizátor IC-ben a nélkülözhetetlen kondikkal nincs semmi meglepő, arra voltam kíváncsi, hogy kell-e bonyolultabb cucc az 1.2V-os táphoz, vagy jó az LM317, ami lehet hogy 1.25V-ot ad... Egyelőre úgy tűnik, ennyit még az FPGA eltűr (adatlap szerint is).
 Van még a rajzon egy kristály oszcillátor, én speciel egy 25MHz-eset tettem bele, az FPGA-ban van PLL, úgyhogy az gyakorlatilag bármilyen frekvencián működhet.
  
 
 Egy fokkal érdekesebb az FPGA tápellátása:
 
 
 
 Az odáig egyszerű, hogy minden föld láb földre van kötve, a VCCINT lábak 1.2V-ra, a VCCAUX és a VCCO lábak 3.3 voltra (ezek nyilván azért, mert LVTTL illetve LVCMOS 3.3V-nál kisebbet nem tervezek használni). A csel a hidegítő kondenzátorokban van, ezek méretezéséről a Xilinx ad egy viszonylag jó leírást. Gyengébb angolosok kedvéért pár ökölszabály röviden: 
 - A kondenzátorok pontos értéke nem számít, hanem inkább az a lényeg, hogy 0.01uF - 4.7uF tartományban minden nagyságrendből legyen elég kondi.
 - Nagyságrendileg annyi kondi kell, ahány táp lába van az FPGA-nak.
 - 0.01uF-os kondiból kell a legtöbb, 0.1uF-ból kb. feleannyi, 1uF-ból negyedannyi, és egy-két darab nagyobb, 470uF körüli. A kicsik legyenek kerámia kondenzátorok, a nagyok lehetőleg tantál vagy elektrolit.
 - A legkisebb kondik csak akkor hatásosak, ha nagyon közel vannak az FPGA-hoz (lehetőleg 2cm-en belül, esetleg közvetlenül alatta). A többi lehet fokozatosan messzebb.
 
 
 Már csak az FPGA néhány fontos lába maradt ki:
 
 
 
 - A JTAG interfész a programozáshoz. Vezessünk ki földet is, és egy 3.3V-os referenciát.
 - Az órajelet ne kösse senki a CLK0-ra mint ahogy én csináltam, mert ott az XC3S50AN-en nincs DCM... a Bank0-ról érdemes egy CLK lábat választani neki.
 - A három Mode pin mondja meg, hogy honnan akarjuk konfigurálni az FPGA-t. Ha a belső flash memóriájából, akkor ez "110" , ha máshonnan, akkor meg ez a dokumentum segít megtalálni, mire állítsuk.
 - A DONE pin "1"-re áll, ha a konfiguráció kész, ezzel hajthatunk egy LED-et is. Ha a belső memóriát használjuk, és JTAG-gal programozzuk, akkor a PROG_B-t nem kell piszkáljuk, én azért egy jumpert raktam rá.
 
 Az összes többi lábat oda kötjük, ahova akarjuk, ezek az user io-k, én speciel csatlakozókra vezettem ki őket, amiken keresztül össze lehet kötni pl. dugaszolós próbapanellal.
 Az biztos, hogy nem ez a legbonyolultabb FPGA fejlesztőpanel amit az életben láttam, de az is valószínű, hogy nem kerül annyiba összerakni, mint egy gyári. A csatlakozókon keresztül pedig olyan perifériákat dughatunk rá, amilyet nem szégyellünk. Sajnos az FPGA bonyolult tápellátása miatt nem ússzuk meg a két oldalas NYÁK-ot, de ha nem tervezel 100MHz-nél sokkal magasabb frekvenciákkal dolgozni, akkor meg lehet úszni SMD kondik nélkül. Ebben az esetben az egyetlen SMD alkatrész, amit be kell bűvölni a helyére, az FPGA lesz, és a kondik lábain váltva a panel rétegeit a viák száma is alacsonyan tartható. Jó szórakozást :)

Címkék: fpga

Szólj hozzá!

Barátunk az FPGA (nem)

Nite 2010.06.18. 10:42

 Először is elnézést kell kérnem, hogy hónapokig nem frissült a blog... persze mint azt írtam, erre számítani kell, nem tudok naponta új témákat feltenni.
 
 Ott hagytam abba legutóbb, hogy rendelem az alkatrészeket egy DDS jelgenerátor megépítéséhez. Itt leginkább néhány Xilinx Spartan-3AN FPGA az ami a költségek nagy részét kitette, ezen felül pár kondit, csatlakozót meg kvarc oszcillátort rendeltem csak. PIC-em, D/A-m van, úgy döntöttem megpróbálom azokkal megoldani. Az FPGA-k típusa XC3S50AN, kiválasztásakor fontos volt, hogy hobby eszközökkel lehessen neki NYÁKot készíteni és be lehessen forrasztani, ezért a tokozása TQG144 (határeset). Nem akartam külön konfigurációs memóriával bajlódni, és ebben a kategóriában a kód is jobban védhető, ha az FPGA-ban van tárolva, ezért az AN család.
A rendelkezésre álló doksik alapján (user guide, és egy gyári demo board) terveztem egy próbapanelt neki, erről majd még részletesen írni fogok. Hogy valami értelme is legyen a bejegyzésnek, összeszedem a tanulságokat amikkel gazdagodtam az elmúlt hónapokban:
 
 - 0.2mm vezető és szigetelés szélességű, 2 oldalas NYÁK készítése feszegeti az otthon rendelkezésre álló eszközök határait. Gyárilag felvitt fotó rétegű lemezre dolgoztam, írásvetítő fóliára nyomtatott áramkört fotóztam rá, annyit tudok mondani, hogy aki hozzám hasonlóan kevés gyakorlattal rendelkezik a témában, ne is álmodjon róla hogy elsőre jól fog sikerülni.
 - Amikor már nem találsz több rövidzárat az elkészült NYÁKon, már valószínüleg csak egy van rajta. De nyugi, az alkatrészek beforrasztása közben keletkezni fog még kettő (és akkor még az elbújt szakadást meg se találtad).
 - Az 1.2V-os táp nem fog LED-et hajtani (Amatőr! - kiált a tömeg).
 - Jó ötlet a két oldalas panelon a viák minimalizálása érdekében az alkatrészek lábain átvinni a jelet az egyik oldalról a másikra. Ugyanakkor ha az alkatrész tokja eltakarja a lábát (oszcillátor, kondik), jó kis szórakozás a beültetési oldalon beforrasztani. Kis szerencsével erre csak akkor jössz rá, amikor a másik oldalon már beforrasztottad.
 - Az FPGA beforrasztása közben mindegy mennyire vigyázol, a pákával néhány lábat össze fogsz zárni. Ezeket a kis hidakat az ónszívó rézsodrony könnyen felszívja, ha elegendő a páka teljesítménye, hogy a környéket felmelegítse. 
 - Az FPGA lába jobban tapad a NYÁKhoz is és az ónszívó huzalhoz is, mint az FPGA-hoz. (Ha sikerül letépni, unalmas estékre jó elfoglaltságot biztosít egyetlen rézszál hozzáforrasztása a csonkhoz. Ja, még nem is mondtam, ha egy láb leszakad, az biztos hogy táp lesz vagy JTAG, ami nélkül az egészet dobhatod ki).
 - A pár száz forintos alkatrészekből összetákolt párhuzamos portos JTAG kábelnek esélye sincs, hogy a 3.3Voltos FPGA-t felprogramozza. Erre rájött a gyártó is, így a gyári JTAG kábel több, mint 70000 Ft, a legolcsóbb csak kicsivel van 30000 felett. Miközben próbáltam elkerülni az ekkora beruházást, sikerült előrehaladnom egy PIC-es USB-s programozóval, de végül hamarabb vettem gyári kábelt minthogy ezt befejezzem. A későbbiekben még játszok vele, mert ez a mennyiségű zseton komolyan megakadályozhat sokakat abban hogy FPGA-kkal foglalkozzanak.
 
Jelenleg a prodzsekt ott tart, hogy sikerült egy kis programot letöltenem a próbapanelom FPGA-jába, ami ráadásul működni is látszik. Rádrótozom majd a PIC és a D/A mellé a dugaszolós panelra, és elkezdek rá DDS kódot fejleszteni. Innentől már nem annyira a digitális részétől félek, hanem majd a végfokozattól, nincs túl nagy tapasztalatom ezekben. De odáig még el kell jutni, aztán ráérek vele kísérletezni.   

Címkék: fpga

Szólj hozzá!

DDS Blues

Nite 2010.03.19. 10:16

 Sajnos nem olvastam utána eléggé a DDS témának így írtam róla pár faszságot. Ami engem legjobban zavart a dologban, az a jitter volt, illetve az, hogy magasabb frekvenciákon nem megy végig a generálandó jel összes mintáján... Aztán futtattam néhány szimulációt és kiderült hogy nem olyan rossz a helyzet mint eredetileg sejtettem, ráadásul az is, hogy a DDS hátrányaival együtt tud élni néhány digitális függvénygenerátor, amiket 250 ezer forint körül vesztegetnek, hmmm...

 Néhány sor kódot bedobok ide, amivel mindenki kipróbálhatja és akár jobban meg is értheti, hogyan működik egy DDS (vagy NCO), csak kedvenc fejlesztőeszközünkbe kell másoljuk (ez most C#, de nagyon hasonló Java vagy C is)
double[] LUT = new double[1 << 10];
double[] LUT2 = new double[1 << 10];            

for (int i = 0; i < LUT.Length; i++)
{
    LUT[i] = Math.Sin(((Math.PI * 2) / LUT.Length) * i);
    LUT2[i] = (double)((double)(2.0/LUT2.Length) * i) - 1.0;
}

  Ez eddig semmi érdekes, létrehozzuk a két LUT(Look Up Table)-t, az egyik egy szinusz függvényt tartalmaz, a másik egy fűrész jelet.
 
int xscale = pbOut.Size.Width;
int yscale = pbOut.Size.Height;
Random r = new Random();

Bitmap bitmap = new Bitmap(xscale, yscale);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.FillRectangle(Brushes.White, 0, 0, xscale, yscale);

Int32 freqreg = Int32.Parse(tbFreqReg.Text);
Int32 phaseacc = 0;

float prevx = 0;
float prevy = yscale/2;
float prevx2 = 0;
float prevy2 = yscale / 2;

for (int i = 0; i < xscale; i++)
{
    phaseacc += freqreg;

    // dither
    int dither = r.Next();
    dither &= (1 << 20) -1;   
    dither -= (1 << 19);

    UInt16 crop = (UInt16)((((UInt32)(phaseacc + dither)) >> 20)                   & (UInt16)((1 << 10)-1)) ;

    graphics.DrawLine(Pens.Black, prevx, prevy, i * 4,                           (float)(LUT[crop] * (yscale / 2)) + yscale / 2);
    prevx = i * 4;
    prevy = (float)(LUT[crop] * (yscale / 2)) + yscale / 2;

    graphics.DrawLine(Pens.Red, prevx2, prevy2, i * 4,                          (float)(LUT2[crop] * (yscale / 2)) + yscale / 2);
    prevx2 = i * 4;
    prevy2 = (float)(LUT2[crop] * (yscale / 2)) + yscale / 2;
}
  Ami itt a DDS-re vonatkozik, az a freqreg, aminek az értékét egy textboxba írtam be, és a phaseacc regiszter, ahonnan vesszük a kimenő jel fázisát. A fázis sokkal több bites, mint a LUT, a kettő között a crop vágja le a felesleges biteket. Kísérleteztem egy kis dither -rel is, hogy a kimenő jel spektruma tisztább legyen, de a Fourier transzformációt csinálja meg aki akarja.
 
 A lényeg, hogy a kimenő jel frekvenciája
fout = freqreg * a rendszer órajele / 2 ^ (phaseacc bithossza)
 
 A kimenő frekvencia felbontását csak a fázis akkumulátor hossza határozza meg, persze nagy frekvenciáknál azért a kimenet nem lesz túl szép. 
 
 Egy ilyen DDS megépítésére ideális eszköz egy fpga, meg esetleg egy PIC, amivel a felhasználói felületet biztosítjuk (pl jelalakok, frekvencia megadása). És ki is derült, hogy a Xilinx biztosít egy varázslót az fpga-ihoz, amivel ilyen DDS-t lehet generálni! Ennek a doksija itt található, nem mellesleg ez a legjobb leírás amit a DDS-ről eddig olvastam.
 
 Namost, gyorsan rakjuk össze, hogy mi derült ki: egy fpga (mondjuk Spartan3 2000 Ft), egy USB-s PIC (1500 Ft), egy DAC (1-3000 Ft), pár kondi, ellenállás és tápfeszültség stabilizátor, és készen van a 250 ezer forintos jelgenerátorunk.
 
 Már rendelem is az alkatrészeket :)
 

Címkék: fpga

Szólj hozzá!

Hozzáérek - működik...

Nite 2010.03.08. 10:25

 Azt hiszem a legidegesítőbb hibajelenség amibe belefutottam a PIC-ekkel folytatott kísérletezéseim közben az volt, amikor látszólag hol működött, hol nem, mindenféle különösebb ok nélkül.

 Azazhogy voltak olyan esetek, amikor inkább működött mint nem, és ez akkor következett be, amikor a kezemmel közelítettem a PIC vagy a próbapanel felé, illetve bármilyen műszert ráakasztottam, hogy mérés alapján találjam ki, mi a baj. Most képzeld ezt el: bekapcsolod az áramkört, se kép se hang. Odanyúlsz, hogy megigazíts valamit - egyből működni kezd. Most jó! felkiáltással elrántod a kezed - baszik menni. Bármit mérni akarsz rajta - egyből működik megint. Vagy egy hétig szórakoztam vele, mire kiderítettem mi a baj, de persze leginkább saját hibámból, tapasztalatlanságomból következett be az egész.

 A szép az benne, hogy amikor az ember nem próbapanelon dugja össze az áramkört, hanem NYÁKot épít neki, akkor az ilyen hibák legtöbbször nem jönnek elő - a próbapanel nem a legideálisabb környezet egy PIC-nek, ráadásul a NYÁK-on valahogy az ember alapból nem szereti az ide-oda lebegő lábakat, hanem inkább kimenetnek állítja őket vagy leföldeli - kísérletezgetés, prototípus építés közben pedig mind a 40 lábra figyelni hogy mit csinál, hát nem az én szokásom. Persze ennyi szájtépés után már gondolhatod, hogy ilyesmi lesz a hiba, de nem volt egyszerű mire a végére jártam. Nyilván az ember egyből arra gondol hogy az MCLR lebeg, gyorsan fel kell húzni hogy ne resetelődjön a PIC. Na ebben az esetben ez nem segített. Gyanakodtam rá, hogy nem áll fel az oszcillátor, mert mindenféle béna jelet mértem rajta, mint kiderült ez csak okozat volt nem ok, de a tuti próba az volt, hogy belső oszcillátorral is ugyanígy nem működött. Utánaolvastam a neten, hogy ki találkozott még ilyennel, és kiderült, hogy páran ugyan láttak hasonlót, de ahogy NYÁK-ot építettek az áramkörnek, elmúlt.

 Végül nem volt több tippem, szépen elkezdtem egyesével minden lábát le-fel kötögetni a PIC-nek, hátha kiderül melyik okoz gondot. És lőn: RB5. Elsőre joggal értetlenkedtem, aztán utánaolvastam az PIC18F2455 adatlapon (nekem ezzel jött elő, de tuti mindegyik csinálja), hogy mi van még ezen a lábon: RB5/KBI1/PGM... Hmmm. A PGM gyanús, dehát nem programozom a PIC-et, ahhoz vagy 10V kellene az MCLR-re, vagyis izé... És igen, a rutinosabbak már ki is találták, az LVP (Low Voltage Programming) be volt kapcsolva a konfigurációban. Innentől kezdve ugyan működik az MCLR-es programozás is, tehát nem veszel észre semmit, csak amikor a PGM úgy dönt, hogy ő most 1, akkor a PIC szépen belép programozó üzemmódba, és se kép se hang az alkalmazásodtól. És a PGM bizony belül nincs húzva sehová, szépen lebeg amerre a szél fúj, az meg valami eszméletlen, hogy ha bármilyen fémhez vagy földhöz érek a környéken, akkor éppen lelebeg és minden működik.

 Mi ebből a tanulság?

- Ha egy funkcióját nem használod a PIC-nek, kapcsold ki. Ha nincs reset gombod, mert úgyis csak addig él az áramkör amíg tápot kap, akkor az MCLR-t állítsd át sima IO lábnak. Ha csak égetővel vagy bootloaderrel programozod, az LVP-t kapcsold ki. Ha a tápot csak stabil helyről kapja, nem kell a BOR. Stb, stb.

- Nézz át minden lábat, hogy mit csinál, akkor is ha nem használod. Ha lehetőség van rá, akkor állítsd be kimenetnek és vezéreld 0-ra még a programod bootolásakor. Ha valami speciális lábról van szó, akkor húzd le földre vagy fel tápra, vagy ha kapcsoló kell rá akkor kikapcsolt állapotban is húzd valamerre pár kilós ellenállással, de semmi esetre ne hagyd lebegni.

És ugyanez prototípus építéskor is. Lusta ember kétszer fárad, emiatt nem érdemes madzagokon vagy utánaolvasáson spórolni.

Címkék: pic

Szólj hozzá!

PIC Programozó vs Bootloader

Nite 2010.03.01. 09:34

 Ha valaki PIC-ekkel akar foglalkozni, már a dolog legelején problémákba fog ütközni. Megveszed a szép új PIC-edet, betolod a próbapanelodba, elolvasod az adatlapját, letöltöd a fejlesztőeszközt a Microchip-től, összerakod az első "Hello World" mórickaalkalmazásodat, aztán őőőőőőőő... hogy is kerül ez most le oda a PIC-re? Természetesen erre van pár megoldása a gyártónak, amik szépen be is szerezhetőek a Chipcad-nél, vagy közvetlenül a Microchip-től is. Egy egyszerű programozó 40000-ért?? Ez azt hiszem bőven kimeríti sok egységsugarú amatőr hobbyjára szánt éves keretét, és akkor még nem csinált semmit. Ne is beszéljünk az olyan úri huncutságokról, mint a Real ICE, ami már debugolni is tudna, de horrorisztikus ára van (arról ne is beszéljünk, hogy mennyi értelme van debugolni olyan real-time környezetben, ahol ha megállítod a program futását, lemaradsz az összes eseményről amire kíváncsi voltál...)

 Szerencsére a PIC-ek programozása nem vészesen bonyolult, és a Microchip elég jól le is dokumentálja a folyamatot ahhoz, hogy akár magunknak építsünk programozó hardvert/szoftvert (ettől azért én mindenkit óva intenék), de van egyszerűbb megoldás is: csak követni kell a többi csóró által kitaposott utat, és az interneten elérhető rengeteg ingyenes / low cost megoldás közül kell válogatni. Egyik legjobb programozó szoftver szerintem a WinPIC, aminek a fejlesztése sajnos leállt, de így is támogat minden PICet ami számít. Hardverből is bőséges a kínálat, csak a WinPIC oldalán van vagy négy amivel együtt tud működni. Sajnos az a programozó, amit én használok, már nem kapható, de azért ide rakom mert állítólag csak szünetel a gyártás. Most hirtelen itt is találtam egy oldalt ahonnan primitív programozót lehet rendelni, de nem tudom, él-e még, ki nem próbáltam.

 Namost, tételezzük fel, hogy beszereztük a pöppec programozó kellékeinket, és nekilátunk fejleszteni. Arról gondolom mindenki az első 5 alkalom után letesz, hogy a programozás kedvéért ki-be cibálja a PIC-et a próbapanelról (vagy egyéb foglalatból), és gyárt magának valamilyen saját csatlakozót, amire a megfelelő lábakat rákötheti, majd amikor szükséges, erre csatlakoztatja a programozót. Az én esetemben ez a folyamat kicsit túl van bonyolítva, mivel hátrányos helyzetből indulok: annyira új alaplapot sikerült szereznem a PC-mbe, hogy nincs rajta soros port... Ebben az esetben a fejlesztési ciklus így néz ki:

- Kód megírása, lefordítása, nem fordul, anyázás, hibajavítgatás, fordítás, most jó. (A VS2008 és az intellisense használata ebben a lépésben a csúnya beszéd mennyiségét jelentősen csökkentette)
- Régebbi gépem (Pentium III) beröffentése, bootol egy ideig... Majd Hex fájl átmásolása.
- PIC lekötése a próbapanel tápról (azt azért nem hajtja meg az égető), és felkötése a programozóra
- PIC programozása, régi gépről Remote Desktoppal irányítva
- PIC táp visszakötése a próbapanelre
- Indít! Nem működik vagy rosszul, anyáz, agyal, fejben kódot futtatva debuggol, heuréka-érzés, és vissza az első lépésre.
- Ha meguntam, régi gépem lelövöm.

 Ez a folyamat azért a valóságban jóval több ideig tart annál, amit hosszú távon tolerálni lehet, bármennyire is rutinos vagyok már benne. Mindezt úgy, hogy USB-s PICekkel dolgozom, tehát a cucc folyamatosan össze van kötve a gépemmel, csak éppen nem olyan madzaggal, amin keresztül tudnám programozni - azazhogy mégiscsak, mégpedig bootloaderrel.

 Amikor először kezdtem a PIC-en USB-vel foglalkozni, a microchip USB library-je elég kezdetleges formában létezett, és a 18F2455-ön (és családján), ami jelenlegi kedvencem, nem futott módosítás nélkül. Mire beüzemeltem, az jó két hetes szopás volt, és ez tartott vissza a bootloader használatától is. Amikor nemrég ujra felvettem a fonalat, a Microchip egy hatalmas, jól struktúrált és átgondolt példakód tömeget tett fel a weboldalára, Microchip Application Libraries néven. Ebben idáig bármilyen kódot fordítottam, elsőre működött minden (ok, kis testreszabás után). Ha valaki még mindig soros portos programozóval büntetné magát annak ellenére, hogy USB-s PIC-et használ, ne tegye. 

 A továbbiakban közreadom amit bootloader témában alkottam, de hozzá kell tennem, ez 99%-ban így benne van a fent nevezett library-ben.

 HIDBootloader: A 18F2455-re optimalizált HID Bootloader verzió (a családból a többire is jó). A módosítások a következők:

- Áttettem Visual Studio-val fordítható állapotba, főleg azért, hogy ha turkálok benne, jobban tudjak navigálni, illetve a #define és #if defined rengetegbe utat vágjak. Persze VS nélkül is fordul, csak a picbuild.bat-ot kell indítani. Ja, újabban szoktam csinálni egy másik bat-ot is, ami release-be fordítja.
- Az io_cfg.h-ban beállítottam az USB által használt ledeket (az én panelomon csak kettő van, és nem ott ahol a demo boardon), és a bootloadert indító mikrokapcsoló helyét (sw2). Ez ha jól rémlik, nekem az MCLR-re van kötve, mivel azt másra nem használom.
- Az io_cfg.h-ban beállítottam az USB_BUS_SENSE-t, mert szeretem ha tudja a cucc, hogy mikor van kábel bedugva és mikor nincs. Ezzel viszont vagy 4 bájttal kilógott a bootloader a neki szánt memóriaterületről (0x1000-ig), így kivettem belőle a ledek villogtatását.

  HIDBootLoader.exe: Ez a PC-n futó programozó szoftver, ez ugyanaz, amit a Microchip ad.

 ClockGen_bldr: A régebbi ClockGen projektem bootloaderesített verziója. A következőket kellett változtatni, hogy menjen:

- A fordításhoz kapott egy új linker script fájlt (18f2455_g_bldr.lkr), ezt az eredeti script alapján vadásztam össze. A lényeg a következő sor:

CODEPAGE NAME=bootloader START=0x0 END=0xFFF PROTECTED
 Ami valami olyasmit mond a linkernek, hogy 0x0000 címtől 0x0FFF címig ne tegyen semmit, mert ott a bootloader. Ennek a fájlnak a mintájára a többi PIC-hez is lehet linker scriptet gyártani, de érdemes előtte megnézni, hogy nem ad-e készen a Microchip.

- Az összes többi változás az interrupt.c fájlban található. A lényeg annyi, hogy az eredeti reset = 0x0000, interrupt low = 0x0008, interrupt hi = 0x0018 vektorok helyett 0x1000, 0x1008, 0x1018 az új vektorok helye. A bootloader ide fogja adni a vezérlést. A projekt letölthető sima soros programozóval is, és működni is fog, mivel a régi vektorok is ki vannak töltve.

 A bootloader működése, használata:

 A bootloader firmware-t felprogramozva elfoglalja az eredeti reset és interrupt vektorokat. A PIC resetkor ő fog elindulni. Első dolga megvizsgálni, hogy a beállított mikrokapcsoló le van-e nyomva, ha igen, akkor programozó üzemmódba lép. Ha nincs lenyomva, akkor a vezérlést a feltöltött programra adja, az 0x1000 pozíciótól. A bootloader saját USB stack-el rendelkezik, ezért elég nagy. Filóztam rajta, hogy hogy lehetne megosztani az USB-s rutinokat a feltöltött alkalmazással, de egyelőre nem küzdök helyhiánnyal úgyhogy jó ez így.

 Ha a bootloaderrel indítjuk a PIC-et, akkor egy USB HID eszközként ismeri fel a PC, nem kell hozzá külön driver. Olyan eszköznél, ami gyártásba kerül(het), a bootloader és a fő program USB VID és PID értékeit ne felejtsük el átírni!

 A HIDBootloader.exe-t elindítva le tudunk tölteni egy .hex fájlt a PIC-re, majd a bootloaderen a Reset gombot megnyomva a PIC ujraindul, a feltöltött kódot futtatva. Innen már a feltöltött kód USB stack-je él, és a PC számára már más USB eszközként látszik.

 Záró gondolatként még annyit, hogy a bootloader meg tudja kapni a vezérlést a fő programból is, aminek különösen akkor van szerepe, ha bedobozoltuk a termékünket és elvitte a felhasználó. Ekkor, ha ügyesek voltunk, tudunk olyan USB utasítást adni, amivel elindítható a bootloader, feltölthetünk új firmware-t, majd resetelhetjük az eszközt - magyarul a felhasználó mindenféle plusz feladata nélkül tudjuk frissíteni a firmware-t. Nem kell hozzá speciális kábel, nem kell visszahozni frissítésre oda, ahol vette (vagy szervízbe), ebből adódóan kevesebbet fog írni a Homárra, és ha azt vesszük, hogy nekünk sem kell programozóval vacakolni, mindenkinek tiszta haszon.

Címkék: pic

Szólj hozzá!

VHDL gyorstalpaló

Nite 2010.02.22. 10:00

 Emlékszem annak idején, még a 90-es években összeraktam egy dobókocka emulátort, csupa-csupa diszkrét logikai IC-ből. Akkoriban jó poénnak tűnt, és esélyem sem volt (nem hogy pénzem) bármiféle PIC vagy egyéb processzor beszerzésére. Azóta az idők megváltoztak, manapság már biztosan PIC-el építeném, még egy USB portot is tennék rá, hogy egyszerűen lehessen tuningolni az egyes számok dobásának esélyeit :)

 Vannak persze ebben is, mint a diszkrét elemekből épülő DDS-ben olyan feladatok, amiknél az ember elgondolkozik, hogy érdemes-e erre egy akkora tudású processzort berakni, csak azért, hogy unatkozzon. Egy számláló meg két logikai kapu kedvéért PIC-et használni túlzásnak tűnik, de ha azt mondom hogy ennek 100MHz-n kell működnie, akkor ráadásul már elég drága processzor kell, ami ezt elbírja. Viszont ha kicsit bonyolódik a logika, diszkrét elemekből megépítve sok alkatrész fog kelleni, és ronda lesz a NYÁK, ami magával hozza a szórt kapacitásokat, induktivitásokat, gerjedést és rossz határfrekvenciát.

 Szerencsére a feladatra kitalálták már a megfelelő célszerszámot, ami ebben az esetben a CPLD (vagy FPGA). Nézzük, milyen előnyei vannak neki:

-  Sok diszkrét logikai elem helyettesíthető egy alkatrésszel

- A lábai általában szabadon programozhatóak a funkciókhoz, így szép (= gyors) NYÁK tervezhető neki

- Bármikor újraprogramozható, így a funkcionalitás frissíthető vagy javítható

 Többet most nem sorolnék fel. Kedvenc CPLD gyártóm jelenleg a Xilinx, mivel széles termékpalettával dolgoznak, a fejlsztő eszközeik ingyenesek, és alkatrészeik könnyen beszerezhetőek a Chipcad-nél. Ha nem akarunk FPGA-kkal foglalkozni, mert a feladat annyira nem bonyolult, nyugodtan használhatjuk például az XC9500 sorozatukból valamelyik CPLD-t. 

 Ha vetünk egy pillantást a család adatlapjára, gyorsan megérthetjük a felépítését egy CPLD-nek: külön vannak választva az IO-blokkok, amik a lábakhoz kapcsolódnak, és a logikát megvalósító Function Block-ok (bocs ezeket nem fordítom le), ezeket egy kapcsoló mátrixal lehet összerendelni. A Function Block áll a Product Term Allocator-ból, ami nagyrészt a logika megvalósításáért felelős, és a Macrocell-ből, ami legfontosabb eleme egy flip-flop, amivel regisztereket lehet megvalósítani. Én a működésébe körülbelül itt hülyültem bele, szerencsére ennél sokkal többet nem is kell tudni arról, hogy mi van benne.

 Az egész cucc JTAG interfészen programozható (és tesztelhető), ehhez a Xilinx van olyan kedves és biztosít dokumentációt, melyben az Appendix B-ben található egy párhuzamos portra készült JTAG kábel kapcsolási rajza is. Ezt könnyen megépíthetjük, működik, szinte a legbonyolultabb dolog olyan PC-t találni amin van még párhuzamos port.

 Nyilván nem fogjuk tudni fejben megírni azt a kódot, amit a JTAG-on le kell tölteni, erre a feladatra adja a Xilinx az ISE fejlesztőeszközét. Már csak azt kellene kitalálnunk, hogy milyen nyelven lehet leírni egy ilyen célhardvert, mint pl a counter vagy a logikai kapuk - és itt érkeztünk el a VHDL-hez.

 A VHDL-t eredetileg azért fejlesztették ki, hogy logikai elemek viselkedését leírják vele, és eleinte tesztelésre használták annak vizsgálatára, hogy a szállított elem megfelel-e a követelményeknek. Később szintézis eszközöket készítettek, hogy ugyanebből a nyelvből létre lehessen hozni magát az alkatrészt. A VHDL-ről érdemes elolvasni az angol wiki-t, amiből viszonylag könnyű az alapokat ellesni, még példakódok is találhatóak benne. Ha valakinek nem szimpatikus a VHDL, programozhat Verilog-ban is, én per pillanat csak a teszteket írtam ebben. Az ISE Webpack fejlesztőeszköz egy elég jó varázslóval rendelkezik a VHDL forrásokhoz, be kell vinnünk neki, hogy a logikánknak milyen bemenetei illetve kimenetei vannak, és ebből a fájl egy részét legenerálja nekünk. A címben említett gyorstalpalás kedvéért fussunk végig egy VHDL-ben megvalósított számláló kódján. A példakódot innen le lehet tölteni.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

 Valahogy így kezdődik a kód, ez nekünk nem annyira lényeges, a VHDL nem kezel gyárilag olyan kimeneteket/bemeneteket, amikkel a CPLD-nk rendelkezik (pl. 3-state), így ezeket a library-ket hozzá kell adni a kódhoz a use utasítással.

entity Counter is
   Port ( Reset : in STD_LOGIC;
      Clock : in STD_LOGIC;
      ClkDivEn : in STD_LOGIC;
      ClkDivRng : in STD_LOGIC;
      Address : out STD_LOGIC_VECTOR (7 downto 0));
end Counter;

 Itt definialtuk az alkatrészünk bemeneteit és kimeneteit. Lesz rajta egy órajel bemenet (Clock), nyolc kimenet, ahol binárisan számol (Address), egy Reset, és hogy valami logika is legyen benne, a számláló frekvenciaosztását szabályozhatjuk a ClkDivEn-el, ami ha nulla, akkor nem osztunk frekvenciát, ha egy, akkor osztunk. Ha a ClkDivRng 0, akkor öttel osztjuk, ha 1, akkor tízzel.

architecture Behavioral of Counter is

signal Divider : integer range 0 to 10;
signal DividerClk: STD_LOGIC;
signal DividedClk : STD_LOGIC;
signal AddrCntr: integer range 0 to 255;

begin

 Egy alkatrészünk állhat több architecture-ból, a mi counterünkben csak egy van, ezt elnevezte nekünk az ISE Behavioral-nak. Még a begin előtt definiálhatunk olyan belső segéd jeleket (signal), amiket egy-az-egyben nem kötünk bemenetre vagy kimenetre, de a leíráshoz szükség van rájuk. Ugyan az Address kimenet típusa STD_LOGIC_VECTOR, én az AddrCntr signal-t integer-nek vettem, mégiscsak egy számot ábrázol.

 Ezután elkezdjük kitölteni az architecture-t az alkatrészünk viselkedését leíró kóddal.

process (Clock, ClkDivEn, ClkDivRng, Reset, DividerClk, Divider)

 A process blokkok írják le, hogy egyes bemenetek függvényében minek kell történnie. A zárójelben fel van sorolva az összes olyan bemenet (vagy signal), amit ez a process blokk feldolgoz.

if (Clock'event ) then 
if (Clock'event and Clock='1') then
if rising_edge(Clock) then

 Ezek a feltételek a Clock lábat vizsgálják. Az első esetben minden esemény érdekel minket, ami a Clock lábon történik, legyen az felfutó vagy lefutó él. A többi eset csak felfutó élre csinál valamit.

if (Reset = '1') then
    DividerClk <= '0';
    Divider <= 0;

 Szóval, ha valami változik a Clock-on, megvizsgáljuk a Reset-et. Ha ez 1, akkor reseteljük a számlálókat.

else
   if (ClkDivRng = '0') then
       if (Divider = 5) then
           Divider <= 0;
           DividerClk <= not DividerClk;
       else
           Divider <= Divider + 1;
       end if;
   else
       if (Divider = 10) then
           Divider <= 0;
           DividerClk <= not DividerClk;
       else
           Divider <= Divider + 1;
       end if;  
   end if; 
end if;

 Ez a rész tulajdonképpen az órajel frekvenciaosztását végzi, akkor ha a Reset nem 1. Ahogy már írtam, ha a ClkDivRng 0, öttel oszt, egyébként tízzel. Az osztáshoz számlálóként a Divider-t használjuk, a leosztott órajel a belső DividerClk signal-on jelenik meg.

process (Clock, ClkDivEn, DividerClk, DividedClk)
begin

   if (ClkDivEn = '0') then
       DividedClk <= Clock;
   else
       DividedClk <= DividerClk;
   end if;

end process;

 Ez a process blokk vizsgálja a ClkDivEn jelet, és ettől függően állapítja meg a számláló belső órajelét, a DividedClk-t. Ha az osztás engedélyezett, akkor a leosztott DividerClk jelenik itt meg, egyébként az eredeti Clock jel.

process (AddrCntr, DividedClk, Reset)
begin
   if (DividedClk'event and DividedClk='1') then
       if (Reset = '1') then
           AddrCntr <= 0;
       else
           AddrCntr <= AddrCntr + 1;
       end if;
       Address <= conv_std_logic_vector(AddrCntr, 8);
   end if;
end process;

 Ez a process végzi tulajdonképpen a számlálást. A DividedClk órajelet figyeli, és számolja. Itt ami érdekes, az az integer átalakítása STD_LOGIC_VECTOR-rá.

 Ha ezt a vhdl fájlt betöltjük a Xilinx ISE fejlesztőeszközbe, egy gyors fordítás után már tölthetjük is le egy JTAG madzaggal a CPLD-nkbe. Ha nehezen hisszük el, hogy működik, az ISE képes letesztelni is emulátorban. Ezt nekem valamiért egy Verilog Test Fixture nevű cuccal sikerült kiviteleznem, úgyhogy az alábbiak a Verilog szépségeit mutatják be. Egyébként teszteléshez jeleket egész egyszerű ezzel a nyelvvel leírni:

module CounterTest;

// Inputs
reg Reset;
reg Clock;
reg ClkDivEn;
reg ClkDivRng;

// Outputs
wire [7:0] Address;

// Instantiate the Unit Under Test (UUT)
Counter uut (
.Reset(Reset),
.Clock(Clock),
.ClkDivEn(ClkDivEn),
.ClkDivRng(ClkDivRng),
.Address(Address)
);
Ezt a részt az ISE generálja nekünk, nagyon nem érdemes vele foglalkozni.

initial begin
  // Initialize Inputs
  Reset = 0;
  Clock = 0;
  ClkDivEn = 0;
  ClkDivRng = 0;

  #100 Reset = 1;
       
  #200 Reset = 0;
  
  #500 ClkDivEn = 1;
  
  #700 ClkDivRng = 1;
end
 Az initial részbe írhatjuk azokat az eseményeket, amik a teszt elindítása után egy meghatározott pillanatban történnek. Először is a bemenetek megkapják a kezdeti értéküket, utána a # után írt számú nanoszekundum eltelte után következik a következő esemény. Jelen esetben 100 ns után a Reset 1 lesz, majd 200 ns-al az indulás után ismét 0. 500 ns-nál a ClkDivEn-t engedélyezzük, 700 ns-nál pedig a range-t 10-es osztásra állítjuk.

 always
  #5 Clock = ~Clock; // every ten nanoseconds invert  
 Az always részbe leírt dolgok folyamatosan történnek. Itt fent azt láthatjuk, hogy a Clock minden ötödik nanoszekundumban invertálódik (a kommentet nem írtam át, bocs), ezzel egy 100MHz-es órajelet adva.

 Ezt a tesztet lefuttatva ellenőrizhetjük a CPLD-nk működését.

 Ennyi fért a gyorstalpalóba, remélem tudtam segíteni elindulni. Nyilván azért is van sikere a VHDL nyelvnek a CPLD/FPGA-k leírásában, mert a nyelv alapjait viszonylag könnyű megtanulni, és egyszerű modelleket gyorsan össze lehet benne hajigálni. Abba azért belegondolni is rossz, hogy ezekkel a nyelvekkel konkrétan processzorok működését is le lehet írni, ehhez már valószínüleg nem lesz elég az alap tudás. Ez is egy szakma, amit teljesen elsajátítani évek alatt lehet - viszont hobby szinten pár nap is elég.

 

Címkék: fpga cpld vhdl

Szólj hozzá!

Programozható órajelgenerátor 1-2.5MHz (III. rész)

Nite 2010.02.07. 09:20

(I. rész)
(II. rész)

 Megkésve bár, de végre felrakom a kódokat is.

 PIC kód
 Windows kód

 Nem gondolom hogy sok meglepetést tartalmaznak. Egy egyszerű függvény a DAC8531 programozására:

 

void SetFreqDAC(WORD_VAL freq)
{
char i;
LATAbits.LATA2 = 0; // CLK Low
LATAbits.LATA1 = 0; // SYNC Low

#ifdef __18CXX
_asm NOP NOP _endasm
#endif

// write PD1 and PD0
for (i = 0; i < 8; i++)
{
LATAbits.LATA2 = 1; // Rising edge LATAbits.LATA0 = 0;
LATAbits.LATA2 = 0; // Falling edge
}

// write level data
for (i = 0; i < 16; i++)
{
LATAbits.LATA2 = 1; // Rising edge LATAbits.LATA0 = freq.bits.b15;
freq.Val *= 2; // rotate left
LATAbits.LATA2 = 0; // Falling edge
}

#ifdef __18CXX
_asm NOP NOP _endasm
#endif

LATAbits.LATA1 = 1; // SYNC High
LATAbits.LATA2 = 1; // CLK High
}

 És kicsit kibővült a TMR1 megszakítás, minden frekvencia mérés után beállítja a DAC-t:

 

void FreqDAC_AutoHoldFreq(DWORD_VAL measured)
{
if (AutoHoldFreq.Val != 0x00) // AutoHold Functionality {
FreqError.Val = AutoHoldFreq.Val - measured.Val; ActualFreq.Val -= (FreqError.Val >> 2); SetFreqDAC(ActualFreq); // Set new freq
}
}

 Ez a frekvencia különbséget néggyel osztja, és ez alapján állítja utána a DAC-t, így nem lesz túl ideges.

 A Windows-os kódot nem részletezem, csak egy új függvényt tartalmaz, ami az auto hold frekvenciát beállítja.

 Az órajelgenerátor kimenő frekvenciájának állandósága nagyban függ attól, hogy a VCO mennyire mászik el. A melegedés miatti, lassú mászásokat a DAC korrigálni tudja, de próbapanelen az áramkör összeszed annyi zajt, hogy a kimenő frekvencia folyton fel-le változzon. Ez 1MHz frekvencián olyan 100 Hz elmozdulásokat jelent. Ha ennél pontosabbra van szükség, akkor a következő megoldások közül lehet választani:

- Jó NYÁK tervvel valószínüleg a zaj nagy része eltűnik

- A VCO bemenetére lehet egy szűrőt tenni, hogy a nagyobb frekvenciás komponensek ne jussanak rá

- A VCO tartományát meg lehet emelni 10MHz-re, és azt visszaosztani 10-el az 1MHz-hez. így a zaj is jelentősen csökkenni fog.

Jó berhelést mindenkinek.

Címkék: usb pic

Szólj hozzá!

Programozható órajelgenerátor 1-2.5MHz (II. rész)

Nite 2010.02.03. 14:26

(I. rész)

 Ahogy ígértem, következzenek a kapcsolási rajzok:

 

 A főszereplő ezen a rajzon a 74LS628, aki egy annyira közönséges VCO, hogy ki se látszik a 74.. szériából. Az ő családjába tartozik még pár IC, nekünk azért jobb ez, mert csak 1 VCO van benne de az jól beállítható. Az adatlapja alapján akkor lesz szép lineáris a frekvenciamenete, ha a Vrng 1-3V közé esik. A 200p és 600Ohm  külső kondi és ellenállás mellett a range beállítható ebben a tartományban úgy, hogy a kimenő frekvencia 0.9 - 2.6 Mhz között változzon 1.5 - 4.5V bemenő feszültségre.

 A DAC egy 8531, persze más is lehet, nekem ez esett kézre. A következőkre érdemes figyelni:

- Monotonic by design, vagyis ugyan nem biztos, hogy a DA átalakítás során minden lépcső ugyanakkora, de legalább biztosan nagyobb mint az előző. Ez nagyon kell a visszacsatolás miatt.

- Serial interface SYNC lábbal, hogy könnyen lehessen a PIC-hez illeszteni.

- Minél több bit, annál jobb lesz a kimenő frekvenciánk felbontása.

 Egy TL431 adja a referencia feszültséget, és egy (pontosabban egy fél) TLV2372 alakítja át a jelszintet olyanra, hogy a VCO meg tudja enni. A sok potméter beállításakor vegyük figyelembe, hogy a VCO kb. 3V tartományban működik jól, és ez a tartomány 1.5V-nál kezdődik. Addig állítsuk őket, míg a DAC-nak adott 0x0000 értékre a kimenő frekvencia kicsivel 2.5MHz felett van, 0xFFFF értékre kicsivel 1MHz alatt (az erősítő invertál).

 A kapcsolási rajz másik fele:

 Ez gondolom nem okoz nagy meglepetéseket, a múltkori frekvenciamérőre kötöttük rá a VCO kimenetét, a PIC RA0, RA1, RA2 lábai programozzák a DAC-ot.

A szoftver és pár sor infó róla legközelebb.

 

 

Címkék: usb pic

Szólj hozzá!

Programozható órajelgenerátor 1-2.5MHz (I. rész)

Nite 2010.02.01. 16:27

 Általában ha Direct Digital Synthesis (DDS) jelgenerátorokról, függvénygenerátorokról van szó, megkapjuk, hogy egy fix órajelből osztják le az összes előállítható frekvenciát. Ebből adódóan ahhoz, hogy tetszőleges, pontos frekvenciát állítsunk elő velük, elég magas órajellel kell működniük. Ha otthon szeretnénk építeni ilyen generátort, több út közül választhatunk:

- "Ami a csövön kifér" USB-s generátor: Az USB2 interfészen keresztül folyamatosan dől a 60MBps adat, ezt egy DA átalakító analóg jellé alakítja. Előnye, hogy gyakorlatilag korlátlan memória áll rendelkezésre a PC-n, hátránya, hogy optimista becsléssel is 40MSps körüli a maximális sebessége, jó felbontása a pár 100kHz-s tartománytól lefele lehet

- Mikroprocesszoros DDS: a DA átalakításon kívül mindent egy processzor intéz (de akár még a DA-t is). Ehhez elég komoly processzor kell, ha magasabb frekvenciákat nagy felbontással akarunk előállítani. Ami halandóknak is elérhető, az jó esetben a 10MSps körül lehet.

- DDS célhardverből: Ez lehet teljesen integrált DDS, amik leginkább szinusz jelet képesek előállítani, pl. az analog devices gyárt nehezen beszerezhető és 100 euró körüli árú, akár 1GSps-re képes DDS-t is (ami már a hobby építgetés határait feszegeti). Használhatunk különálló memóriát, DAC-t, és valamilyen PLD-t vagy FPGA-t, amikből szintén elég drágát kell szerezni, hogy nagy (500 - 1000 MHz) órajelfrekvencián működhessen.

Van egy olyan lehetőségünk is, hogy a hagyományos DDS sémát kicsit felrugjuk, és nem fix órajellel hajtjuk meg a DAC-t, hanem valamilyen VCO kimenetével. Ennek van egy olyan előnye, hogy a VCO felbontása lesz az előállított jel felbontása is, hátránya, hogy a VCO pontossága lesz az eredmény pontossága is. Magyarul feláldozunk egy adag frekvencia pontosságot a felbontásért, és hogy ne kelljen nagyon magas órajelet használni a DDS-hez.

Sajnos a VCO-k viszonylag keskeny frekvencia tartományban hangolhatóak, de különböző frekvencia osztókkal-szorzókkal ez kezelhető. Ha az 1-2.5MHz tartományra lövünk, annak kétszerese lehet a 2-5MHz, ötszöröse az 5-12.5MHz. A VCO bemenetére a feszültséget egy 16 bites DAC-al állíthatjuk elő, ekkor ha a VCO elég lineáris, a kimeneti frekvencia felbontása 23Hz körül alakul. A VCO-knak van még egy olyan tulajdonsága, hogy hajlamosak elmászni melegedéstől, zajtól, stb. Ez a hatás csökkenthető, ha a VCO kimenetét visszacsatoljuk, vagyis a frekvencia elmászást a bemenetre adott jellel kompenzáljuk.

Gondolom már érthető a bejegyzés címe, egy ilyen programozható (természetesen PIC-es, USB-s), VCO-s, stabilizált órajelgenerátor építése következik...

A folytatásban jönnek a kapcsolási rajzok és a szoftverek.
 

Címkék: usb pic

Szólj hozzá!

Primitív USB-s frekvenciamérő ~10MHz

Nite 2010.01.25. 12:28

 Rövid ujjgyakorlatként pár alkatrészből és jónéhány sor kódból összerakhatunk egy egyszerű, de bővíthető frekvenciamérőt, közben pedig összebarátkozunk az USB-s PIC-ekkel és a Microchip USB library-vel. Hogy miért USB-s? Abból a feltételezésből kiindulva, hogy gyakorlatilag minden háztartásban van számítógép, ésszerűnek látszik arra terhelni a kijelzést és a számításigényes műveletek egy részét, így maga a műszer olcsóbb tud maradni. Persze egy frekvenciamérőnél amúgy sincs túl nagy kijelző, de ha az alapokat megismerjük most, akkor bonyolultabb műszerekkel se lesz problémánk később.

 Nem is tépem tovább a számat, itt a hatalmas kapcsolási rajz:
 

 

 És a letölthető PIC firmware illetve Windows-os kód. Visual Studio-val fordul mind a kettő, persze a PIC-hez kell az MCC18 fordító is.
 

 

 Néhány észrevétel már az elején:

 - Itt a PIC18F2455 látható, de ebből a családból bármelyikkel helyettesíthető. Más USB képes PIC-ekkel is, de akkor érdemes a Microchip USB Library-ból kiindulni, ugyanis amit itt találsz, azt kicsit kiheréltem hogy olvashatóbb legyen.

 - Ez az áramkör simán elmegy az USB tápjáról, úgyhogy nyugodtan össze lehet rakni úgy is. Ahogy egyre több mindent akasztunk rá, előbb-utóbb ez a teljesítmény kevés lesz (és a 0-5V se túl sok komolyabb műszerekhez), így később érdemes lesz saját tápot készíteni neki, és csak figyelni az USB kábel csatlakoztatását (ez van most a rajzon).

 - A bemenő jelnek vannak korlátai, a PIC TMR0 számlálóját hajtjuk vele, amihez legalább 0.2Vdd és 0.8Vdd között kell váltakoznia. A mérhető maximum frekvencia olyan 10 MHz-re jön ki. Egy bemeneti fokozattal és egy frekvencia osztóval használhatóbb műszert tudunk ebből csinálni.

 - A mérés pontossága attól függ, mennyi ideig mérünk. Ez a kódban az InterruptCount-al szabályozható. A TMR1 megszakítás kb. 22.8Hz-el érkezik, de ha az InterruptCount = 1, csak minden másodikra mér, kb. 11.4Hz-el. Ez a mérés pontossága is. Ha van egy hitelesített frekvenciamérőnk, a pontos szorzót érdemes ahhoz belőni. 

 

Röviden a működésről:

Microchip USB Library:

 Aki még nem ismeri, annak röviden leírom melyik fájlban mi található.

 - Az USB könyvtárba benézni sem érdemes, azt egyszer jól megírták, működik. Minden ami paraméterezhető, egyel kijjebb van.

 - HardwareProfile.h: Ez írja le, hogy melyik lábon mi van.

 - usb_config.h: Az USB Library beállításai. Érdemes megjegyezni, hogy itt található az USB_POLLING vagy USB_INTERRUPT flag, ami beállítja, hogy az USB feladatok pollozva vagy megszakításból fussanak. Mivel frekvencia mérésnél jó lenne, ha a mérés vége viszonylag pontosan következne be, mi pollozást használunk.

 - usb_descriptors.c: Az USB eszközt leíró VID és PID, illetve a stringek lelőhelye. Éles projektben a Microchip megkér minket, hogy ne az ő VID-jét használjuk.

 - interrupt.c: Az alacsony és a magas prioritású megszakítások kódjai

 - user.c: Az UserInit függvénybe tehetjük a saját inicializáló utasításainkat, a ProcessIO függvény folyamatosan futó feladatok végzésére használható (itt van az USB polling is), a ServiceRequests függvényben az USB-n érkező kéréseket szolgálhatjuk ki.

 Gyakorlatilag ezek a fájlok ugyanazok, mint amiket a Microchip a Generic Demo-jához ad. Amítől ez frekvencia mérő lesz, az a FreqMeter.c és .h fájlokban található.

 

 Induláskor a TMR0 16 biten számol felfele a bejövő jel minden periódusára. Ha a 16 bit körbefordul, a keletkező megszakításban az UpperFreq értéke nő egyel. Minden második (InterruptCount-al állítható) TMR1 megszakítás kiolvassa a TMR0 aktuális értékét és az UpperFreq-t, majd nullázza azokat.

 Egy USB utasítás van definiálva, a READ_FREQ. Ez visszaadja a legutoljára mért frekvenciát.

 

PC szoftver:

 A Microchip driver-ét és az ahhoz kapcsolódó mpusbapi.dll-t használjuk. A drivert a driver könyvtárból fel kell telepíteni, az .inf fájlban található a VID és a PID, ha véletlenül át szeretnénk írni.

 A többit kicsit túlbonyolítottam, de használható: az usbdriver egy C-s program, ami a dll-t használja, ehhez van egy C# wrapper, az usbwrapper.

 Maga a FreqMeter egy C# alkalmazás, indulásakor megnyitja az USB-s eszközt, majd bizonyos időnként kiadja a READ_FREQ parancsot, és megjeleníti a kiolvasott frekvenciát. Itt található a szorzó, amivel lehet kalibrálni egy pontos frekvenciamérőhöz.

 

 Ugyan ez a műszer így frekvencia mérésére éppen hogy csak alkalmas, azért remélem sikerült használható információkat és példakódokat összeszednem az USB-s PIC-ek programozásáról, és talán azok, akik eddig nehezen szánták rá magukat, mert túl bonyolultnak találták a protokollt, mostmár könnyebben fognak boldogulni vele.
 

UPDATE: Képes vagyok három sor kódot is elrontani, úgyhogy frissítettem a rarokat hibajavított verziókkal.

Címkék: usb pic frekvenciamérő

Szólj hozzá!

Microchip C18 kódok szerkesztése Visual Studio-ban

Nite 2010.01.21. 10:46

 Nagyon kedves dolog a Microchip részéről, hogy a saját PIC-einek programozásához ingyenes fejlesztőeszközt biztosít, ráadásul primitív szoftveres emulátorral, ami segít az egyszerűbb kódokat debugolni. Sajnos az MPLab IDE nem a fejlesztők álma, kód szerkesztési képességei körülbelül a notepaddal vetekednek. Ezzel szemben ott van a Visual Studio, amiből fellelhető nem egy ingyenes verzió is, és az intuitív felhasználói felület koronázatlan királyai (na jó, legalábbis az apple után másodikok) készítették. Nagy kár, hogy a VS-t nehezen lehet rábírni PIC gépi kód fordítására, ráadásul a Microchip C18 a VS-től eltérő tájszólásban beszéli a C-t, így a források szerkesztése sem triviális.

 A Microchip fórumán fellelhető egy VS Wizard, ami az MPLab projekteket hivatott átkonvertálni VS-hez, de nekem valamiért nem működik, és mivel nem értem mit csinál meg sem tudom javítani. Ennél egyszerűbb útnak ígérkezett egy saját megoldást készíteni, amit itt most mindenki okulására meg is osztanék.

A problémát érdemes két részre osztani, egyik a forráskód szerkesztése, másik a fordítás. A kód szerkesztéséhez a VS-t fogjuk használni, és amikor elégedettek vagyunk vele, ráuszítjuk az MCC18 fordítót hogy a Hex fájlt előállítsa. Persze a cucc le fog fordulni a VS alatt is, szépen x86 procira, úgyhogy azzal semmit se fogunk kezdeni azon kívül hogy örülünk hogy nincs hiba a kódban. Ha valaki debugolni szeretne vagy ICE-t használni, akkor meg elvileg a kód visszatölthető az MPLab-ba, és hadd szóljon.

Szóval első lépés, hogy a tájszólásbeli különbségeket kicsit lecsökkentsük. Ehhez a near, rom, far, auto, long típusokat felül kell definiálni, a legtöbbet ráadásul semmivel, mivel hasonló fícsör nincs a VS-ben:
#ifndef __18CXX

#define near
#define rom
#define far
#define auto

#define long int
#define __18F2455

#endif
  Ezt egy mscext.h fájlba belementjük, majd az összes c fájlunkhoz beinclude-oljuk. Látszik, hogy ez az egész csak akkor lesz érvényes, ha a __18CXX nem definiált, vagyis ha MCC18 fordítóval fordítjuk, az ezt átugorja.

A következő lépés kicsit fájdalmasabb, sajnos a VS nem kezeli a bináris számok megadására használt 0b01010101 formátumot, így ezeket mindet át kell írnunk hexára vagy decimálisra. Kísérleteztem pár megoldással, de nem sokra jutottam, úgyhogy akinek van erre ötlete, az ne habozzon megírni.

Hasonlóan nem tud mit kezdeni a VS az _asm, _endasm szófordulatokkal, ezeket érdemes a fentihez hasonló blokkba rejteni:
#ifdef __18CXX
    _asm
        CALL high_vector_branch, 1
    _endasm
#endif

 Ezekkel sem fog a VS szórakozni, csak az MCC18.

Figyelni kell még arra is, hogy az include pathokat a VS máshogy kezeli, mint az MCC, általában ha jól belőjük őket a VS-nek, az MCC panaszkodni fog. Ezt majd az MCC fordításnál egy új include könyvtár hozzáadásával orvosoljuk, most állítsuk be úgy, hogy a VS-nek jó legyen.

A sikeres fordításhoz két dolgot be kell még állítani a VS-ben a Project Properties ablakban: A "C/C++" General fülön az Additional Include Directories-hez írjuk be a "C:\MCC18\h" útvonalat, vagy ahova tettük az MCC-t. Ezután az Advanced fülön a Disable Specific Warnings-hoz írjunk 4068-at, hogy a sok ismeretlen pragma miatt ne sírjon.

 Ha minden igaz, mostmár a kódunk lefordul, egyedül linker hibákat fogunk kilóra látni, mert a PIC-hez használt <p18f2455.h> (vagy más) minden változót extern-nek deklarál, persze neki könnyű mert saját lib-je van. Mi inkább csapjunk hozzá a project-hez egy új fájlt, mondjuk mscext.c néven, amiben létrehozzuk a memória területet az extern változóknak:
#include "mscext.h"

#include <p18f2455.h>
#include <i2c.h>

#ifndef __18CXX

volatile near unsigned char TMR0H;
volatile near unsigned char TMR0L;
volatile near unsigned char TMR1H;
volatile near unsigned char TMR1L;

...
...

volatile near union _RCONbits RCONbits;

unsigned char EEAckPolling( PARAM_SCLASS unsigned char control ){ return 0;}
unsigned char WriteI2C( unsigned char data_out ){return 0;}
void IdleI2C( void ) {}


#endif

 Itt még annyiba futhatunk bele, hogy az MCC header fájljaiban nem minden unionnak / structnak van neve, így abból a típusból nem tudnánk példányt létrehozni (ld. union _RCONbits). Itt kicsit hozzá kell nyúlni a .h fájlhoz, de ez a változtatás nem fogja zavarni az MCC-t:
extern volatile near union _RCONbits {
struct {
unsigned NOT_BOR:1;
unsigned NOT_POR:1;
unsigned NOT_PD:1;
unsigned NOT_TO:1;
unsigned NOT_RI:1;
unsigned :1;
unsigned SBOREN:1;
unsigned NOT_IPEN:1;
};
struct {
unsigned BOR:1;
unsigned POR:1;
unsigned PD:1;
unsigned TO:1;
unsigned RI:1;
unsigned :2;
unsigned IPEN:1;
};
} RCONbits;

 Vagyis adjunk nevet az unionnak.

 Ezután az MPLab kódunk ha minden igaz, lefordul ... intel procira :)

 Hogy Hex fájlunk is legyen a végén, az MCC18 fordítást rábízzuk egy batch fájlra:
rem @echo off

set pic=18f2455
set mccpath=C:\MCC18\bin
set projpath=%~dp0
set projname=test
set sourcepath=%projpath%%projname%
set outpath=%projpath%out
set lkrpath=%mccpath%\LKR\%pic%_g.lkr

del %outpath%\*.* /Q

FOR /R "%sourcepath%" %%i IN (*.c) DO %mccpath%\mcc18 -p=%pic% -I=c:\MCC18\h -I=%sourcepath%\usb -I=%sourcepath% %%i -fo=%outpath%\%%~ni.o -fe=%outpath%\%%~ni.err -D__DEBUG -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-

%mccpath%\mplink /p%pic% /l%mccpath%\..\lib %outpath%\*.o /o %outpath%\%projname%.out /m %outpath%\%projname%.map /u_CRUNTIME /u_DEBUG /z__MPLAB_BUILD=1 /z__MPLAB_DEBUG=1

  És ezt mentsük el picbuild.bat néven, a solution könyvtárába. Értelemszerűen a pic és projname változókat írjuk át. Ezt lefuttatva az out könyvtárban létrejön a Hex, amit letölthetünk a PIC-re.

 A FOR-os sorban a -I=%sourcepath%\usb egy projekt alatti könyvtárat jelöl, ez azért kellett, hogy az include-ok működjenek rendesen - konkrétan a ".."-tal volt baja sok helyen. Ezt vedd ki vagy írd át egy saját alkönyvtáradra.

  Akinek nincs kedve külön futtatni a bat-ot, az a VS-ben a Project Properties ablakban a Build Events / Post-Build Event fülön a Command Line mezőbe írja be a "$(SolutionDir)\picbuild.bat" sort. Így az Output ablakban minden fordítás után megjelenik a picbuild kimenete is.

 Ezzel készen is lennénk, használhatjuk a VS-t az MPLab helyett kódolásra. Éljenek a lusta programozók és az IntelliSense!
 

Címkék: visual studio mcc18

Szólj hozzá!

SMD alkatrészek próbapanelen

Nite 2010.01.17. 17:51

 Sokszor előfordult már velem, hogy eszembe jutott valami, amit össze akartam gyorsan dobni, és kipróbálni, hogy működik-e. Erre a feladatra találták ki a próba paneleket, amiből konkrétan nekem a dugdosós fajta tetszik leginkább (pl ilyen.) Nem részletezem hogy milyen bonyolult dolog tud lenni valaminek a kipróbálása ilyenek nélkül, legalábbis bonyolultabb áramkörök esetében, amiket nem drótoz össze az ember a levegőben.

Namost az SMD cuccokkal gyakorlatilag ott vagyunk ahol a part szakad, márpedig egyre több olyan alkatrésszel kell dolgozni, amiket nem lehet más tokozásban kapni (kaphatóak viszont előre gyártott IC panelek, amikre be lehet forrasztani ezeket az alkatrészeket, és lábanként vezetéket hozzájuk. Ezeknek elég horrorisztikus ára van, otthon készítve meg annyi idő és szerencsétlenkedés, mint bármilyen NYÁK gyártás). Erre a problémára szült a kényszer furcsa megoldásokat, amikre különösebben nem lehetek büszke, bár működnek, és ahogy elnéztem a neten, nem én vagyok az egyetlen aki ilyesmire vetemedik :)

PLCC, SOJ és egyéb hasonló tokoknál jól ki lehet használni, hogy az alkatrészek lábai között 1.25mm van, pont mint a szalagkábel erei között.
Ehhez a mókához úgy tűnt, elengedhetetlen egy "pótkéz" (ilyesmi bár ide még nagyító nem kell) és kábelcsupaszoló sem árt, mert őrjítő ennyi eret késsel (ne adj isten foggal) csupaszolni :)
 
 
 
 
 
Érdemes először a szalagkábelt lecsupaszolni, a végeit előónozni (ha csak 1mm körüli részen lesz csupaszítva akkor nem ér össze semmivel és nem kell sodorgatni sem), az IC lábait folyasztószerrel megkenegetni, és előónozni. Ha az ón összezár két lábat véletlenül, ónszívó rézsodronnyal fel lehet szedni a felesleget.
A szalagkábel másik végét érdemes valamilyen kis tűsorra forrasztani hogy egyszerűen be lehessen dugni. Én külön tűsorra forrasztom a vezetékeket funkció szerint (pl. táp, kimenet, bemenet), és szines szalagkábelt használok, de így is sikerült már eltévednem ebben a dzsumbujban.
 
 
Sokkal jobb szórakozás, ha az alkatrész lábai ennél sűrűbben vannak, mint például a TSSOP tokoknál.
Ezeknél a lábakra elég jól rá lehet forrasztani (folyasztószer, előónozás, rézsodrony takarítás után...) alulról (ott valahogy laposabbak :) egy-egy réz szálat, amiket egy szétbontott sodrott rézhuzalból nyerhetünk ki. Ez a művelet már könnyebben végezhető nagyítóval, én legalábbis tuti megvakulnék ha napokig ezt kéne szabad szemmel csinálnom. Szerencsére egy ekkora szál réz nem sok hőt vezet, ezért forrasztás közben kézzel fogható, ráadásul külön öröm, hogy nem forrasztja le magát a lábról, miközben a másik végét erőszakoljuk egy IC foglalatba. 
 
Akármennyire bízunk képességeinkben, érdemes a kész terméket ellenőrizni, hogy nem zártunk-e rövidre valamit valahol. Ha minden oké, akkor már csak arra kell vigyázni hogy a próbapanelbe bedugás vagy a környéken szerelés közben véletlenül ne kuszáljuk össze a pók lábait :)
 
 
Azért én csodát nem várnék ettől a módszertől, az tuti hogy több 100 MHz-re hitelesített alkatrészeink sávszélességét ekkora szórt kapacitásokkal jócskán csökkentettük, de az ember nem is sávszélességet tesztel próbapanelen hanem működési elvet. Ha már minden úgy megy ahogy annak kell, akkor jöhet a nagyfrekvenciás nyáktervezés.

Címkék: smd

Szólj hozzá!

FAQ

Nite 2010.01.17. 08:28

 1. Ezeket a kérdéseket feltette bárki is?

 Van néhány rövid gondolat amit csoportosítva szeretnék leírni, hogy könnyen megtalálhatóak legyenek, ezért mindenek előtt gyorsan megírom ezt a FAQ-t. Majd ha lesznek kérdések tényleg ráérek bővíteni...
 
2. Ez a blog miről szól?
 
 Ha foglalkoztál már hobbi szinten elektronikával, valószínüleg rájöttél, hogy amíg minden elsőre működik, addig szép az élet, de mihelyt valami nem azt csinálja amire számítottál, szükséged lesz műszerekre. Rövidzár méréshez és ha nem akarsz vonalkódos ellenállásokat visszafejtegetni, jól jön egy multiméter, próbapanelekhez nem árt egy tápegység, frekvenciaátvitel vizsgálatához kéne egy jelgenerátor meg egy oszcilloszkóp, digitális áramkörökhöz egy logikai analizátor.
Ha felpattan az ember e-bay-re és szétnéz olcsó műszerek után, gyorsan rájön, hogy több százezer forintot el lehet verni úgy hogy még két ellenállást nem tettél keresztbe. Nem igaz, hogy ennek a pénznek a feléből nem lehet otthon kétszer ilyen jó műszereket építeni! (de, sajnos néha igaz) 
Műszer és más elektronikai kütyük otthoni, hobbi szintű tervezése, építése, buktatók, szép és kókány megoldások: erről akar szólni a blog.
 
3. Régen frissült az oldal. Most mi van?
 
 Sajnos kicsit szétszórt vagyok, és a családom és melóm mellett vagy 5 hobbinak hódolok. Ezért a rendszeres frissítés hiú ábránd, ahogy haladok előre a projektjeimmel, és jön a téma, úgy írom a bejegyzéseket. Nem azért csinálom ezt az egészet, hogy naponta megmondjam a tutit vagy érdekeseket olvashass, hanem inkább egyfajta referenciaként az érdeklődőknek és magamnak.
 
4. Miért ír elektronikáról blogot aki nem ért hozzá?
 
 2000-ben végeztem a Kandón Műszer szakon, így nem mondanám hogy sík hülye vagyok a témához. Azóta nem dolgozom a szakmában, csak hobbi szinten foglalkozok vele. Így kimaradt egy nagy rakás tapasztalat, ezért biztos vagyok benne, hogy sokszor hülyeségeket írok. Szerencsére a web2 korszakában ezek miatt nyugodtan kijavíthatsz, és nem csak én okulok belőle, hanem mindenki aki erre jár. Egyébként szívesen várom más hozzáértő szerzők cikkeit is a blogon.
 
5. Mi olyan érdekes a 21. század elektronikájában, ami a 20.-ban nem volt meg?
 
 Nekem olyan érzésem van, hogy 10-15 évvel ezelőtt elektronikával foglalkozni sokkal inkább kiváltság volt, mint mostanában. Ha az ember keresett egy alkatrészt, bazinagy katalógusokat kellett átnyálaznia különböző gyártóktól, arról nem is beszélve, hogy mennyire volt triviális ezeket beszerezni. Manapság már gyakorlatilag az összess valaha gyártott alkatrész adatlapja 10 másodperc keresés után letölthető az internetről, és a rengeteg webshopnak hála 2-3 nap múlva már forraszthatod befele. Másik érdekes változás, hogy egyre közelebb áll egymáshoz az elektronika és az informatika. Annak idején papíron kiszámoltuk, kézzel megrajzoltuk, diszkrét elemekből építettük az áramköröket, újabban már két szalmaszálat se teszünk keresztbe számítógép nélkül, ráadásul a gyerekek is PIC-el csinálnak villogó ledes áramköröket.
Hogy valami negatívat is mondjak, az igazán bonyolult vagy modern alkatrészeket már csak SMD tokozással fogod megtalálni, természetesen nem véletlenül. Aki ilyesmikkel akar foglalkozni, az jobb ha barátkozik a folyasztószerek, SMD forrasztás és többrétegű panelok világával.
 
 

2 komment