Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2014:spi-glcd-msp

Zadání

Navrhněte hardware SPI převodníku pro řízení paralelního grafického displeje s rozlišením 320×240 typu Raystar RG320240A1 a vytvořte řídící program. Použijte mikrokontrolér MSP430F5529

Úvod

Účelem práce bylo navrhnout řízení dnes již ne příliš moderních displejů typu RG320240A1 využívajících řadič SED1335/RA8835/S1D13700. Displeje s tímto řadičem lze získat poměrně levně (oproti novým moderním LCD) z různých asijských obchodů. Jejich nevýhodnou je na dnešní poměry již zastaralý paralelní interfece s možností použití interface 8080 případě 6800. Z důvodu ušetření počtu pinů byl navržen převodník paralel/SPI, díky kterému je reálně na mikrokontroleru nevratně zabrán pouze 1 pin pro zápis. Převodník bude zároveň možné použít jako paralelní expanzní port nebo převodník pro ovládání HD44780 s možností změny polarity podsvícení a umítění pinů napájení podsvícení.

Pro řadič RA8835 lze najít velké množství knihoven, avšak velká část pracovala pouze s řadičem SED1335. Většina knihoven, i přesto, že byly testovány oba módy displeje se ukázala být nefunkční, případně fungující velmi zvláštním způsobem. Bylo tedy vytvořeno jednoduché vlastní řízení s SPI linkou.

Display RG320240A1 je grafický černobílý s rozlišením 320×240 bodů. Obsahuje několik grafických vrstev s možností tvorby negativu a vlastní generátor znaků.

Srdcem převodníku jsou 2 logické integrované obvody 74HC595. Data do SPI/Paralel převodníku vstupují konektorem SV1. = Pinout SV1 =

  • PIN 1 GND
  • PIN 2 LCD select
  • PIN 3 Data out strobe, přivede seriově přenesená data na výstupy
  • PIN 4 SCLK, seriové hodiny SPI
  • PIN 5 SDATA, seriová data SPI
  • PIN 6 +5V

Konektor SV10 je pokračováním seriové linky SV1 konektoru, lze na něj připojit další SPI periferie, případně další expanzní desku. SV3 a SV2 jsou pouze piny na kterých je vyvedena zem a napájecí napětí. Na obou paralelních linkách jsou vyvedeny SMD LED diody pro případné experimenty nebo test seriové linky. Předřadné rezistory je doporučeno použít dle svítivosti LED diod. Vzhledem k faktu že se jedná pouze o indikační LEDky je vhodné zvolit vyšší hodnoty rezistorů, typicky 1k5 a více. Při velkém jasu by LED diody působily značně rušivě. Barva je volitelná, pro indikační účely je dobré zvolit barvu červenou, žlutou nebo zelenou neboť jsou pro oko nejpříjemnější.

Rezistory R21-R28 mají funkci ochrannou. V případě přepnutí displaye do režimu čtení by bez těchto rezistorů mohlo dojít ke kolizi na datové lince. Konektory SV5 a SV4 jsou pouze výstupní paralelní porty. Konektor SV6 slouží k připojení velkého grafického LCD displeje. Převodník je také kompatibilní s s alfanumerickými displayi s řadičem Hitachi HD44780. K jeho připojení slouží konektor SV9. Konektor SV9 má vyveno více pinů než má standardní altanumetický displej a to z důvodu různého umístění pinů napájení podsvícení. Pomocí jumperů je nezbytné nastavit správné napájení podsvícení, a trimr kontrastu R17. Hodnoty součástek jako je předřadný rezistor podsvícení a podobné je nutno konzultovat s katalogovým listem. Pro různé typy displejů budou hodnoty součástek různé.

Program pro řízení

