Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2014:spi-oled-msp

Zadání

Oživte komunikaci se znakovým OLED displejem, na kterém implementujte logické menu a jeho jednotlivé podnabídky. V menu se pohybujte za pomoci připojených ovládacích tlačítek. Implementujte potvrzení volby, uložení do displeje a poslání příslušných dat do koncového zařízení na SPI lince.

Úvod

Cílem práce je navrhnout komunikaci s SPI koncových zařízením. Pro řízení je využit vývojový kit MSP430F5529, na kterém je osazen mikrokontrolér stejného názvu. Je třeba také vytvořit a oživit komunikaci s s OLED displejem. Na tomto displeji bude vytvořeno přehledné menu za jehož pomocí budou nastavený příslušné parametry koncového řízeného SPI zařízení. Pro ovládání jsou uvažovány 4 tlačítka, ke kterým je nutné vytvořit rutinu přerušení z důvodu jejich korektní činnosti.

Koncové SPI zařízení je ve vývojové verzi nahrazeno vytvořeným jednoduchý SPI převodníkem. Tento převodník převádí SPI komunikaci na 16 bitovou paralelní informaci. Takto vytvoření převodník představuje jakousi logickou 16 bitovou sondu. Na výstupech tohoto převodníku je použito 16 LED. Tyto použité LED představují konkrétní bity řídících registrů koncového SPI zařízení, jakým může být například D/A převodník, přijímač S/PDIF atd.

Mikrokontrolér

Zařízení je realizováno ve formě funkčního prototypu a proto pro vývoj byl využit vývojový kit. Jak bylo uvedeno jedná o kit od společnosti Texas Instrumenst. Kit má označení MSP430F5529 a jméno vychází z označení a řady mikrokontroléru, který je na vývojovém kitu použit. Velkou výhodou tohoto vývojového kitu je především jeho možnost využití jako programátoru pro externí mikrokontroléry řady MSP430FXXXX. Použitý mikrokontrolér MSP430F5529 je 16 bitový a je označován výrobce jako „Mixed signal“ mikrokontrolér. To znamená, že mikrokontrolér obsahuje a je schopen zpracovat pokročilejší instrukce, které byly dříve doménou pouze signálových procesorů ( např. HW podpora násobení 32 bitových čísel atd.) Mikrokontrolér pracuje na taktu 4 MHz. Maximální takt mikrokontroléru je až 25 MHz. Velkou výhodou mikrokontroléru je však použití například na bateriový provoz z důvodu velmi malých požadavků na odběr proudu typicky v plném vytížení je odběr proudu 150 uA/MHz. Navíc mikrokontrolér disponuje i 4 stanby režimy, kdy spotřeba klesá na naprosté minimum.

SPI převodník

Jak bylo uvedeno výše, tento převodník slouží v prototypiélním zapojení celého zařízení jako jakési pomyslné koncové SPI zařízení. Za pomocí 16 LED je možné velmi dobře monitorovat, zda jsou příslušné bity na konkrétních pozicích správně nastavovány. Základem převodníku jsou 2 8 bitové shift registry. Konkrétně se jedná o CMOS integrované obvody 74HCT595.Schéma zapojení indikačního převodníku představujícího koncové SPI zařízení je uvedeno na následujícím obrázku. Význam jednotlivých pinů:

  • PIN 1 GND
  • PIN 2 CS (chip select)
  • PIN 3 SCLK (SPI hodiny)
  • PIN 4 SDATA, (SPI data)
  • PIN 5 +5V

Schéma zapojení převodníku pro převod SPI na paralelní informaci pro OLED displej je uvedeno na následujícím obrázku. Jedná se pouze o modifikaci předchozího zapojení převodníku, který slouží jako koncové SPI zařízení.

Ovládací menu a ovládání

Pro snadné a přehledné ovládání a nastavování koncového SPI zařízení bylo vytvořeno přehledné a intuitivní menu. Pro snadné ovládání přípravku byly zvoleny pouze 4 ovládací tlačítka.

  • Menu UP → pohyb v hlavním menu směrem nahoru
  • Menu DOWN → pohyb v hlavním menu směrem dolů
  • Submenu → výběr podnabídky příslušného hlavního menu (kruhové menu)
  • SET

Ke snímání stavu všech tlačítek se přistupuje v rutině přerušení, která je vyvolána přerušením interního časovače/čítače mikrokontroléru MSP430F5529. Tímto způsobem je zajištěno dokonalé SW odstranění zákmitů a zajištěna tak dokonalá a bezproblémová činnost ovládacích tlačítek.

