Jste zde

Display 16x16LED s FFT na ATmega8

f5.jpg

Tento display je navržen jako doplňující modul do libovolného přístroje   jako zobrazovací jednotka. Vzhledem k analogovému stereofonnímu vstupu   je bližší určení spíše jako zobrazovač signálových veličin (oscilogramů,   spekter) v přístroji pro ekvalizaci nebo podobnou úpravu audiosignálů.   Funkce zobrazování není nijak omezená, chová se jako grafický display.   Navíc obsahuje prvky umožňující snadné ovládání celého přístroje.   Komunikace s okolím je pak zajištěna pomocí portu SPI, který je zároveň i   portem pro ISP.Řešení bylo zaměřeno především na co nejmenší cenové náklady.

Fyzická realizace:

Obr. 1. Foto moduluCelý modul je lze rozdělit na několik základních částí, zobrazovací matice, budič, analogový vstup, ovládací prvky a řídící jednotka.

Zobrazovací matice je složena z 16x16 červených LED diod rozměru 2x5mm. Finančně je to nejnáročnější část, proto byly vybrány LED s If=20mA, což naznačuje hlavní nevýhodu celého projektu, spotřebu energie.

Buzení pole LED je zajištěno osmi budiči SCT2024. Tento obvod dokáže budit 16 LED obvodově nastavitelným proudem v rozsahu několika jednotek mA až do 60mA. Přesouvání zobrazovaných dat probíhá po sériové lince a jsou zapisována do posuvného registru, větší množství dat je pak vysouváno na výstup, kam je možné připojit další obvod. Tato možnost je zde využita pro spárování budičů pro vytvoření formátu 4x32. Obvody umožňují rychlou komunikaci v řádech MHz, takže je dovoleno i rychlé multiplexování, takto byl počet budičů snížen na polovinu. Budící proud je pevně nastaven rezistory na hodnotu přibližně 30mA, ve výsledku jsou tedy LED buzeny se střídou 50% proudem 30mA, tj. efektivní hodnota proudu If=15mA. Toto nastavení zajišťuje téměř maximální jas a zároveň velkou životnost LED. Obvodově nejefektivnější řešení by bylo multiplexování 16x16, což by ale vyžadovalo větší počet portů řídící jednotky s nutností posílení na 240mA, na co už ale LED nejsou koncipovány a jejich životnost by byla malá. Navíc toto silně pulzní řešení by zvýšilo i vyzařované rušení do okolí.>

Jelikož je modul předurčen pro zobrazování spektra audiosignálu, je také vybaven dvěma analogovými kanály a ADC. Před AD převodník je vložen antialiasingový filtr 2. řádu s čebyševovou aproximací s mezním kmitočtem 15kHz. Je to aktivní filtr s operačním zesilovačem LM358. Při nízkém nesymetrickém napájení je ovšem dynamický rozsah malý a postačí pouze pro zobrazení nižší kvality. AD převodník je integrovaný přímo v procesoru ATmega8, je to 10bitový převodník s postupnou aproximací s rychlostí až 15kSa/s. Pro audiosignály je ovšem nutno zajistit převod s rychlostí alespoň 40kSa/s, což tento převodník zvládne, ale za cenu snížení rozlišovací schopnosti. Programově je tedy převodník nastaven na snad nejvyšší možnou rychlost (řídící kmitočet ADC 500kHz) a zajišťuje tak převod rychlostí 40kSa/s o rozlišení prakticky asi jen 4bity, což ale pro základní zobrazení akorát postačuje. Pro kvalitnější zpracování se předpokládá získávání dat již v digitální formě pomocí SPI portu.

Pro komunikaci s uživatelem jsou na modulu ummístěna 4 tlačítka, rotační enkodér s tlačítkem a 3 signalizační LED diody. 3 tlačítka jsou umístěna spolu s diodami v řadě a jsou určena pro rychlou volbu a libovolnou signalizaci. Stiskací enkodér spolu s doprovodným tlačítkem (funkce "nahoru") je určena pro ovládání menu a pro jiné pokročilejší volby.

