==== 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 320x240 bodů. Obsahuje několik grafických vrstev s možností tvorby negativu a vlastní generátor znaků. ==== Návrh zapojení převodníku ==== 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é. {{:2014:spi-glcd-msp:prevodnik.png?500}} ==== 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