Použitý displej na kterém je vytvořeno ovládací menu je znakový. Disponuje 2 řádky a 20 symboly v každém řádku. Použitá technologie displeje je OLED. Řadič displeje je WS0010. Tento řadič displeje vychází z klasického řadiče Hitachi pro běžné OLED displeje. Ovšem velkou výhodou tohoto řadiče je možnost komunikace také po SPI. Ovšem aby displej, resp. řadič komunikoval po SPI, je nutné provést drobné změny přímo na DPS displeje (záměna několika rezistorů). Poté displej může bez problémů komunikovat i po sériové lince. Ve výchozím nastavení však displej komunikuje klasicky paralelně 8 nebo 4 bitově. Tedy řadič se chová stejně jako klasický LCD s běžným Hitachi řadičem a inicializační algoritmus tohoto displeje je tak totožný. Pro univerzálnost návrhu přípravku nebylo zasahováno do DPS displeje. Avšak z důvodu úspory spousty vstupně výstupních pinů mikrokontroléru byl použit naprosto stejný převodník SPI na paralelní informaci, který je využit jako logická sonda představující koncové zařízení. Místo LED diod se jednoduše na výstupy obvodů 74HCT595 připojí příslušné piny OLED displeje. Displej poté s mikrokontrolérem komunikuje po SPI lince, které se převádí v převodníku na 8 bitovou paralelní informaci pro displej.

Po zapnutí přípravku se na obrazovce objeví uvítací obrazovka. Po stisku tlačítka menu UP se přepne z uvítací obrazovky do menu a zobrazí se první nabídka menu. Dalším stiskem tlačítka menu UP je postupováno v hlavním menu směrem nahoru až do poslední nabídky. Stiskem tlačítka menu DOWN je postupováno menu směrem dolů až do první nabídky.

Při prvním zapnutí přípravku je koncové SPI zařízení z resetováno a uvedeno tak do výchozího nastavení. V této situaci jsou všechny bity řídícího registru tohoto SPI zařízení vynulovány. To je indikováno na 16 LED, které jsou v tuto chvíli zhasnuty. Kromě indikace na LED diodách je výchozí nastavení indikováno také na OLED displeji, neboť při procházení hlavního menu tlačítky menu UP a DOWN není na druhém řádku displeje indikovány žádný zvolený parametr.

Pokud je v menu zobrazen požadovaný parametr který má být změněn je možné třetím tlačítkem s názvem submenu prohlížet všechny podnabídky, které daný parametr umožňuje. Neustálým stiskáváním tohoto tlačítka je projížděno dokola kruhové menu, které toto tlačítko u každé nabídky vyvolává. Pokud je nalezen požadovaný parametr, který má být změněn stiskne se jednoduše poslední nastavovací tlačítko, které má název SET. Tímto stiskem dojde okamžitě k odeslání dat po SPI lince do koncového SPI zařízení a jsou nastaveny příslušné bity jeho řídícího registru, které odpovídají nastavenému parametru. Zároveň s tímto odesláním dat dojde také k zapamatování této volby. Na OLED displeji při zpětném prochází v hlavním menu, již bude na druhém řádku displeje u této volby indikován i zvolený parametr. Tím je zřetelně indikováno, jak bylo koncové zařízení nastaveno.

Vybrané statě řídícího algoritmu

