Předem musím uvést že se opět nejedná o nějaký ucelený tutoriál, spíš jen o takové komentáře a střípky jak používat na STM8 mou LCD knihovnu. Vysvětlovat co je to alfanumerický LCD displej určitě nemusím. Jistě jste všichni nějaký viděli třeba v automatu na jízdenky. Možná máte dojem, že je to "přežitá technologie, konec konců i běžné domácí spotřebiče mixérem počínaje a myčkou konče mají grafický displej. Alfanumerický LCD displej má ale tři nesporné výhody - jednoduchost, nízkou náročnost na prostředky mikrokontroléru (paměti) a nízkou spotřebu. Pro nás bude důležitá hlavně ta první - jednoduchost, protože naše znalosti jazyka C jsou zatím na velmi nízké úrovni. Pro tyto displeje existuje nespočet různě kvalitních knihoven a v našem kurzu budeme používat tuto.
Mikrokontrolér komunikuje s displejem pomocí 7 datových linek. Ty jsou na displeji označeny D4,D5,D6,D7 (tvoří 4bitovou sběrnici) a RS,RW,E. Můžeme je připojit na libovolné piny našeho mikrokontroléru a naši volbu musíme zapsat do souboru stm8_hd4480.h. Displej dále ke svému provozu potřebuje napájení (GND a VCC). To přivedeme například z pinů označených +5V a GND. Dále potřebuje přivést na vstup VLCD napětí nastavující kontrast. To vyrobíme pomocí trimru připojeného mezi VCC (+5V) a GND. Jezdec trimru přivedeme na pin VLCD (jako na schematu A). Poslední co musíme zapojit je podsvícení. U některých displejů není potřeba, ale vy používáte "negativní" varianty (tedy světlé písmo na tmavém pozadí) a bez podsvícení nic neuvidíte. Podsvícení je jen LED dioda s prahovým napětím okolo 4V a provozním proudem přibližně 130mA. Anoda i katoda LED jsou vyvedeny na piny označené A a K. Stačí tedy například připojit anodu na +5V a katodu propojit přes sériový rezistor s GND.
Během připojování doporučuji si zapojení poznamenat na list papíru nebo postupně zapisovat rovnou do stm8_hd4480.h. Nejčastější příčinou proč displej "nejde" je právě chybné zapojení. V souboru stm8_hd4480.h najděte makra:
// define your own pinout. Do not forgot that driver needs 5V tolerant pins #define LCD_RS_PORT GPIOF #define LCD_RW_PORT GPIOF #define LCD_E_PORT GPIOF #define LCD_D4_PORT GPIOG #define LCD_D5_PORT GPIOG #define LCD_D6_PORT GPIOG #define LCD_D7_PORT GPIOG #define LCD_RS_PIN GPIO_PIN_7 #define LCD_RW_PIN GPIO_PIN_6 #define LCD_E_PIN GPIO_PIN_5 #define LCD_D4_PIN GPIO_PIN_0 #define LCD_D5_PIN GPIO_PIN_1 #define LCD_D6_PIN GPIO_PIN_2 #define LCD_D7_PIN GPIO_PIN_3
#define LCD_LINES 4 // 1 , 2 or 4 #define LCD_COLUMNS 20 // 8 , 12 , 16 , 20 , 40 (not all are properly implemented)
Pro zobrazování na displeji používáme tyto základní funkce (existuje jich víc, ale my si zatím vystačíme s omezeným repertoárem):
Jistě jste si všimli, že máme vlastně jen dva způsoby jak na displej dostat nějaký text. Buď ho můžeme vypisovat znak po znaku pomocí funkce lcd_putchar a nebo jako celek funkcí lcd_puts. Díky tomu, že Céčko má mezi "standardními" knihovnami (stdio.h) docela slušnou sadu funkcí pro práci s textem, bude pro nás výhodnější využívat je a "tisknout" na displej pomocí druhé jmenované (lcd_puts). Většinu práce za nás budou dělat funkce printf a sprintf. Potkáte je asi v každém tutoriálu k jazyku C a zjednodušeně řečeno provádí formátování a převod čísel na řetězce (text). Umí tedy z proměnných vykouzlit jejich textovou podobu. Obě funkce se od sebe liší jen tím že printf posílá znaky na takzvaný standardní výstup (to zatím neznáte) a sprintf skládá znaky do řetězce (tedy do pole). Bylo by hloupé abych teď popisoval to co je na internetu už 100x napsané, takže si vás dovolím vyzvat aby jste si chování funkce printf/sprintf nastudovali například v jednom z těchto zdrojů.
Naše používaná varianta sprintf se od výše zmíněné funkce printf liší jen v tom že má jeden (první) argument navíc. Tím je pole (tedy ukazatel) kam se má výsledný řetězec zapsat. Druhým argumentem je takzvaný formátovací řetězec. Ten je typicky konstantní (tedy předem daný, zapsaný v uvozovkách) a určuje kolik proměnných, jakého typu a jak se má do pole/řetězce vypsat. Další argumenty jsou pak ony proměnné. Opět si pro jistotu dovolím zapsat pár odkazů na manuál funkce sprintf. Funkce sprinf vrací počet znaků které do řetězce zapsala, čehož lze využít při vypisování textu na LCD. Protože ale plnohodnotná funkce zabírá mnoho paměti, existují i "lightweight" verze. My budeme většinu času používat právě odlehčenou variantu, kterou jsme dostali spolu s překladačem. Ta nemá podporu typů float a double.Velmi užitečná funkce, která je skoro nezbytná při vypisování na displej je možnost zarovnat číslo na pevný počet znaků. Proč si předvedeme na následující chybičce. Máme kus programu který má za úkol nejprve vypsat "rychlost=321" a potom na stejné místo "rychlost=45". Co se stane můžete vidět na obrázku. Poslední číslice "1" zůstane na displeji protože ji nepřepíšeme... Z toho důvodu se vyplatí při takovém zobrazování vždy přepsat předem stanovený počet znaků. K nápravě stačí specifikovat že se hodnota proměnné má vypisovat na pevný počet (zde tři) znaky. Aby jste měli z čeho čerpat, dovolím si vypsat několik různých způsobů formátování. V komentářích vždy uvidíte jak výsledný řetězec (v uvozovkách) který funkce sprintf "vyplyvne"
uint16_t x=500; sprintf(text,"x=%0.5u",x); // "x=00500" sprintf(text,"x=%05u",x); // "x=00500" sprintf(text,"x=%.5u",x); // "x=00500" sprintf(text,"x=%5u",x); // "x= 500" int16_t x=-1256,y=293; sprintf(text,"x=%i y=%i",x,y); // "x=-1256 y=293" -- %i znamená dávej znaménko (minus) jen u záporných sprintf(text,"x=%+i y=%+i",x,y); // "x=-1256 y=+293" -- %+i znamená dávej znaménko vždy sprintf(text,"x=%i y=% i",x,y); // "x=-1256 y= 293" -- % i znamená dej znaménko minus záporným číslům, ostatním mezeru sprintf(text,"x=% 6i y=% 6i",x,y); // "x= -1256 y= 293" -- bezpečný výpis znaménkových int16 (int16 má max. 6 míst) uint32_t y=123456; int32_t z=-259; sprintf(text,"y=%lu z=%li",y,z); // "y=123456 z=-259" -- uint32_t je %lu, int32_t je %li (l jako long) char x='A',y=66; char retezec[]="Ahoj"; sprintf(text,"x=%c x=%u y=%c",x,(uint16_t)x,y); // "x=A x=65 y=B" sprintf(text,"retezec=%s",(uint16_t)retezec); // "retezec=Ahoj" uint16_t y=500; sprintf(text,"y=%x y=%#x",y,y); // "y=1f4 y=0x1f4" sprintf(text,"y=%04x y=%#0.4x",y,y); // "y=01f4 y=0x01f4" sprintf(text,"y=%04X y=%#0.4X",y,y); // "y=01F4 y=0X01F4" uint8_t y=37; sprintf(text,"y=%u",(uint16_t)y); // "y=15" -- takhle se vypisuje typ uint8_t (tedy byte) .. přetypujeme ho na uint16_t
Home
| V1.01 8.7.2020 /
| By Michal Dudka (m.dudka@seznam.cz) /