Řídící jednotkou celého systému je mikrokontrolér ATmega8. Budiče jsou jím řízeny po 4 sériových linkách a několika společnými doprovodnými signály včetně hodinového. Multiplexování je zajištěno spínáním anod LED pomocí dvou linek posílených tranzistory. Posílení jednotlivých sloupců bylo nutno dimenzovat na 480mA! Proto byly použity tranzistory BC807-16. Pro analogový vstup jsou rezervovány 2 piny s kanály ADC6 a ADC7. Referenční napětí je nastaveno externími rezistory. Port D je celý rezervován pro uživatelské rozhraní. Ovládání trojice tlačítek a LED je realizováno přepínáním a oba prvky (tlačítko i LED) ač jsou připojeny na stejný pin, tak jsou nezávislé. Pro snímání polohy rotačního enkodéru jsou rezervovány 2 piny, na kterých je možné vyvolat externí přerušení, což zajišťuje nejrychlejší nejjeddnodušší a nejspolehlivější reakci. Zbylá tlačítka jsou snímána piny samostatně. Pro komunikaci s HW okolím je vyhrazeno rozhraní SPI a je vyvedeno na samostatný konektor. Tento port je rozšířen ještě o reset, čímž je využitelný univerzálně pro SPI komunikaci za běhu programu, programování pomocí bootloaderu přes SPI i pro sériové programování ISP. Časování procesoru je zajištěno krystalem 16MHz a nastaven tak nejvyšší možný výkon.


Obr. 2. Schéma zapojení

Celé zapojení je fyzicky realizováno na dvou oboustranných deskách. Rozměry modulu jsou 13x8x3,5cm (ŠxVxH). Nutno je snad jen dodat pár poznámek k propojení desek mezi sebou. Jsou propojeny velkým množstvím pinů, které jsou realizovány rozebranými dutinkovými lištami a kousky drátu. Řešení je to trochu krkolomné, ale výsledek je kompaktní a spolehlivý.

Dále následují plány desky a osazovací plány a fotografie reálného modulu. Přesné rozměry desek jsou 12,7x7,81cm.


Obr. 3. a 4. DPS top a bottom

 


Obr. 5. a 6. Osazení top a bottom


Obr. 7. Drátové propojky

Tab. 1. Seznam součástek

Název Hodnota Pouzdro

C22, C24

5n6 1206
C1, C2, C3, C5, C6, C7, C8 100n 0805
C4, C17, C19, C21, C23, C25, C28, C31, C33-C41 100n 1206
C9-C16 4M7/6V3 SMC-A
C18, C20  10M/10V SMC-A
C26, C27  100M/16V SMC-D
C32  220M/10V SMC-D
D1-D256 LED2x5 červená  
LED2, LED3, LED4 LED 1206
IC1 MEGA8 TQFP32
IC2- IC9 SCT2024CSOG SO24W
IC10 LM358 SO08
T1-T16 BC807-16 SOT23
T17, T18, T19 BC857 SOT23
T21, T22 BC846 SOT23
R17 1R 1206
R1, R2, R3, R4, R6, R7, R8 10 1206
R5 10 0207
R24, R25 100 1206
R19, R22 180 1206
R18, R21 330 1206
R10-R16 680 0805
R9 680 1206
R20, R23 750 1206
R31-R46, R69, R70 1k 1206
R57, R58, R59 1k2 1206
R29 3k 1206
R64, R65, R73, R74 4k7 1206
R30, R47-R52, R56, R61, R62, R66, R71, R72 10k 1206
R28 12k 1206
R53, R54, R55, R60, R63 100k 1206
R26, R27 47k RTRIM3165W
Q1 16MHz HC49UP
S1, S2, S3, S5  tlačítko TSHA-2P
S4  rotační enkodér P-RE20S
I1-I34 kontaktní piny a dutinky
K5-K18
K1, K2 FAST-ON 6,3x0,8 DPS
K3 PC vidlice MA03-1
K4 PC vidlice MA05-1

Obr. 8. a 9. Foto rozebraného modulu

K modul byla vytvořena knihovna s funkcemi pro ovládání modulu a s několika základními funkcemi pro DSP. Také byl vytvořen demonstrační program.

Knihovna byla nazvána jménem modulu, aby byla jasná soudržnost. V hlavičkovém souboru (FZ012010.h) jsou definovány konstanty umožňující jednoduchý přístup k periferiím modulu a některá makra. V céčkovém souboru (FZ012010.c) jsou pak všechny ovládací funkce včetně obsluhy přerušení.

První nutnou funkcí je init(), v ní jsou nastaveny všechny potřebné ovládací registry IO portů, časovače 0, externího přerušení a AD převodníku.

Výpis na display je realizován funkcí zobr(unsigned int).

