A/D převodník se ZN 427

Úvod

Zapojení A/D převodníku s čipem ZN427 bylo zveřejněno v nějakém Amatérském Rádiu 11/89. Podobná, nebo možná i stejná konstrukce, byla používána jako audio sampler u počítačů Amiga. Ostatně od jednoho z majitelů Amigy jsem se o něm tehdy dozvěděl a posléze dohledal v AR.

Použití převodníku ZN427 je nyní značně neaktuální, ačkoli převodník samotný není špatný, tak v porovnání s jinými možnostmi je relativně drahý a jednoúčelový. Nicméně, když jsem ho předváděl na Bytefestu 2007, tak se ukázalo, že tato jednoduchá konstrukce přesto není příliš známá.

Princip funkce

Převodník ZN427 je klasický aproximační A/D převodník, který převádí analogové napětí na binární hodnotu v 10 krocích. Převodník je taktován oscilátorem o frekvenci max. 1MHz, pro převod potřebuje cca 10 taktů, nějaké zpoždění vzniká v obslužném softwaru a na rozhraní 8255 atd... teoreticky by tedy mělo být možné samplovat na frekvenci max. 100kHz, prakticky jsem se nikdy nedostal přes 50kHz. Mimo jiné to je dáno tím, že neřeším reakci na ukončení převodu, prostě programem počkám dost dlouho a spoléhám na to, že bude převod dokončen.

ZN427 může pracovat v bipolárním, nebo unipolárním režimu. Viz datasheet strany 12 až 14, rozdíl je prakticky jen v tom, jestli prostředek rozsahu - hodnota 128, odpovídá 0V nebo polovině Uref. V obou případech je vrácená binární hodnota v rozsahu 0 až 255, převodník nikdy nevrací záporná čísla.

Schéma zapojení

schéma zapojení da odporový převodník

Zapojení použité v praxi a nakreslené ve schématu se poněkud liší od referenčního z datasheetu výrobce. Přiznávám, že si nejsem jistý proč. Pochází právě ze zmíněného článku v AR a v praxi je funkční, jen vstupní kondenzátor je vhodné nahradit větší kapacitou, třeba řádu desítek μF a doplnit přepínačem, který umožňuje kapacitu zkratovat, kvůli "měření" stejnosměrných napětí.

Druhý obvod - 74LS13 funguje jako generátor hodin, kombinace odporu 330Ω a kondenzátoru 1,2nF definují trvání pulzů, signál /BUSY přivedený z převodníku hodiny spouští jen po dobu trvání převodu.

Jediný problém u ZX Spectra je se získáním napětí -5V, v mém ZX Spectrum +2 grey naštěstí na sběrnici dostupné je, takže jsem ho prostě připojil uvnitř UR-4 na jeden dosud nevyužitý kontakt konektoru. K převodníku je připojené přes odpor 82kΩ, proto je odebíraný proud hodně malý a prakticky zdroj nezatěžuje, což je důležité, zdroj v ZX Spectru ani příliš zatížen být nesmí (maximální zátěž bohužel neznám). Ale -5V obecně v ZX Spectru nemusí být dostupné. naštěstí jsou i jiné možnosti. Například postačí 9V baterie zapojená + na GND a - na vstup nějakého 5V stabilizátoru, ideálně lineárního low drop, v krajním případě lze použít jen zenerovu diodu 5V0 s velkým odporem od baterie. Řešení ponechám na fantazii a šuplíkových zásobách konstruktéra.

Součástí celého zapojení je i klasický D/A převodník tvořený R-2R odporovou sítí. Je zapojený přímo na výstupy 8255, port A, který je v UR-4 použit zároveň jako vstup pro Joystick, proto rozhodně nemůže být řeč o nějaké velké přesnosti. Napětí na TTL výstupech je ovlivněno přes odpory připojenými invertory od Kempston joysticku. Krom toho samotné výstupy z 8255 moc přesné nejsou, mnohem lépe se osvědčil např. obvod 74HCT574, ale jako příposlech pro kontrolu signálu takový D/A převodník plně postačuje. Nebo lze rovnou použít integrovaný D/A převodník s TTL latchem a R-2R sítí v jednom pouzdře (např. jsem zkoušel TLC7528N).

Praktické provedení

foto ze strany součástí foto ze strany spojů

