Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
Obě strany předchozí revize Předchozí verze Následující verze | Předchozí verze | ||
2014:spi-glcd-msp [2014/12/29 15:33] David Čada |
2014:spi-glcd-msp [2015/01/09 10:14] (aktuální) David Čada [Závěr] |
||
---|---|---|---|
Řádek 9: | Řádek 9: | ||
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ů. | 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é == | ||
+ | |||
+ | <code cpp> | ||
+ | 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; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | == Funkce pro odeslání příkazu do LCD== | ||
+ | <code cpp> | ||
+ | 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; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | == Funkce pro odeslání dat do LCD== | ||
+ | <code cpp> | ||
+ | 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; | ||
+ | } | ||
+ | </code> | ||
+ | == Umístění kurzoru na pozici == | ||
+ | <code cpp> | ||
+ | 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 | ||
+ | } | ||
+ | </code> | ||
+ | == Vynulování RAM displeje == | ||
+ | <code cpp> | ||
+ | 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); | ||
+ | |||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | == Zápis pixelu na pozici == | ||
+ | <code cpp> | ||
+ | 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); | ||
+ | } | ||
+ | </code> | ||
+ | ==Inicializační sekvence== | ||
+ | <code cpp> | ||
+ | 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 | ||
+ | </code> | ||
+ | |||
+ | ==Test grafické části řízení - jezdící had== | ||
+ | <code cpp> | ||
+ | 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; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== 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 |