void zobr(unsigned int *dat)
{
	static unsigned char mpx=0;		/*multiplexovani*/
	unsigned char port;
	char i;
 
	dat=dat+mpx+4;				/*nastaveni ukazatele*/
 
	for (i=0;i<16;i++)			/*poslani prvnich 16b*/
	{
		port=PINC;			/*zadani bitu*/
		port&=(1<<DAT1)|(1<<DAT2)|(1<<DAT3)|(1<<DAT4);
		port^=(1&(*dat>>i))<<DAT1;
		port^=(1&(*(dat+2)>>i))<<DAT2;
		port^=(1&(*(dat+8)>>i))<<DAT3;
		port^=(1&(*(dat+10)>>i))<<DAT4;
		PORTC^=port;
		PORTC|=(1<<CLK);		/*hodinovy pulz*/
		PORTC&=~(1<<CLK);
	}
	dat-=4;					/*nastaveni ukazatele*/
	for (i=0;i<16;i++)			/*poslani druhych 16b*/
	{
		port=PINC;
		port&=(1<<DAT1)|(1<<DAT2)|(1<<DAT3)|(1<<DAT4);
		port^=(1&(*dat>>i))<<DAT1;
		port^=(1&(*(dat+2)>>i))<<DAT2;
		port^=(1&(*(dat+8)>>i))<<DAT3;
		port^=(1&(*(dat+10)>>i))<<DAT4;
		PORTC^=port;
		PORTC|=(1<<CLK);
		PORTC&=~(1<<CLK);
	}
 
	PORTC|=(1<<OE);				/*vypnuti vystupu*/
	PORTB&=~(1<<(MPX1-mpx));		/*vypnuti tranzistoru*/
	PORTB|=(1<<LA);				/*latch dat*/
	PORTB&=~(1<<LA);
	PORTC&=~(1<<OE);			/*zapnuti vystupu*/
	PORTB|=(1<<(MPX2+mpx));			/*prepnuti tranzistoru*/
 
	if (mpx==0) mpx++;			/*posunuti multiplexovani*/
	else mpx=0;
	PRIZNAK&=~(1<<OBR);			/*nulovani priznaku*/
}

Tato funkce postupně načítá jednotlivé bity z datového pole (16xint) a posílá je po sériových linkách do posuvného registru v budících obvodech. Po nasunutí dat je obraz přepnut. Funkce rozlišuje pořadí spuštění, závisí tedy na tom, jestli pořadí spuštění je liché nebo sudé, což zaznamenává proměnná mpx. Takto je realizováno multiplexní zobrazení. Funkci je tedy nutno spouštět periodicky 2-násobkem obnovovací frekvence obrazu, tj. alespoň každých 10ms.

Interval spouštění je ovládán časovačem 0, implicitně je nastaven asi na 160Hz. Po přetečení časovače je nastaven příznak, že má být spuštěna funkce zobrazení. V ukázkovém programu jsou všechny události řešeny prioritně pomocí příznaků, je tím zajištěno, že zobrazovaná informace bude vždy správná i když se její výpočet mírně zpozdí, a zároveň se tím obsluha přerušení zkrátí na nejmenší možnou dobu. Obsluha přerušení pak vypadá následovně:

ISR(TIMER0_OVF_vect)
{
	TCNT0=	CAS_O;
	PRIZNAK|=(1<<OBR);
}

Časovači je nastavena nová konstanta a je nastaven příznak pro zobrazení, jeho vyhodnocení je pak v hlavním programu.

Tímto časovačem je ovládána také funkce ledtl(), která vyžaduje také periodické spouštění. Funkce se stará o rozsvěcování informačních LED a snímá tlačítka (i stisk enkodéru). Výstupem je informace o stavu tlačítek, krátkém stisku a dlouhém stisku. Stav LED je očekáván také v proměnné TLLED.