Odeslání 16b proměnné
void send_SPI(unsigned int c)
{
//funkce odešle po SPI lince 16bitovou proměnnou
 
	unsigned int a;
	a=c>>8;        //do a je uložena horní část 16bitové proměnné
 
	while(!(UCA0IFG&UCTXIFG));   //čekej dokud je buffer prázdný
	UCA0TXBUF=(unsigned char)a;  //pošli horní část proměnné
	while(!(UCA0IFG&UCTXIFG));   //čekej dokud je buffer prázdný
	UCA0TXBUF=(unsigned char)c;  //pošli spodní část proměnné
	while(!(UCA0IFG&UCTXIFG));   //čekej dokud je buffer prázdný
 
	P1OUT |= BIT6;
	P1OUT &=~BIT6;
	return;
}
Funkce pro odeslání příkazu do LCD
void LCD_CMD(unsigned char command)
{
	P8OUT &=~ BIT1;
	SPIDAT |= A0;			//A0 do 1
	SPIDAT=SPIDAT+command;
	SPIDAT &=~ WR;			//WR vynuluji
	send_SPI(SPIDAT);
 
	SPIDAT |= WR;			//WR, A0 přepnu do 1
	send_SPI(SPIDAT);
 
 
	SPIDAT=SPIDAT&0xFF00;
	return;
}
Funkce pro odeslání dat do LCD
void LCD_DATA(unsigned char data)
{
 
	SPIDAT=SPIDAT+data;
	SPIDAT &=~ A0;			//A0 vynuluji
	SPIDAT &=~ WR;			//WR vynuluji
	send_SPI(SPIDAT);
	SPIDAT |= WR;		//WR, A0 přepnu do 1
	send_SPI(SPIDAT);
 
	SPIDAT=SPIDAT&0xFF00;
	return;
}
Umístění kurzoru na pozici
void cursor(unsigned int pozice)
{
LCD_CMD(0x46);  // cursor command
LCD_DATA((unsigned char)pozice); // lower
pozice=pozice>>8;
LCD_DATA((unsigned char)pozice);	// higher
}
Vynulování RAM displeje
void graphics_clear(void)
{
 
//funkce vyčistí grafickou a textovou část
//všechny pozice RAM jsou vyplněny nulami
//bez vynulování zobrazuje LCD nahodilé symboly a grafiku
 
unsigned int m=0; //proměnné pro cykly
unsigned int n=0; //proměnné pro cykly
LCD_CMD(0x4F);
for(m=0;m<27;m++)
{
 
 
	for(n=0;n<40;n++)
	{
		cursor(9600+m*360+n); //výběr jednotlivých sektorů paměti LCD
 
		LCD_CMD(0x42);        //nastav zápis
                                      //sektor LCD vyplněn nulami
		LCD_DATA(0x00);
		LCD_DATA(0x00);
		LCD_DATA(0x00);
		LCD_DATA(0x00);
		LCD_DATA(0x00);
		LCD_DATA(0x00);
		LCD_DATA(0x00);
		LCD_DATA(0x00);
		LCD_DATA(0x00);
 
	}
}
}
Zápis pixelu na pozici
void write_pixel(unsigned int x,unsigned int y)
{
	static int pozicnik=0;
	static int mem;
	static int pole[20]={0};
	unsigned char sektor;
	unsigned char subbit;
	subbit=x%8;
	sektor=(x-subbit)/8;
 
	if(pozicnik!=19)
	{
	cursor(pole[pozicnik+1]);//předchozí pozici vyčistit
	LCD_CMD(0x42);
	LCD_DATA(0x00);
	}
	else
	{
	cursor(pole[0]);//předchozí pozici vyčistit
	LCD_CMD(0x42);
	LCD_DATA(0x00);
	}
 
	mem=9600+y*40+sektor;
	pole[pozicnik]=mem;
	pozicnik++;
 
	if(pozicnik==20)
		{
		pozicnik=0;
		}
 
 
	cursor(mem);
	LCD_CMD(0x42);
	LCD_DATA(0b10000000>>subbit);
}
Inicializační sekvence
SPIDAT|= A0|WR|RD;
send_SPI(SPIDAT);
_delay_cycles(1000);
SPIDAT|= RESET;
send_SPI(SPIDAT);
_delay_cycles(1000);
_delay_cycles(1000);
 
// inicializační sekvence pro LCD 320x240 
// pro jiný rozměr je nutno přepočítat
 
LCD_CMD(0x40); //system set
LCD_DATA(0x30);
LCD_DATA(0x07);
LCD_DATA(0x07);
LCD_DATA(0x27);
LCD_DATA(0x2F);
LCD_DATA(0xEF);
LCD_DATA(0x28);
LCD_DATA(0x00);
 
LCD_CMD(0x44); //scroll
LCD_DATA(0x0);
LCD_DATA(0x0);
LCD_DATA(0xF0);
LCD_DATA(0x80);
LCD_DATA(0x25);
LCD_DATA(0xF0);
LCD_DATA(0x00);
LCD_DATA(0x4B);
LCD_DATA(0x0);
LCD_DATA(0x0);
 
LCD_CMD(0x5A); //HDOT SCR
LCD_DATA(0x0);
LCD_CMD(0x5B); //ovlay
LCD_DATA(0x01);
LCD_CMD(0x58); //DISP ON OFF
LCD_DATA(0x56);
LCD_CMD(0x46); //CSRW
LCD_DATA(0x00);
LCD_DATA(0x00);
LCD_CMD(0x5D); //CSR FORM
LCD_DATA(0x04);
LCD_DATA(0x86);
LCD_CMD(0x59); //display ON
Test grafické části řízení - jezdící had
unsigned int px=0;
unsigned int py=0;
//proměnné se inkrementují tak dlouho dokud "nenarazí na kraj LCD" 
//což je zjištěno pomocí podmínek if(py==239), následně se vynuluje příznak
//a proměnná se dekrementuje, poloha aktuálního bodu je zapsána pomocí write_pixel(px,py);
 
while(1)
{
if(xpriznak==0)
px++;
if(ypriznak==0)
py++;
 
if(xpriznak!=0)
px--;
if(ypriznak!=0)
py--;
 
if(px==319)
xpriznak=1;
if(py==239)
ypriznak=1;
 
if(px==0)
xpriznak=0;
if(py==0)
ypriznak=0;
 
write_pixel(px,py); //zápis polohy bodu
 
for(i=0;i<4000;i++)  //jednoduchý delay
{}
 
}
 
	return 0;
}

Závěr

Funkční řízení LCD po lince SPI je možno vidět na tomto odkazu https://www.youtube.com/watch?v=FCzxzdG-qaQ . Na uvedeném testu je možno vidět postupné několikanásobné vypsání textu Hello world, následně změněna adresa zápisu a vypsáno písmeno C pro zjištění správně textové mřížky LCD. Grafická část zobrazuje jezdícího hada. Během testování se ukázalo, že k řízení by bylo vhodné zvýšit takt procesoru ( použitá vývojová SPI deska využívá takt pouze 4MHz ) případně využít procesor s rychlejším SPI modulem. Použitý LCD výrobce Raystar nedosahuje příliš vysokého kontrastu. V katalogovém listu je uvedena barva černobílá avšak černá tohoto displeje připomíná spíše modrou. Celkový kód je možno vidět zde http://pastebin.com/UqdhU00N

2014/spi-glcd-msp.txt · Poslední úprava: 2015/01/09 10:14 autor: David Čada