Obrázky jsem pořizoval kdysi dávno pomocí scanneru, takže podle toho vypadají, ale snad poslouží.

Jak je vidět, plošný spoj je maximálně jednoduchý, navržený tak, aby ho bylo možné nakreslit ručně perem. Tak ostatně taky vznikl. Použité konektory odpovídají určení. Datový konektor je určený k připojení na rozhraní UR-4 Vstupní cinch a výstupní 3,5mm stereo jack jsem volil s ohledem na dostupné audio kabely, protože právě k hraní si se zvukem jsem převodník původně zamýšlel používat.

pár naměřených hodnot

Navzdory tomu, že D/A převodník je připojen k portu, kde je připojen joystick a navzdory tomu, že jsem před lety k výrobě použil odpory 21K a 10k, místo aby ten větší byl přesným dvojnásobkem, je výstup relativně použitelný. S připojeným audio zesilovačem jsem na výstupu D/A převodníku (před posledním odporem) naměřil tato napětí - viz tabulka. Na tom posledním odporu, ve schématu označeném jako >>R je sice nějaký úbytek napětí, ale díky němu zůstává výstup D/A převodníku více lineární a vstupní odpor zesilovače nemá tak velký vliv.

dec. hodnotabin. hodnotavýstupní napětí [V]
0000000000,02
63001111110,59
127011111111,16
191101111111,65
255111111112,23

Abych na výstupu A/D převodníku dosáhl hodnoty 127, musel jsem nastavit na vstupu napětí 1,27V. To ještě neznamená, že se jím dá přímo napětí měřit, protože bude ovlivněno vstupním děličem. Nicméně bez něj by to pravděpodobně možné bylo.

Na výstupu Uref lze naměřit hezkých 2,56V.

Frekvence generovaná obvodem 74LS13, kterou je převodník taktován, je v mém případě 1,44MHz, což je víc než udává specifikace výrobce (má být max. 1MHz).

Úplně nejvyššího samplerate se mi podařilo dosáhnout násl. programem. Bohužel natolik zjednodušeným, že už nic jiného nedělá. Samplerate jsem naměřil 47,5kHz (měřeno čítačem na signálu /WR). Včetně ukládání do RAM se lze dostat na 34,5kHz (měřeno čítačem) a možná i víc, při rozumné optimalizaci programu. Osciloskopem jsem naměřil délku trvání spouštěcího pulzu 4,3μs a čekání na převedená data 24,5μs (tomu odpovídá samplerate 34,7kHz - tj. s nějakou chybou totéž). Zajímavé pak je, že 24μs je mnohonásobně delší doba, než by měl převod trvat při naměřené taktovací frekvenci (při 1MHz a 11 taktech na převod vychází cca max 12μs i s nějakým náběhem), podle úrovní na dig. výstupu A/D převodníku se zatím zdá, že největší chyba vzniká právě tam, cca 11μs trvá než se TTL úroveň ustálí na smysluplné hodnotě. Ostatně nejvíc omezující je spíš velikost RAM a rychlost CPU takže toto není kritické. 3x NOP je tedy na 3,54MHz ZX Spectru minimum.

		org	32768

		di
		ld	a,130
		out	(127),a
LOOP		xor	a
		out	(95),a
		cpl
		out	(95),a
		nop
		nop
		nop
		in	a,(63)
		out	(31),a
		jp	LOOP

Něco málo obecných informací o A/D - D/A

Jen ve stručnosti a velmi jednoduše, na internetu je dost materiálů popisujích detailně teorii včetně přesných výpočtů. Pokud znáte, text můžete klidně přeskočit.

Obecně jde o to, že analogové napětí při převodu na číslo je nutné tzv. kvantizovat, pomyslně rozsekat po malých kouscích - to jsou ty vodorovné čáry v grafu, čím víc bitů převodník má, tím hustší jsou "řádky", tím přesněji je schopen rozlišit úroveň napětí. Četnost snímání je vyjádřena svislými čarami. Chceme snímat co nejčastěji, ale nelze to provádět nekonečně rychle a to s ohledem na principy fungování, fyzikální limity, cenu převodníku a RAM, kam ukládáme data.

Chceme tedy co nejvíc bitů a co nejvyšší četnost vzorkování tzv. samplerate. V praxi jsou obě hodnoty kompromisem. Obojí je dáno konstrukcí, v tomto případě je počet bitů 8 a samplerate se bude pohybovat někde okolo 20 - 35kHz. Pro srovnání audio CD přehrávače pracují se 2 kanály, 16bity na kanál a vzorkují 44,1kHz. Nicméně i tak je nízká kvalita ZX A/D převodníku v lecčems dostačující.