void ledtl()
{
	unsigned char port,zm;	
	static unsigned char ltmpx, cnt_t1, cnt_t2, cnt_t3, cnt_tc, cnt_tr;
 
	switch (ltmpx)				/*rozliseni poradi spusteni*/
	{
	case 0:
		DDRD=0b11100001;		/*vybiti C*/
		PORTD=0b00000001;
		ltmpx++;
	break;
	case 1:
		DDRD=0b00000001;		/*test tlacitek*/
		PORTD=0b00000001;
		ltmpx++;
	break;
	default:
		port=PIND;			/*vyhodnoceni tlacitek*/
		zm=(port&0b11110000)^(TLLED&0b11110000);
		if (zm!=0) 
		{
			TLLED&=0b00001111;
			TLLED^=port&0b11110000;
			PRIZNAK|=(1<<TL);
		}
		if (((port>>TR)&1)!=((TLLED>>TLR)&1)) 
		{
			TLLED&=~(1<<TLR);
			TLLED^=((port>>TR)&1)<<TLR; PRIZNAK|=(1<<TL);
		}
 
		DDRD=0b11100001;		/*vystup LED*/
		port=0b11100000;
		if ((TLLED&(1<<LED1))!=0) port^=(1<<T1);
		if ((TLLED&(1<<LED2))!=0) port^=(1<<T2);
		if ((TLLED&(1<<LED3))!=0) port^=(1<<T3);
		PORTD=port;
		ltmpx=0;
	break;
	}
				/*vyhodnoceni kratkeho a dlouheho stisku*/
	if ((TLLED&(1<<TL1))!=0) {if (cnt_t1<=CAS_DL) cnt_t1++;}
	else if (cnt_t1!=0) {if (cnt_t1<CAS_DL) TLLED_ST|=1<<TL1; cnt_t1=0;}
	if (cnt_t1==CAS_DL) {TLLED_DL|=1<<TL1; PRIZNAK|=(1<<TL);}
 
	if ((TLLED&(1<<TL2))!=0) {if (cnt_t2<=CAS_DL) cnt_t2++;}
	else if (cnt_t2!=0) {if (cnt_t2<CAS_DL) TLLED_ST|=1<<TL2; cnt_t2=0;}
	if (cnt_t2==CAS_DL) {TLLED_DL|=1<<TL2; PRIZNAK|=(1<<TL);}
 
	if ((TLLED&(1<<TL3))!=0) {if (cnt_t3<=CAS_DL) cnt_t3++;}
	else if (cnt_t3!=0) {if (cnt_t3<CAS_DL) TLLED_ST|=1<<TL3; cnt_t3=0;}
	if (cnt_t3==CAS_DL) {TLLED_DL|=1<<TL3; PRIZNAK|=(1<<TL);}
 
	if ((TLLED&(1<<TLC))!=0) {if (cnt_tc<=CAS_DL) cnt_tc++;}
	else if (cnt_tc!=0) {if (cnt_tc<CAS_DL) TLLED_ST|=1<<TLC; cnt_tc=0;}
	if (cnt_tc==CAS_DL) {TLLED_DL|=1<<TLC; PRIZNAK|=(1<<TL);}
 
	if ((TLLED&(1<<TLR))!=0) {if (cnt_tr<=CAS_DL) cnt_tr++;}
	else if (cnt_tr!=0) {if (cnt_tr<CAS_DL) TLLED_ST|=1<<TLR; cnt_tr=0;}
	if (cnt_tr==CAS_DL) {TLLED_DL|=1<<TLR; PRIZNAK|=(1<<TL);}
}

Jak je vidět z příkazu switch, funkce postupně prochází třemi stavy, v jednom se obsluhují LED diody a čte stav tlačítek. Ostatní stavy slouží k ustálení napětí na filtračních kondenzátorech. Poslední část pak odměřováním intervalu rozhoduje o krátkém nebo dlouhém stisku tlačítka. Po každé změně stavu tlačítek je opět nastaven příznak. Obsluha rotačního enkodéru je realizována velice jednoduše pomocí dvou vstupů pro externí přerušení.

Poslední důležitou operací je obsluha AD převodníku. Převod je zahajován funkcí adstart(char ch, unsigned int n), vstupními parametry jsou kanál 0/1 a počet vzorků. Převodník je nastaven na maximální vzorkovací kmitočet, převod je spuštěn jako volně běžící a po získání kýženého počtu vzorků je zastaven. Každý vzorek je ukládán do paměťového pole addata, která musí být deklarována v hlavním programu.

void adstart(char ch, unsigned int n)
{
	if ((ADCSRA&(1<<ADSC))==0)
	{
		adcnt=n;
		if (ch==0) ADMUX|=1<<MUX0;	/*nastaveni kanalu*/
		else ADMUX&=~(1<<MUX0);
		ADCSRA|=(1<<ADFR);		/*volne bezici prevod*/
		ADCSRA|=(1<<ADSC);		/*start*/
	}
}

A obsluha přerušení dokončení převodu:

ISR(ADC_vect)
{
	int adl, adh;
 
	adl=(int)ADCL;				/*uvolneni k dalsimu prevodu*/
	adh=(int)ADCH;
	adcnt--;
	addata[adcnt]=(char)((adh-167)>>2);	/*ulozeni vzorku*/
	if (adcnt<2) ADCSRA&=~(1<<ADFR);	/*ukonceni prevodu*/
	if (adcnt==0) PRIZNAK|=1<<ADR;		/*nastaveni priznaku*/
}

Při změně stavu programu je někdy nutno převod náhle zastavit, to je realizováno pomocí funkce stop_ad(), zastavení však není okamžité, trvá ještě několik instrukčních cyklů po zavolání.

