Toto je starší verze dokumentu!
====== Zadání ======
Realizujte řízení dotykového RGB displeje K430WQA-V4-F pomocí mikrokontroléru Atmel ATSAM4E16 doplněného o 16MB flash paměť a USB rozhraní. Vytvořte textový font a funkce na zobrazení základních tvarů. Realizujte zobrazení obrázku z flash paměti.
====== Hardware ======
Tento projekt je součást diplomové práce. K řízení je použit MCU ATSAM4E16E který je osazen na vlastní DPS. Zařízení je napájeno z baterie. Toto napětí je impulsními zdroji regulováno na 3.3V a další potřebné napájení (+5V,-5V a +17V pro podsvícení displeje).
Display je je připojen na PORTC. Spodních 24 bitů je určeno pro přenos dat (RGB-888) a zbylé bity jsou použity pro signály HSYNC, VSYNC, DE a DCLK.
====== Program ======
Periodické signály, hlavně DCLK a HSYNC je vhodné řešit hardwarově, nejlépe některými z 9 TimerCounter modulů. Při návrhu se s tímto počítalo a je to takto také realizováno. Zobrazení provádí funkce ZobrazitDISP(). Ta pracuje ve smyčce pro každý řádek. 10 prvních a posledních řádků jsou bez dat nutné pro správnou funkci. Během prvního řádku je nutné signál VSYNC držet celou dobu v aktivní úrovni. Každý jednotlivý řádek také obsahuje několik DCLK před aktivní zónou dat a také za ní.. Tuto zónu určuje signál DE. Pro dekódování formátu je nutné převést formát 256 barev na RGB888. Ktomu slouží pole ENCODE_DISP. Je veliké 256 hodnot každá odpovídá patřičné barvě. Pole DISPLAY_POLE by pro plné rozlišení překročilo velikost RAM MCU a proto je nutné použít pouze rozlišení 420×238. I tak toto pole zabírá 75% RAM.
====== Kód ======
Při ladění a zprovozňování bylo využito logického analyzátoru pro kontrolu generovaných signálů.
#define __SAM4E16E__ #include "stdbool.h" #include "sam4e16e.h" uint8_t DISPLAY_POLE[420][238]; uint32_t ENCODE_DISP[256]; uint16_t Radek,Sloupek;
void PinInit(void){ PIOA->PIO_OER = 0xE03F0000; PIOA->PIO_CODR = 0xE03F0000; PIOC->PIO_OER = 0xD0FFFFFF; PIOC->PIO_CODR = 0xD0FFFFFF; PIOD->PIO_OER = 0xFF000000; PIOD->PIO_CODR = 0xFF000000; PIOE->PIO_OER = 0xF; PIOE->PIO_CODR = 0xF; PIOB->PIO_PDR = 0x0C; PIOB->PIO_ABCDSR[0] = 0x0C; PIOB->PIO_ABCDSR[1] = 0x0C; PIOC->PIO_PDR = 0x2D000000; PIOC->PIO_ABCDSR[0] = 0x2D000000; PIOC->PIO_ABCDSR[1] = 0x0C000000; return; }
void TimerInit(void){ REG_TC1_IER2 = 0x10u; REG_TC1_WPMR = 0x54494D00; REG_TC1_RC0 = 0x05; REG_TC1_RC2 = 0x00CF; REG_TC1_CMR0 = 0x0C00C400; REG_TC1_CMR2 = 0x0009C402u; PMC->PMC_PCER0 = 0x05000000u; REG_TC1_WPMR = 0x54494D01u; REG_TC1_WPMR = 0x54494D00; REG_TC1_RA2 = 0x00CE; REG_TC1_WPMR = 0x54494D01u; return; }
void ZobrazitDISP(void){ uint16_t Cykl=0; while(Cykl<290) { if(Cykl==0x0) { PIOC->PIO_SODR = ((0x1u) << 28); } if(Cykl==0x2) { PIOC->PIO_CODR = ((0x1u) << 28); } if(Cykl>=0xB&&Cykl<0x11B) { Radek=0; uint16_t t=0; while(t<0xEF){t++;} PIOC->PIO_SODR = ((0x1u) << 31); Sloupek=0; while(Sloupek<420) { PIOC->PIO_CODR = ~ENCODE_DISP[DISPLAY_POLE[Sloupek][Radek]]; PIOC->PIO_SODR = ENCODE_DISP[DISPLAY_POLE[Sloupek][Radek]]; Sloupek++; } Radek++; PIOC->PIO_CODR = ((0x1u) << 31); } while(REG_TC1_CV2<=0xC0); Cykl++; } return; }
int main(void) { SystemInit(); SystemCoreClockUpdate(); PinInit(); TimerInit(); REG_TC1_CCR0 = 0x5; REG_TC1_CCR2 = 0x5; while (1) { ZobrazitDISP(); } }