Inicializace SPI komunikace
void SPI_ini(void)
{
	// začátek inicializace SPI
	UCA0CTL1 |= UCSWRST; 				//nastavím
	UCA0CTL0  = UCMST + UCSYNC + UCCKPL + UCMSB; 	// master mode, synchronní mód, polarita hodin,MSB
	UCA0CTL1  = UCSSEL_2;
	UCA0BR0   = 0x00;       		        //předdělička nižší bity
	UCA0BR1   = 0x00;       			//předdělička vyšší bity
	UCA0MCTL  = 0x00;       			//modulace, vždy zapsat 0 (bez modulace)
	UCA0CTL1 &=~ UCSWRST; 				//vynuluji
	//konec inicializace SPI
 
}
Odeslání dat po SPI lince do koncového SPI zařízení
void DAC_send(unsigned int c)
{
     unsigned int a;
     a=c>>8;                    // shiftování doprava o 8 → uložena horní polovina 16 bit proměnné
 
     while(!(UCA0IFG & UCTXIFG)); // čekej dokud není prázdný zásobník
     UCA0TXBUF=(unsigned char)a;  // vloží proměnnou a do zásobníku
     while(!(UCA0IFG & UCTXIFG)); // čekej dokud není prázdný zásobník
     UCA0TXBUF=(unsigned char)c;  // vloží proměnnou c do zásobníku (horních 8 bitů)
     while(!(UCA0IFG & UCTXIFG)); // čekej dokud není prázdný zásobník
 
     P8OUT |= BIT1;		// vytvořen krátký pulz (obě jsou součástí enable pro DAC)
     P8OUT &=~BIT1;
     return;
}
Funkce pro inicializaci OLED displeje
// funkce SPI_send je vytvořena naprosto stejně jako DAC_send,pouze má na jiném pinu MCU vyveden chip select
void LCD_ini(void)
{
	cekej;                           // čekací smyčka, zpomalení komunikace pro řadič
	INIDATA = DB5 | DB4 | DB3;       // nastavení příslušných inicializačních bitů
	SPI_send (INIDATA);              // pošle data po SPI
	cekej;
	INIDATA = EN | DB5 | DB4 | DB3;  // inicializační bity se signálem enable pro displej
	SPI_send (INIDATA);
	cekej;
	INIDATA = DB5 | DB4 | DB3;
	SPI_send (INIDATA);
	cekej;
 
	INIDATA = DB1;
	SPI_send (INIDATA);
	cekej;
	INIDATA = EN | DB1;
	SPI_send (INIDATA);
	cekej;
	INIDATA = DB1;
	SPI_send (INIDATA);
	cekej;
 
	INIDATA = DB3 | DB2;
	SPI_send(INIDATA);
	cekej;
	INIDATA = EN | DB3 | DB2;
	SPI_send (INIDATA);
	cekej;
	INIDATA = DB3 | DB2;
	SPI_send(INIDATA);
	cekej;
 
	INIDATA = DB0;
	SPI_send(INIDATA);
	cekej;
	INIDATA = EN | DB0;
	SPI_send (INIDATA);
	cekej;
	INIDATA = DB0;
	SPI_send(INIDATA);
	cekej;
 
	INIDATA = DB2 | DB1;
	SPI_send(INIDATA);
	cekej;
	INIDATA = EN | DB2 | DB1;
	SPI_send (INIDATA);
	cekej;
	INIDATA = DB2 | DB1;
	SPI_send(INIDATA);
	cekej;
}
Funkce pro instrukcí do LCD
void LCD_instr (unsigned int instrukce)
{
	LCDINSTR = instrukce;
	SPI_send (LCDINSTR);
	cekej;
	LCDINSTR = EN | instrukce;
	SPI_send (LCDINSTR);
	cekej;
	LCDINSTR = instrukce;
	SPI_send (LCDINSTR);
	cekej;
}
Výpis znaku na displej
void LCD_znak (unsigned int znak)
{
	LCDZNAK = RS | znak;
	SPI_send (LCDZNAK);
	cekej;
	LCDZNAK = EN | RS | znak;
	SPI_send (LCDZNAK);
	cekej;
	LCDZNAK = RS | znak;
	SPI_send (LCDZNAK);
	cekej;
}
Funkce pro výpis řetězce na displeji
void LCD_text(char radek, char pozice,char prepis, char text [20])
{
	if (radek==1)
	{
		LCD_instr(DB7 |0x00+pozice-1); //nastavení výpisu od požadovaného segmentu 1.řádku
	}
 
	else if (radek==2)
	{
		LCD_instr(DB7 |0x40+pozice-1); //nastavení výpisu od požadovaného segmentu 2.řádku
	}
 
	char buffer[20];
	int i=0;
	sprintf(buffer,text); // výpis řetězce na OLED
 
		while (buffer[i]!=0)
			{
				LCD_znak(buffer[i]);
				i++;
			}
			if(prepis==true)       // povolení přepisu zbývajících segmentů
			{
			for (i;i>0;i--)
			{
				LCD_znak(' ');
			}
			}
			else if (prepis==false)
			{
 
			}
}
Nastavení a povolení tlačítek
void tlacitka_ini (void)
{
	// inicializace tlačítek
	P1REN |= BIT2;		// povolím pullup rezistor na portu 1 a pinu 2
	P1OUT |= BIT2;		// připojím pullup rezistor na 2
 
	P1REN |= BIT3;
	P1OUT |= BIT3;
 
	P1REN |= BIT4;
	P1OUT |= BIT4;
 
	P1REN |= BIT5;
	P1OUT |= BIT5;
	// konec inicializace tlačítek
}
Přerušení od časovače, ošetření zákmitů tlačítek a přiřazení funkce tlačítům
// Timer A0 interrupt service routine → odstranění zákmitů tlačitek
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void)
{
	if(menu<9)      // nastavení pro tlačítko menu UP
	{
		static int old_state;
		int new_state= P1IN & BIT2;
		if(new_state < old_state)
		{
			btn1_pressed = true;
			menu++;
		}
		old_state = new_state;
	}
	if(menu>1)    // nastavevní pro tlačítko menu DOWN
	{
		static int old_state2;
		int new_state2= P1IN & BIT3;
		if(new_state2 < old_state2)
		{
			btn2_pressed = true;
			menu--;
		}
		old_state2 = new_state2;
	}
 
	static int old_state3;  // nastavení pro tlačítko submenu
	int new_state3= P1IN & BIT4;
		if(new_state3 < old_state3)
		{
			btn3_pressed = true;
			submenu++;
		}
			old_state3 = new_state3;
 
	if(submenu-1 == pocet_submenu)
	{
		submenu=1;
	}
 
	if (send_param!=false)  // nastavení pro tlačítko SET
	{
	static int old_state4;
	int new_state4= P1IN & BIT5;
		if(new_state4 < old_state4)
		{
			btn4_pressed = true;
		}
		old_state4 = new_state4;
	}
}
Test grafické části řízení - jezdící had
// 1. menu
	if((btn1_pressed || btn2_pressed) && menu==1)
	{
		LCD_instr(DB0);             // kompletní vymazání displeje
		LCD_text(1,1,true,"Input");
		btn1_pressed=false;
		btn2_pressed=false;
		send_param=false;           // deaktivace SET tlačítka
		pocet_submenu=2;
		submenu=0;
		if(nastaveni1==1)          // zapamatování nastavení (pokud vybrán Optical)
		{
			LCD_text(2,1,true,"Optical");
			submenu=1;
		}
		else if (nastaveni1==2)   // zapamatování nastavení (pokud vybrán Coaxial)
		{
			LCD_text(2,1,true,"Coaxial");
			submenu=2;
		}
	}
			else if(menu==1 && submenu==1)    // výběr příslušného submenu 3. tlačítkem
			{
				send_param=true;          // umožnění potvrzení tlačítkem SET
				LCD_text(2,1,true,"Optical");
				if(btn4_pressed == true)  // jestliže je stisknuto 4. tlačítko (SET)
				{
					SPDIFDAT |= BIT0; // nastavení nultého bitu na SPI zařízení do 1
					SPDIF_send(SPDIFDAT);
					btn4_pressed=false;
					nastaveni1=1;
				}
			}
 
			else if(menu==1 && submenu==2)
			{
				send_param=true;           // umožnění potvrzení tlačítkem SET       
				LCD_text(2,1,true,"Coaxial");
				if(btn4_pressed == true)   // jestliže je stisknuto 4. tlačítko (SET)
				{
					SPDIFDAT &=~ BIT0; // nastavení nultého bitu na SPI zařízení do 0
					SPDIF_send(SPDIFDAT);
					btn4_pressed=false;
					nastaveni1=2;
				}
 
			}