Další skupina funkcí zajišťuje zpracování získaného signálu. Stěžejní funkce této skupiny je rFFT(char *dat, unsigned char n) pro výpočet spektra signálu. Vstupními hodnotami je pole dat o 2^n reálných vzorků. Po výpočtu je v tomto poli uloženo komplexní spektrum ve složkovém tvaru, nejdříve reálné části a v druhé polovině jejich imaginární části. Funkce je vytvořena jako volatile asm, takže je již maximálně optimalizovaná. Spektrum je možno spočítat až pro 128 vzorků, avšak s rostoucím rozlišením rostou i hodnoty spektra a tím se zvyšuje možnost přetečení. Normalizování spektra by tuto jednoúčelovou funkci akorát zpomalovalo. Algoritmus pro výpočet je odvozen v [4], je použit prakticky stejný algoritmus, jaký je uveden v příloze, jen je zmeněn formát uložení výstupních dat.

Pro určení modulu spektra ze složkového tvaru je k dispozici funkce absh(char *m1, char *m2), která nedělá nic jiného, než že počítá geometrickou absolutní hodnotu. Odmocnina je v tomto případě realizována výčtem z převodní tabulky s 8bitovým rozlišením.

Pro větší rozlišení na nízkých kmitočtech je však možno využít decimace s následnou FFT. Pro decimaci je zde k dispozici funkce decimace(char *vstup, char *vystup, int n, unsigned char d), kde d určije, kolikrát má být signál zdecimován.
Dále byla vytvořena jednoúčelová makra filtrů dolní (IIR_LP01(char *data, int N))a horní (IIR_HP01(data, N))propusti IIR 3. řádu eliptické aproximace s mezním kmitočtem 0,05fvz. Tyto filtry byly vytvořeny za účelem rozdělení výpočtu spektra s logaritmickým rozložením kmitočtu na dvě stejné poloviny. Funkce pro toto rozdělení není vytvořena, ale prakticky už jen stačí vypočítat dvě spektra s vysokým rozlišením a průměrovat některé vzorky.

Jako doplňující byla ještě do knihovny vložena základní znaková sada a funkce, které jsou s ní schopny pracovat.

Ukázkový program využívá většiny dostupných funkcí, je tak možné dobře pochopit jejich funkci. Po inicializaci se objeví intro s úvodním textem a poté se zobrazí jednoduché menu. Menu je ovládáno intuitivně rotačním enkodérem a ukazuje 4 možnosti zobrazení signálu. 1. zobrazuje oscilogram, tzn, zobrazují se periodicky nijak neupravované vzorky vstupního signálu. Další položky již zobrazují vypočtené spektrum a to v rozsahu 20Hz-20kHz, 20Hz-2kHz a 2kHz-20kHz. Pomocí tlačítek je ještě možné zvolit zobrazovaný kanál a zobrazený obraz zmrazit, což je vše indikováno pomocnými LED. Podrobnější funkce je snad zřejmá z komentářů přímo ve zdrojovém souboru.

Závěr:

Display je široce využitelný zvláště pro zobrazování jednoduchých animací nebo spekter signálů. Jeho konstrukce jej předurčuje k použití jako doplňujícího modulu ve větším zařízení. Analogová část je spíše demonstrativní a nelze od ní očekávat přesné výsledky, předpokladem je spíše příjem dat po sériové lince. Menší nevýhodou může být vyšší spotřeba, až 4A, to činí asi 20W při napájení 5V, ovšem doporučené je napájení 3,3V, kdy je sice více omezena analogová část, ale spotřebovaný výkon klesne o více než 6W a tepelné ztráty na budičích jsou pak zanedbatelné. Výhodné je tento modul napájet spínaným zdrojem, který svými rozměry nepobouří.

Literatura:

[1] ATmega8 [online]. ATMEL Datasheet [cit. 12. února 2010]. Dostupný z www: <http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf>
[2] L-113IDT [online]. Kingbright Datasheet [cit. 5. ledna 2010]. Dostupný z www: <http://www.datasheetarchive.com/pdf-datasheets/Datasheets-315/488991.pdf>
[3] SCT2024 [online]. Star Chips technology Datasheet [cit. 5. ledna 2010]. Dostupný z www: <http://www.starchips.com.tw/pdf/SCT2024V01_01.pdf>
[4] ZÁPLATA F. Digitální filtrace na 8bitových procesorech: bakalářská práce. Brno: FEKT VUT v Brně, 2009. 35 s., 6 příl.

Odkazy

PřílohaVelikost
Package icon Projekt ve formátu zip8.57 MB
Soubor Ukázkové video8.12 MB
Hodnocení článku: