LPC je možné softwarově vypnout a piny použít jako GPIO porty procesoru, se 7dmi řídícími signály (typ. 4bit datová komunikace a 3 řídící signály), umožnuje snadno připojit libovolné periferie, výkonem se hodí pro periferie jako je např. LCD display, hlídací kontakty, spínání relé spod...
schéma připojení LCD s řadičem (některé LCD mají signál R/W inverzní), většina řadičů podporuje 4bitovou komunikaci, je dobré si oveřit, signály DB0 - DB3 jsou připojeny na - (0), DB4-DB7, RS, RW a E jsou připojeny na linky GPIO LPC konektoru JP1, většina LCD je dnes už i ve 3,3V provedení, tak že nemá li podsvícení je možné celý napájet z PINu 18 vedeným přes JP5, pro 5V LCD a pro podsvícení je potřebné další napájení mimo LPC konektor JP5 v poloze VCC, pomocí R1 nastavíme kontrast, GPIO39 můžeme použít k ovládaní podsvícení nebo pro jinou libovolnou funkci pokud nepotřebujeme z LCD číst status (u jedno a dvouřádkových LCD stačí počkat pár ms a pin může být použit na cokoli jiného, u grafických LCD už mazání a scrollování trvá různě dlouhou dobu a pin je nutné použít)
při prvním spuštění stačí vypnoput LPC a aktivovat GPIO32-GPIO37 a GPIO39 jako výstupy případně vstupy, viz následující kousek programu:
#define GPIO_REGS 0xf400 void gpio_init(void) { /* GPIO 32-37,39 are outputs */ unsigned int val; unsigned int mask = 0x3a2f3fff; unsigned char bit_ids[] = { 32, 33, 34, 35, 36, 37, 39 }; unsigned char bit_cfg[] = { 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45 }; int ix; iopl(3); /* Give us lots of privilege */ val = inl(0x9030); /* Fetch the PMR (32-bit fetch) */ val = val & mask; /* Clear bits 31-24, 16, 14 */ outl(val, 0x9030); /* Write out the changed value */ val = inl(0x9030); val = inl(GPIO_REGS+0x18); /* read existing interrupt enable bits */ val &= 0xfec0; /* clear 39, 37-32 */ outl(val, GPIO_REGS+0x18); for (ix = 0; ix < sizeof(bit_ids); ix++) { outl((unsigned)bit_ids[ix], GPIO_REGS+0x20); outl((unsigned)bit_cfg[ix], GPIO_REGS+0x24); } val = inl(GPIO_REGS+0x10) | 0x3f; outl(val, GPIO_REGS+0x10); }
komunikace s LCD: RW pro řadič necháme nastaven na 1 budeme pouze zapisovat, lcd_write zapíše data a vytvoří puls pro pin E, lcd_write_data nastaví RS na 1 a zavolá lcd_write nejprve pro horni čtyři bity a následně pro dolní čtyři bity, lcd_write_control nastaví RS na 0 a zavolá lcd_write pro horní čtyři bity a následně pro dolní čtyři bity
void lcd_write(char data){ unsigned int val, cur; cur = inl(GPIO_REGS+0x10); val = (cur & 0xFFC0) | (data & 0x001F); /* E=0*/ outl(val, GPIO_REGS+0x10); usleep(0); /* Sleep for the appropriate time */ val = (cur & 0xFFC0) | (data & 0x001F) | 0x0020; /* E=1*/ outl(val, GPIO_REGS+0x10); usleep(0); /* Sleep for the appropriate time */ val = (cur & 0xFFC0) | (data & 0x001F); /* E=0*/ outl(val, GPIO_REGS+0x10); usleep(0); /* Sleep for the appropriate time */ } void lcd_write_data(char data) { lcd_write(((data >> 4) & 0x000f) | 0x0010); lcd_write((data & 0xf) | 0x0010); usleep(sleeptime); } void lcd_write_control(char data) { lcd_write((data >> 4) & 0x000f); lcd_write(data & 0xf); usleep(sleepttime); }
přeložený program na testování setup_gpio -i zavolá gpio_init, -c zavolá write_control (RS=0), -s čeká mezi voláními zvolený čas (u inicializace nebo mazání LCD nutnost), -x zavolá write_data (RS=1), text bez parametru zavolá pro každý znak write_data (RS=1)
příklad použití z ash:
#gpio_init setup_gpio -i #lcd init setup_gpio -s300000 -c51 -c50 -c40 -c12 -c1 #text 1st line setup_gpio -c128 `hostname` #text 2nd line setup_gpio -c192 `date`