// konec 1.menu
 
// pro ostatní nabídky menu je algoritmus totožný pouze se změnami příslušných proměnných 

Výsledné zařízení je zobrazeno na následujícím obrázku. V horní části obrázku se nachází vývojový kit a z něj jsou vedeny vodiče pro tlačítka a také vodiče do dvou převodníků. Prvním převodníkem je převodník sloužící jako logická sonda (zelené LED), která indikuje nastavené bity řídícího registru koncového SPI zařízení. Druhým převodníkem (červené LED) je převodník sloužící pro převod sériové linky pro paralelní 8 bitovou komunikaci OLED displeje.

Závěr

Cílem práce bylo oživit komunikaci s periferií po SPI lince. Touto periferií může být chápán například D/A převodník, či přijímač S/PDIF a mnoho dalších obvodů, které umožňují své řízení po SPI a umožňují tak SW řízení své činnosti. Cílem práce bylo také oživit komunikaci s OLED displejem a na tomto displeji vytvořit intuitivní ovládací menu přípravku. Menu mělo být přehledné a jasně informující o právě nastavených parametrech koncového obvodu. posledním důležitým blokem návrhu bylo vytvoření vhodného algoritmu pro snímání stavu tlačítek. Algoritmus musel efektivně potlačit zákmity, které se na tlačítkách vyskytují a stabilizovat tak jejich činnost a tím stabilizovat činnost celého zařízení při jeho ovládání za pomocí těchto tlačítek. S přihlédnutím na tyto požadavky a na dosažené výsledky je možné konstatovat, že zadání bylo splněno. Ovládací menu funguje spolehlivě. Spolehlivě fungují také tlačítka. Bezchybně funguje také zasílání dat po SPI lince do koncového zařízení,což bylo hlavním úkolem této práce.

2014/spi-oled-msp.txt · Poslední úprava: 2015/01/10 19:48 autor: Milan Abrman