graf AD DA převodu

Zeleně je nakreslený pomyslný průběh analogového napětí, červeně pak hodnoty, jak takové napětí může snímat A/D převodník.

Při převodu dochází k různým chybám, kde jsou nejčastější příčinou:

  • nízkým samplerate
  • nízké rozlišením úrovní
  • nelinearitou převodu

nízký samplerate

Říká se, že minimum je pro navzorkování nějakého sinusového průběhu o frekvenci f je potřeba samplerate dvojnásobný. Prakticky tomu tak není, pokud chci vidět na obrazovce tvar průběhu, potřebuju alespoň desetinásobně rychlejší samplerate než je vzorkovaný průběh (a i to je málo), ale pokud se spokojím s tím, že navzorkovaný průběh po přehrání na D/A převodníku zní lidskému uchu stejně jako původní signál, tak dvojnásobek postačí. Ve výsledném signálu se totiž objeví spousta vyšších harmonických, které lidské ucho (nebo výstupní frekvenční filtry) potlačí.

Názorněji to je vidět na sestupu křivky v grafu úplně vpravo. Kdyby byl samplerate vyšší, mohli bychom lépe využít rozlišení převodníku a místo skoku o dvě a více úrovní bychom dokázali snímat po jedné, tím bychom se lépe přiblížili tvaru původní křivky.

nízké rozlišení úrovní

Čím víc, tím líp, protože to umožní sledovat i malé změny vstupního napětí. Bit navíc znamená dvojnásobek úrovní, ale taky data navíc, která je potřeba uložit. V případě ZX Spectra odlišovat méně než 8 bitů nemá význam, stejnak to zabere celý byte, resp. pokud neuvažuju všelijaké "kompresní" metody, kdy do jednoho bytu nacpu dva 4 bitové vzorky, jeden do horní a druhý do dolní půlky.

U aproximačních převodníků vyšší rozlišení v bitech znamená i zpomalení převodu, protože na každý další bit je potřeba takt hodin. Počtem bitů tak může být omezen samplerate, což se u ZN427 děje.

nelinearita převodu

To znamená problémy s přesným určením hodnoty. Ideální lineární převodník převádí tak, že binární hodnota 00000000 (0) odpovídá přesně nejnižšímu napětí rozsahu, 11111111 (255) nejvyššímu napětí rozsahu (Uref) a hodnota 01111111 (127) pak polovině rozsahu. Opět přesně viz datasheet, je to tam popsáno.

Linearita převodu je obvykle dána kvalitou čipu, kvalitou provedení výrobcem. Ovšem při zapojování lze udělat několik chyb, které přesnost ovlivní, např. nesprávně nastavený vstupní dělič (hodnota je pak o něco posunutá), nepřesné referenční napětí (totéž), moc malá kapacita na vstupu (zkreslení tvarové) atd...

Ještě pro pořádek, bit s nejmenší váhou (1) se označuje LSB a bit s nejvyšší váhou (128) se označuje MSB. MSB je nastaven pokud napětí na vstupu přesáhne polovinu rozsahu, bit těsně před MSB je nastaven pokud je napětí větší než polovina z poloviny (resp. celek - polovina a z výsledku polovina), atd... až po LSB.

Praktické použití u ZX Spectra

Po připojení k ZX Spectru je nejprve potřeba správně nastavit UR-4. Defaultně po zapnutí, nebo resetu jsou všechny porty nastaveny jako vstupní. Pro práci s tímto A/D D/A převodníkem musí být port A výstup, B vstup a C výstup.

		ld	a,130
		out	(127),a

Detaily viz tabulka Základní řídící slovo 8255.

Když je port nastaven, tak je potřeba nějak přečíst hodnotu. Zapojení převodníku je velmi zjednodušené a stačí na jeho signál /WR připojení k portu C7 přivést log. 0. (Mimochodem, C7 je zvoleno proto, aby to jednak nekolidovalo s C0, které se používá u Didaktiku Gama k přepínání stránek paměti a druhak proto, že to tak bylo v už existujícím zapojení.) Ve stavu nečinnosti udržujeme na C7 log. 1, např. takto.

		xor	a
		out	(95),a
		cpl
		out	(95),a

Pak počkáme pár taktů, než převodník hodnotu převede.

		ld      b,20		; budeme čekat 20 průchodů cyklem (0 = 256 opakování!)
WAIT		djnz	WAIT		; opakuj dokud není B nula

Po uplynutí nějakého času, který závisí buď na rychlosti hodin, nebo prostě na tom, jak chceme samplerate zpomalit, můžeme z převodníku přečíst hodnotu.

		in	a,(63)

A to je vše, zpracování hodnoty nechám na vás. Nakonec ještě malý příklad jak hodnotu číst z Basicu.

	10 OUT 127,130
	20 OUT 95,0: OUT 95,255
	30 PRINT AT 0,0;IN 63;"   "
	40 GOTO 20

Příklad záznamu zvuku

Převodník lze použít k záznamu zvuku, a ten pak použít třeba v programu Sampletracker. Jen je před použitím potřeba zaznamenaný zvuk zkonvertovat, protože (neupravený) Sampletracker pracuje se 4bitovými samply. K tomu účelu také existují jednoduché programy.

;==============================================================================
;  SAMPLER - program demostrující záznam zvuku pomocí A/D převodníku
;==============================================================================

		org	64500			; sem se program přeloží, musí být v rychlé stránce!
		ent	$			; spouštět odsud (pseudoinstrukce pro Prometheus)

START		ld	hl,32768		; adresa místa pro uložení samplu
		ld	de,30000		; počet bytů, které budou zaznamenány
						; pozor ať si nepřemažete program!

LOOP		xor	a			; A = 0, násl. 4 instrukce vyrobí impuls /WR
		out	(95),a			; pošli na port C
		cpl				; A = 255
		out	(95),a			; pošli na port C (trvání asi 4μs)

; Tím, že jsem nastavil všechny bity a nejenom bit 7 jsem zajistil, že tento program
; bude pracovat i s jinými verzemi převodníku s nimiž jsem se setkal.

; V tuto chvíli převodník převádí analogové napětí na číslo, chvíli počkáme

		ld	b,20    		; čekací smyčka
WAIT		djnz	WAIT			; možno měnit počet průchodů (ld b,počet  pozor 0=256 krát!)
						; (nečíst dřív než za 24μs)
						; (což odpovídá frekvenci asi 20kHz až 28kHz)

		in		a,(63)		; přečti hodnotu z převodníku
		ld		(hl),a		; ulož ji do paměti na adresu HL
		inc		hl		; zvyš ukazatel adresy o 1
		dec		de		; sniž počet zbývajících bytů o 1
		ld		a,e		; a porovnej registry B s C, jestli nejsou nulové
		or		d
		jp		nz,LOOP		; pokud nejsou nulové opakuj smyčku
		ret				; hotovo, vrať se

Úpravu programu podle použitého překladače nechám na vás, je dost jednoduchý, aby to nebyl problém. Komentáře samozřejmě můžete vynechat.

Načtení a zpouštění z Basicu lze obstarat třeba takto.

	10 CLEAR 32767
	20 LOAD "" CODE
	30 RANDOMIZE USR 32768

O přehrávání samplovaného zvuku na ZX Spectru si můžete přečíst zde.

Další možností jak převodník využít je jednoduchý osciloskop. Je sice velmi pomalý, ale byl mi párkrát užitečný k pozorování všelijakých pomalých a neperiodických fyzikálních průběhů na které se analogový osciloskop nehodí. Nebo jsem na něm dětem vysvětloval funkci usměrňovače, na to je rychlý dost.

Opravené chyby a změny

  • 17.9.2007 - Kompletně jsem přepracoval celý text o převodníku a odstranil jsem z textu zmínku o ZX Osciloskopu a přesunul do samostatného článku.
  • 22.9.2007 - poslední drobnosti, překlepy , doplnění naměřených hodnot
  • 19.10.2016 - mírně aktualizováno

Download

Zdroj informací: Amatérské rádio 11/89 a spousta vlastních zkušeností k tomu.

[ Zpět na hlavní stránku ]

Tento web je převážně o ZX Spectru, kompatibilních počítačích a jiném zajímavém hardwaru. Naleznete-li chybu, nebo byste rádi cokoliv co s tímto souvisí, můžete mi napsat email. Stručně o mém webu zde.