Slår på LCD 1602. Ansluter HD44780-baserad LCD-skärm till Arduino

Under hela min passion för elektronik har jag haft möjlighet att använda LCD-skärmar från flera tillverkare - DataVision, WINSTAR, Uniworld Technology Corp. De skilde sig åt i typ av styrenhet, antal stift och längd på ledningarna, men de hade alla samma anslutningsschema, kommandosystem och betjänades av samma program från mikrokontrollern. Därför, även om vi nu kommer att prata om displayen WH0802A från WINSTAR, allt som sägs nedan gäller för tecken LCD-skärmar från andra företag.

Så vi ansluter WH0802A-YGH-CT-skärmen till mikrokontrollern

WH0802A är en tvårads teckendisplay för 8 tecken med en inbyggd KS0066 styrenhet.
Låt oss titta på syftet med displaynålarna.

Vissa skärmar har två extra stift – bakgrundsbelysningsstift + LED och –LED. Dessutom, om det finns slutsatser, betyder det inte att det finns bakgrundsbelysning. Samt vice versa. Min skärm har bakgrundsbelysning, men inga kontrollstift.

Som standard är bakgrundsbelysningen för WH0802A-YGH-CT-skärmen inaktiverad. För att slå på den måste du göra ett par enkla manipulationer, nämligen installera två byglar och löda ett strömbegränsande motstånd (se foto RK, JF respektive RA).

Visa anslutningsschema

Detta är ett typiskt diagram för att ansluta tecken LCD-skärmar. Vi kommer inte att använda kontrollkretsen för displayens bakgrundsbelysning, men jag ritade den för säkerhets skull.

Startkod

Efter att ha lagt på ström till kretsen måste du vrida kontrastregulatorn (motstånd R1). Om den översta raden visas på skärmen betyder det att den är vid liv och att det är dags att börja skriva kod. I det inledande skedet kommer vi att använda en 8-bitars buss. För att få de första resultaten måste vi skriva två funktioner - en datainspelningsfunktion och en kommandoinspelningsfunktion. De skiljer sig på bara en rad - när data skrivs måste RS-signalen vara 1, när ett kommando skrivs måste RS vara 0. Vi kommer inte att använda läsfunktionerna för tillfället, så R/W-signalen kommer alltid att vara 0 .

Skrivcykeln för en 8-bitars buss ser ut så här:
1. Ställ in RS (0 - kommando, 1 - data)
2. Mata ut värdet på databyten till DB7...DB0-bussen
3. Sätt E=1
4. Programvarufördröjning 1
5. Ställ in E=0
6. Programvarufördröjning 2

Kontrollenheten för LCD-teckenvisning är inte oändligt snabb, så programvarufördröjningar används mellan vissa operationer. Den första behövs för att hålla strobesignalen en tid, den andra för att styrenheten ska hinna skriva data eller utföra ett kommando. Fördröjningsvärdena anges alltid i beskrivningen av displaykontrollern och du måste alltid behålla åtminstone deras minimivärde, annars är fel i driften av kontrollenheten oundvikliga.

I allmänhet har displaykontrollern en så kallad busy-flagga - BF. Om flaggan är 1 är styrenheten upptagen, om den är 0 är den ledig. Istället för en andra mjukvarufördröjning kan du läsa upptagetflaggan och kontrollera när displaykontrollern är ledig. Men eftersom vi snabbt vill få de första resultaten kommer vi att ta itu med den upptagna flaggan senare.

//anslut tecken LCD-displayen till AVR
#omfatta
#omfatta

//port till vilken LCD-databussen är ansluten
#define PORT_DATA PORTD
#define PIN_DATA PIND
#define DDRX_DATA DDRD

//port som kontrollstiften är anslutna till
#define PORT_SIG PORTB
#define PIN_SIG PINB
#define DDRX_SIG DDRB

//mikrokontrollerns pinnummer
//till vilken LCD-kontrollstiften är anslutna
#define RS 5
#define RW 6
#define EN 7

//makron för att arbeta med bitar
#define ClearBit(reg, bit) reg &= (~(1<<(bit)))
#define SetBit(reg, bit) reg |= (1<<(bit))

#define F_CPU 8000000
#define_delay_us(us) __delay_cycles((F_CPU / 1000000) * (us));
#define_delay_ms(ms) __delay_cycles((F_CPU / 1000) * (ms));

//kommandoinspelningsfunktion
tomhet LcdWriteCom( osignerad röding data)
{
ClearBit(PORT_SIG, RS); // sätt RS till 0
PORT_DATA = data; // mata ut data till bussen
SetBit(PORT_SIG, EN); // sätt E till 1
_delay_us(2);
ClearBit(PORT_SIG, EN); // sätt E till 0
_delay_us(40);

//datainspelningsfunktion

tomhet LcdWriteData( osignerad röding data)
{
SetBit(PORT_SIG, RS); //ställ RS till 1
PORT_DATA = data; //mata ut data till bussen
SetBit(PORT_SIG, EN); //ställ E till 1
_delay_us(2);

ClearBit(PORT_SIG, EN); // sätt E till 0

Delay_us(40);
}

int huvud( tomhet )
{
medan (1);
lämna tillbaka 0;
}

Det finns inga komplicerade delar här, allt ska vara klart. Varsågod.

Alla LCD-skärmar måste initieras före användning. Initieringsprocessen beskrivs vanligtvis i databladet för displaykontrollern. Men även om det inte finns någon information där så kommer sekvensen med största sannolikhet att vara så här.

1. Servera mat

2. Vänta >40 ms

3. Utför kommandot Function set

D.L.– inställningsbit för bussbredd
0 – 4 bitars buss, 1 – 8 bitars buss

N– bit för att ställa in antalet displayrader
0 – enradsläge, 1 – tvåradsläge

F– teckensnittsinställningsbit
0 – 5*8 format, 1 – 5*11 format

* - det spelar ingen roll vad som kommer att finnas i dessa bitar

4. Ge kommandot Display ON/OFF

D– visa på/av bit
0 – display av, 1 – display på

C– markör på/av bit
0 – markören avaktiverad, 1 – markören aktiverad

B– flimmeraktiveringsbit
0 – flimrande markör aktiverad, 1 – flimrande markör avaktiverad

5. Utför kommandot Rensa display


6. Vänta > 1,5 ms

7. Utför kommandot Entry Mode Set

I/D– ordningsföljd för att öka/minska DDRAM-adressen (visa data-RAM)
0 – markören flyttas åt vänster, adressen minskar med 1, 1 – markören flyttas åt höger, adressen ökar med 1

SH– ändra ordning på hela displayen
0 – ingen växling, 1 – växling sker enligt I/D-signalen – om det finns en 0 – skiftar displayen åt höger, 1 – visningen skiftar åt vänster

För vårt exempel kommer initialiseringsfunktionen att se ut så här

När jag monterade min metalldetektor slutade jag med en LCD-skärm 1602, byggd på HD44780-kontrollern. Jag bestämde mig för att inte missa möjligheten och ansluta den till min kinesiska analog av Arduino UNO.

Det här är 1602-skärmen vi kommer att ansluta till Arduino idag.

Siffrorna "1602" indikerar att displayen består av 2 rader, 16 tecken vardera. Detta är en ganska vanlig skärm, där människor konstruerar klockor, testare och andra prylar. Skärmen kommer med grön och blå bakgrundsbelysning.

Jag lödde en kam av kontakter till displayen så att jag enkelt kunde koppla ihop ledningarna.

Vi kommer att ansluta 1602-skärmen till Arduino via ett 4-bitars parallellt gränssnitt. Det finns också ett alternativ för ett 8-bitars gränssnitt, men det använder fler ledningar, och vi kommer inte att se några vinster i detta.

Förutom displayen och Arduino kommer vi att behöva ledningar och ett 10 kOhm variabelt motstånd. Motståndet kommer att vara lämpligt för alla märken, så länge det har det önskade värdet.

Ström till displayen tillförs genom 1:a (VSS) Och 2:a (VDD) Slutsatser. Till slutsatser 15 (A) Och 16 (K)- Ström tillförs till displayens bakgrundsbelysning. Eftersom samma +5V spänning används för ström och belysning, kommer vi att driva dem från Arduino-stiften "5V" Och "GND". Det viktigaste är att inte förväxla polariteten, annars kan du bränna displayelektroniken.

3:a slutsats (V0) Vi ansluter ett variabelt motstånd till benet, vi kommer att använda det för att kontrollera kontrasten på skärmen. Motståndet kan inte användas, men utgången "V0" koppla till GND. I det här fallet kommer kontrasten att vara maximal och det kommer inte att finnas någon möjlighet till smidig justering.

5:a slutsats (RW) används för att läsa från eller skriva till displayen. Eftersom vi bara kommer att skriva till displayen kommer vi att ansluta detta stift till jord (GND).

Slutsatser: 4:a (RS), 6:e (E), 11:a (D4), 12:a (D5), 13:a (D6), 14:e (D7) anslut till Arduino digitala stift. Det är inte nödvändigt att använda samma stift som mina, du kan ansluta till alla digitala, huvudsaken är att sedan ställa in dem korrekt i skissen.

Min anslutna Arduino, allt jag behöver göra är att ansluta den till datorn via USB och ladda upp skissen.

I skylten kommer vi att använda en skiss från standarduppsättningen.

I Arduino IDE väljer vi "Fil" -"Sampler" -"Flytande kristall" - "Hej världen".

Låt oss titta på skisskoden.

I kö "Liquid Crystal lcd", inom parentes, är de digitala stiften som används på Arduino. Pins visas i följande ordning: RS, E, DB4, DB5, DB6, DB7. Om du använde andra digitala stift när du ansluter bildskärmen, ange dem i rätt ordning inom parentes.

I kö "lcd.print("hej världen!");" en hälsning visas på displayen, som standard är detta inskriptionen "Hej världen!", du kan ändra det till något eget, skriver vi på latin.

Vi laddar upp skissen till Arduino och här är resultatet. Istället för "hej världen!" Jag gick in på min hemsida. Raden nedan räknar timern ner tiden.

Varje radioamatör kommer efter ett visst antal enkla hemgjorda projekt till målet att konstruera något grandiost med hjälp av sensorer och knappar. Det är trots allt mycket mer intressant att visa data på en bildskärm snarare än på en portmonitor. Men då uppstår frågan: vilken display ska man välja? Och i allmänhet, hur man ansluter det, vad behövs för att ansluta? Svaren på dessa frågor kommer att diskuteras i den här artikeln.

LCD 1602

Bland de många visningsalternativen vill jag specifikt nämna LCD1602-skärmen baserad på HD4478-kontrollern. Denna display finns i två färger: vita bokstäver på blå bakgrund, svarta bokstäver på gul bakgrund. Att ansluta LCD 1602 till Arduino kommer inte heller att orsaka några problem, eftersom det finns ett inbyggt bibliotek och det finns inget behov av att ladda ner något ytterligare. Skärmarna skiljer sig inte bara i pris utan också i storlek. Radioamatörer använder ofta 16 x 2, det vill säga 2 rader med 16 tecken. Men det finns också 20 x 4, där det finns 4 rader med 20 tecken. Mått och färg spelar ingen roll för att ansluta lcd 1602-skärmen till Arduno, de är anslutna på samma sätt. Betraktningsvinkeln är 35 grader, skärmens svarstid är 250 ms. Den kan fungera vid temperaturer från -20 till 70 grader Celsius. Under drift använder den 4 mA för skärmen och 120 mA för bakgrundsbelysningen.

Var används den?

Denna display är populär inte bara bland radioamatörer utan även bland stora tillverkare. Till exempel använder även skrivare och kaffemaskiner LCD1602. Detta beror på dess låga pris; denna skärm kostar 200-300 rubel på kinesiska webbplatser. Det är värt att köpa där, eftersom priset för denna display är mycket högt i våra butiker.

Ansluter till Arduino

Att ansluta LCD 1602 till Arduino Nano och Uno är inte annorlunda. Du kan arbeta med displayen i två lägen: 4 bitar och 8. När du arbetar med 8-bitar används både lågordningens och högordningens bitar och med 4-bitars endast de lågordnade. Det finns ingen speciell mening med att arbeta med 8-bitar, eftersom det kommer att lägga till ytterligare 4 kontakter för anslutning, vilket inte är tillrådligt, eftersom hastigheten inte kommer att vara högre, gränsen för skärmuppdateringar är 10 gånger per sekund. I allmänhet, för att ansluta lcd 1602 till Arduino, används många kablar, vilket orsakar en del besvär, men det finns speciella sköldar, men mer om det senare. Bilden visar anslutningen av skärmen till Arduino Uno:

Exempelkod:

#omfatta // Lägg till det nödvändiga LiquidCrystal-biblioteket lcd(7, 6, 5, 4, 3, 2); // (RS, E, DB4, DB5, DB6, DB7) void setup())( lcd.begin(16, 2); // Ställ in skärmstorleken lcd.setCursor(0, 0); // Ställ in markören till början 1 rader lcd.print("Hej världen!"); // Mata ut texten lcd.setCursor(0, 1); // Ställ markören till början av rad 2 lcd.print("site") ; // Mata ut texten ) void loop ()( )

Vad gör koden? Det första steget är att ansluta biblioteket för att arbeta med displayen. Som nämnts ovan är detta bibliotek redan inkluderat i Arduino IDE och behöver inte laddas ner och installeras ytterligare. Därefter bestäms kontakterna som är anslutna till stiften: RS, E, DB4, DB5, DB6, DB7, respektive. Sedan ställs skärmstorleken in. Eftersom vi arbetar med en version med 16 tecken och 2 rader skriver vi följande värden. Vi placerar markören i början av den första raden och visar vår första text Hello World. Placera sedan markören på den andra raden och visa namnet på webbplatsen. Det är allt! Att ansluta lcd 1602 till Arduino Uno övervägdes.

Vad är I2C och varför behövs det?

Som nämnts ovan tar det många kontakter att ansluta skärmen. Till exempel, när du arbetar med flera sensorer och en LCD-skärm, kanske 1602 stift helt enkelt inte räcker. Radioamatörer använder ofta Uno- eller Nano-versionerna, som inte har många kontakter. Sedan kom folk på speciella sköldar. Till exempel I2C. Den låter dig ansluta en skärm med endast 4 stift. Detta är dubbelt så mycket. I2C-modulen säljs både separat, där du behöver löda den själv, och redan lödd till LCD 1602-skärmen.

Anslutning med I2C-modul

Att ansluta LCD 1602 till Arduino Nano med I2C tar lite plats, bara 4 stift: jord, ström och 2 datautgångar. Vi kopplar ström och jord till 5V respektive GND på Arduino. Vi ansluter de återstående två kontakterna: SCL och SDA till alla analoga stift. På bilden kan du se ett exempel på att ansluta en lcd 1602 till en arduino med en I2C-modul:

Programkod

Om det var nödvändigt att bara använda ett bibliotek för att arbeta med en display utan en modul, behöver du två bibliotek för att arbeta med en modul. En av dem ingår redan i Arduino IDE - Wire. Ett annat bibliotek, LiquidCrystal I2C, måste laddas ner separat och installeras. För att installera biblioteket i Arduino måste innehållet i det nedladdade arkivet laddas in i rotbiblioteksmappen. Exempel på programkod som använder I2C:

#omfatta #omfatta LiquidCrystal_I2C lcd(0x27,16,2); // Ställ in displayens void setup() ( lcd.init(); lcd.backlight(); // Slå på displayens bakgrundsbelysning lcd..setCursor(8, 1); lcd.print("LCD 1602"); ) void loop( ) ( // Ställ markören på den andra raden och nolltecknet. lcd.setCursor(0, 1); // Visa antalet sekunder sedan Arduino startade lcd.print(millis()/1000); )

Som du kan se är koden nästan densamma.

Hur lägger man till sin egen symbol?

Problemet med dessa skärmar är att det inte finns något stöd för kyrilliska alfabet och symboler. Till exempel måste du ladda någon symbol i displayen så att den kan reflektera den. För att göra detta låter displayen dig skapa upp till 7 av dina egna symboler. Föreställ dig bordet:

0 0 0 1 0
0 0 0 0 1
1 1 0 0 1
0 0 0 0 1
1 1 0 0 1
0 0 0 0 1
0 0 0 1 0
0 0 0 0 0

Om 0 - det finns inget där, om 1 - är detta ett målat område. I exemplet ovan kan du se skapandet av symbolen "leende smiley". Med ett exempelprogram i Arduino skulle det se ut så här:

#omfatta #omfatta // Lägg till det nödvändiga biblioteket // Bitmask för leendesymbolen byte smile = ( B00010, B00001, B11001, B00001, B11001, B00001, B00010, ); LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // (RS, E, DB4, DB5, DB6, DB7) void setup())( lcd.begin(16, 2); // Ställ in skärmstorleken lcd.createChar(1, smile); // Skapa teckennummer 1 lcd.setCursor(0, 0); // Ställ markören till början av rad 1 lcd.print("\1"); // Visa en smiley (tecken nummer 1) - "\1" ) void loop ())( )

Som du kan se skapades en bitmask på samma sätt som tabellen. När den väl har skapats kan den visas som en variabel på displayen. Kom ihåg att du bara kan lagra 7 tecken i minnet. I princip räcker detta. Till exempel om du behöver visa en gradsymbol.

Problem där displayen kanske inte fungerar

Det finns tillfällen då displayen inte fungerar. Till exempel slås den på, men visar inga tecken. Eller så tänds den inte alls. Kontrollera först om du har anslutit stiften korrekt. Om du använde en LCD 1202-anslutning till Arduino utan I2C är det väldigt lätt att trassla in sig i ledningarna, vilket kan göra att displayen inte fungerar korrekt. Du bör också se till att skärmens kontrast ökas, eftersom det med minimal kontrast inte ens syns om LCD 1602 är påslagen eller inte. Om detta inte hjälper, så kanske problemet ligger i lödningen av kontakterna, detta är när man använder en I2C-modul. En annan vanlig orsak till att skärmen kanske inte fungerar är felaktig inställning av I2C-adressen. Faktum är att det finns många tillverkare, och de kan lägga en annan adress, du måste korrigera det här:

LiquidCrystal_I2C lcd(0x27,16,2);

Inom parentes kan du se två värden, 0x27 och 16.2 (16.2 är skärmstorleken och 0x27 är I2C-adressen). Istället för dessa värden kan du prova att ställa in 0x37 eller 0x3F. Tja, en annan anledning är helt enkelt en felaktig LCD 1602. Med tanke på att nästan allt för Arduino är tillverkat i Kina kan du inte vara 100% säker på att den köpta produkten inte är defekt.

För- och nackdelar med LCD 1602

Låt oss titta på för- och nackdelarna med LCD 1602-skärmen.

  • Pris. Denna modul kan köpas till ett mycket överkomligt pris i kinesiska butiker. Priset är 200-300 rubel. Ibland säljs den till och med tillsammans med en I2C-modul.
  • Lätt att ansluta. Förmodligen är det ingen som ansluter LCD 1602 utan I2C nuförtiden. Och med denna modul tar anslutningen bara 4 kontakter, det kommer inte att finnas några "nät" av ledningar.
  • Programmering. Tack vare färdiga bibliotek är det enkelt att arbeta med denna modul; alla funktioner är redan skrivna. Och om du behöver lägga till din egen symbol tar det bara ett par minuter.
  • Under användningen av tusentals radioamatörer har inga större nackdelar identifierats, bara det finns fall av defekta köp, eftersom kinesiska versioner av displayer huvudsakligen används.

Den här artikeln tittade på att ansluta 1602 till Arduino och gav också exempel på program för att arbeta med den här skärmen. Det är verkligen en av de bästa i sin kategori; det är inte för inte som tusentals radioamatörer väljer det för sina projekt!

Det blev så att jag köpte något till mig själv här för skojs skull LCD visa två rader med åtta tecken. Han låg i en låda, men något slog mig och jag bestämde mig för att använda honom och samtidigt engagera mig i hans arbete. Hur man ansluter till AVR LCD Jag ska berätta om displayen nu.

Till att börja med gör jag en reservation direkt som vi kommer att prata om LCD indikatorer på styrenheten HD44780, som har blivit de facto industristandard på marknaden för alfanumeriska displayer. Det säljs där det är möjligt, är billigt (8x2 kostar mig cirka 150 rubel), och det finns också massor av kod skriven för den. Jag bestämde mig som vanligt för att uppfinna hjulet på nytt och bygga ett eget bibliotek för att arbeta med den här typen av indikatorer. Naturligtvis i assembler, men vad mer? ;)

Förbindelse.
LCD på basen HD44780 ansluter till AVR mikrokontroller direkt till portarna. Det finns två anslutningsmetoder - 8 bitar och 4 bitar. I åttabitarsläge är det lite lättare att ladda upp byte - du behöver inte flytta en byte, men i fyrabitarsläge behöver du spendera så många som fyra färre kontrollerben. Det finns ytterligare en funktion för att arbeta i 8-bitars läge - den här skärmen kan anslutas till vissa kontroller som externt RAM och skicka data med enkla vidarebefordrankommandon. Personligen kopplade jag den i fullt portläge; jag hade ingenstans att placera en av terminalerna, så det är inte synd.

  • Slutsatser DB7…DB0 Detta är data-/adressbussen.
  • E- stroboskopingång. Genom att rycka på spänningen på denna linje låter vi displayen veta att den behöver ta emot/sända data från/till databussen.
  • RW— bestämmer i vilken riktning vår data rör sig. Om 1, läs sedan från displayen, om 0, skriv sedan till displayen.
  • R.S.— bestämmer vad som sänds, ett kommando (RS=0) eller data (RS=1). Data kommer att skrivas till minnet på den aktuella adressen, och kommandot kommer att utföras av styrenheten.

På kraftsidan är saker och ting ännu enklare:

  • GND– minus, det är vanligt.
  • Vcc- plus strömförsörjning, vanligtvis 5V
  • V0— kontrastingång. Här måste du lägga på en spänning från noll till matningsspänningen och därigenom ställa in bildkontrasten. Du kan installera ett variabelt motstånd som slås på av en potentiometer och vrida det så mycket du vill. Det viktigaste är att fånga det maximala kontrastvärdet, men så att bekantheten (en grå gloria av rutor runt symbolen) inte syns. Om du ställer in kontrasten för lågt kommer karaktärerna att växla lätt och eftertänksamt. Ungefär som en miniräknare vars batterier är slut.
  • A— detta är ingången för LED-bakgrundsbelysningsanoden. Kort sagt, ett plus.
  • TILL- följaktligen katoden, även känd som minus. Bakgrundsbelysningen drar ungefär 100mA och därför behöver du installera ett 100 Ohm strömbegränsande motstånd där. Förresten, många LCD-skärmar har fläckar på kortet för lödmotstånd. Om du ringer kan du se till att dessa linjer leder till LCD-strömingångarna, därför, genom att löda in motstånd, behöver du inte bry dig om att driva bakgrundsbelysningen, den kommer att anslutas till styrenhetens strömförsörjning.
Logisk struktur för HD44780 LCD-kontrollern

Regulatorn har en egen styrenhet som behandlar kommandon och minne. Den är uppdelad i tre typer:

DDRAM- displayminne. Allt som är inspelat i DDRAM kommer att visas på skärmen. Det vill säga att vi till exempel skrev koden där 0x31- en symbol dyker upp på skärmen "1" därför att 0x31 detta är ASCII-koden för siffran 1. Men det finns en egenhet här - DDRAM Minnet är mycket större än det synliga området på skärmen. Vanligtvis, DDRAM innehåller 80 celler- 40 på den första raden och 40 på den andra, och displayen kan röra sig längs denna linje som ett fönster på en linjal och markerar det synliga området. Det vill säga att man till exempel kan lägga in den DDRAM fem menyalternativ på en gång, och sedan är det bara att flytta displayen fram och tillbaka och visa en post i taget. Det finns ett speciellt kommando för att flytta displayen. Det finns också konceptet med en markör - det här är platsen där nästa tecken kommer att skrivas, d.v.s. aktuellt värde på adressräknaren. Markören behöver inte vara på skärmen, den kan placeras bakom skärmen eller inaktiveras helt.

CGROM- symboltabell. När vi skriver till en cell DDRAM byte, sedan tas ett tecken från tabellen och ritas på skärmen. CGROM kan inte ändras, så det är viktigt att den har ryska bokstäver ombord. Om, naturligtvis, ett ryskspråkigt gränssnitt planeras.

CGRAM- även en symboltabell, men vi kan ändra den genom att skapa våra egna symboler. Det adresseras linjärt, det vill säga först finns det 8 byte av ett tecken, rad för rad, från botten till toppen - en bit är lika med en punkt på skärmen. Sedan den andra symbolen på samma sätt. Eftersom vår förtrogenhet är 5 gånger 8 poäng, alltså de viktigaste tre bitarna spelar ingen roll. Totalt in CGRAM kan bestå av 8 tecken CGRAM Det har 64 byte minne. Dessa programmerbara tecken har koder från 0x00 till 0x07. Så, efter att ha kastat in till exempel den första 8 byte CGRAM(det första tecknet med koden 00) något slags skräp, och skriva in det DDRAM noll (koden för det första tecknet i CGRAM) kommer vi att se vår skit på skärmen.

Minnesåtkomst.
Allt är enkelt här. Vi använder ett kommando för att välja vilket minne och med utgångspunkt från vilken adress vi ska skriva. Och sedan är det bara att skicka byten. Om det indikeras att vi skriver till DDRAM, kommer tecknen att visas på skärmen (eller i ett dolt område), om i CGRAM, kommer byten redan att visas i teckengeneratorns minne. Det viktigaste är att inte glömma att byta tillbaka till området DDRAM

Kommandosystem.
Kommandosystemet är så enkelt som ett moo. Benet kommer att indikera att ett kommando skickas till displaykontrollern. R.S.=0. Själva kommandot består av den mest signifikanta biten, som bestämmer vad detta kommando är ansvarigt för, och parameterbitar, som talar om för HD44780-styrenheten hur den ska gå vidare.

Kommandotabell:

DB7DB6DB5DB4DB3DB2DB1DB0Menande
0 0 0 0 0 0 0 1 Rengöring av skärmen. Adressräknare vid position 0 i DDRAM
0 0 0 0 0 0 1 Adressering till DDRAM-återställning skiftar, adressräknaren till 0
0 0 0 0 0 1 I/DSInställning av skärm och markörförskjutning
0 0 0 0 1 DCBStälla in visningsläge
0 0 0 1 S/CR/LSkift markör eller skärm, beroende på bitar
0 0 1 D.L.NFVälja antal rader, bussbredd och teckenstorlek
0 1 A.G.A.G.A.G.A.G.A.G.A.G.Byt adressering till SGRAM och ställ in adress i SGRAM
1 ADADADADADADADByt adressering till DDRAM och ställ in adressen till DDRAM

Nu ska jag förklara vad de enskilda bitarna betyder:
  • I/D— ökning eller minskning av adressräknaren. Standardvärdet är 0 - Minska. De där. varje efterföljande byte kommer att skrivas till n-1 celler. Om du sätter 1 kommer det att bli en ökning.
  • S— skärmförskjutning, om du ställer in den på 1, så kommer skärmfönstret att flyttas för varje nytt tecken tills det når slutet av DDRAM, det kommer förmodligen att vara bekvämt när du visar en rejäl rad på skärmen, för alla 40 tecken, så att den inte rinner av skärmen.
  • D— slå på displayen. Om du sätter 0 där försvinner bilden, och vid den här tiden kan vi göra alla möjliga obscena saker i videominnet och de kommer inte att vara ett öga. Och för att bilden ska visas i denna position måste du skriva 1.
  • MED— slå på markören i form av ett streck. Det är enkelt, skriv 1 här - markören slås på.
  • B— få markören att se ut som en blinkande svart fyrkant.
  • S/C flytta markören eller skärmen. Om det är 0, flyttas markören. Om 1, skärm. En gång per lag
  • R/L— bestämmer riktningen för markörens och skärmens förskjutning. 0 - vänster, 1 - höger.
  • D/L— en bit som bestämmer databussens bredd. 1-8 bitar, 0-4 bitar
  • N— antal rader. 0 - en rad, 1 - två rader.
  • F— symbolstorlek 0 — 5x8 pixlar. 1 - 5x10 poäng (extremt sällsynt)
  • A.G.- adress i minnet CGRAM
  • AD- adress i minnet DDRAM

Själv stirrade jag länge på den här skylten och försökte förstå vad de ville ha av mig. Tydligen var han sömnlös, men det är faktiskt inte uppenbart vid första anblicken, så jag ska backa upp det med ett exempel.

Uppgift:

  1. Slå på displayen.
  2. Rensa innehållet.
  3. Flytta markören en position.
  4. Och skriv "1" där.
Lösning (kommandosekvens):

Först Initialisering skärm utan vilken de flesta skärmar på HD44780 helt enkelt vägrar att fungera. Vissa typer har ett standardläge (8-bitars buss, markören vid 0) och de behöver bara slå på displayen. Men det är fortfarande bättre att göra det, du vet aldrig vad utvecklaren har gjort. Det blir inget extra.

  1. 001 11000 Buss 8 bitar, 2 linjer
  2. 00000001 Rengöring av skärmen
  3. 000001 10 Adressökning. Skärmen rör sig inte
  1. 00001 100 Display påslagen (D=1)
  2. 00000001 Rensade displayen. Pekaren är på DDRAM
  3. 0001 0100 Flyttade markören (S/C=0) åt höger (R/L=1)
  4. 00110001 - vi har redan registrerat data (RS pin = 1) kod "1" 0x31

Lagidentifieraren är markerad med fet stil, men resten ser du i tabellen.

Uppgift: skapa din egen symbol. Med kod 01 och visa den på skärmen.
Vi tror att vår display redan har initierats och är redo att ta emot data.

Lösning:

  1. 01 001000 Välj in CGRAM adress 0x08 är bara början på det andra tecknet (låt mig påminna dig om att ett tecken tar 8 byte)
  2. 00000001 Detta är 8 byte data. ( RS=1)
  3. 0000001 0 Rita en blixtikon, eller
  4. 000001 00 SS Zig runa, som du vill
  5. 00001 Jag gillar 000 bättre.
  6. 00011111 De mest signifikanta tre bitarna har ingen effekt
  7. 0000001 0 Du kan skriva vad som helst där, på
  8. 000001 00 påverkar inte resultatet.
  9. 00001 000 Sista byten med data
  10. 1 0000000 Och detta är ett kommando - växla adressen till DDRAM och en pekare till adressen 0000000 — det första tecknet i första raden.
  11. 00000001 Och återigen data ( RS=1), kod 01 - det är här vi lägger vår dragkedja.
Oj och han är på skärmen!

Så vi har löst logiken, det är dags att fördjupa sig i kommunikationsprotokollets fysik. Jag kommer att tillhandahålla koden lite senare, när jag rengör mitt bibliotek och optimerar det till perfektion. För nu kommer jag att ge dig algoritmen, och den kan implementeras i vilket programmeringsspråk som helst. Åtminstone i assembler, åtminstone i Syah, och till och med i Vasik :)

Algoritm för att läsa/skriva till LCD-kontroller HD44780
Riktningen, liksom kommandot/data, bestäms av benen, och läsning och skrivning utförs genom övergången av stroben (stift E) från 1 till 0

Initiering av portar

  1. RS, RW, E - för att lämna läget.
  2. DB7..DB0 till inmatningsläge. Du behöver dock inte röra dem, vi kommer att omdefiniera dem senare.

Väntar på beredskap, läser upptagen flagga.
  1. RS=0 (kommando)
  2. RW=1 (läs)
  3. E=1 (Gör dig redo!!!)
  4. Paus (14 processorcykler vid 8 MHz räckte)
  5. E=0 (Pli!)
  6. Läser från hamnen. Om bit 7 (upptagen flagga) är inställd, upprepar vi allt igen tills det återställs.

Skriv ett kommando
  1. Väntar på beredskap
  2. RS=0 (kommando)
  3. RW=0 (skriv)
  4. E=1 (Gör dig redo!!!)
  5. Utgångsport
  6. Mata ut kommandokoden till porten
  7. Paus
  8. E=0 (Pli!)
  9. Axelpistol Port för inträde, för säkerhets skull.

Dataregistrering
  1. Väntar på beredskap
  2. RS=1 (Data)
  3. RW=0 (skriv)
  4. E=1 (Gör dig redo!!!)
  5. Utgångsport
  6. Mata ut kommandokoden till porten
  7. Paus
  8. E=0 (Pli!)
  9. Port för inträde, för säkerhets skull.

Läs kommando
  1. Väntar på beredskap
  2. Dataport till ingång med pull-up (DDR=0, PORT=1)
  3. RS=0 (kommando)
  4. RW=1 (läs)
  5. Paus
  6. Läser data från porten
  7. E=0 (Att!)

Läs data
  1. Väntar på beredskap
  2. Dataport till ingång med pull-up (DDR=0, PORT=1)
  3. RS=1 (Data)
  4. RW=1 (läs)
  5. E = 1 (Gör dig redo! För närvarande skickas data från LCD-skärmen till bussen)
  6. Paus
  7. Läser data från porten
  8. E=0 (Att!)

Med en fyra-bitars buss är allt exakt sig likt, bara där görs varje läs/skrivoperation i två strobe-drag.

Inträde:

  1. Paus
  2. De satte senioranteckningsboken i hamnen
  3. Paus
  4. Paus
  5. Junior-tetrad togs till hamnen

Läsning
  1. Paus
  2. Läser senioranteckningsboken från hamnen
  3. Paus
  4. Paus
  5. Läser den låga tetraden från hamnen

Vänta på koden :) Kommer snart :)
UPD:

Vad är en integrerad del av ett stort antal elektroniska enheter? Naturligtvis sätt för indikation och grafisk utdata av data. Det är alltid bekvämare och trevligare för användaren när resultatet av "smartboxen" kan ses visuellt. Därför kommer vi idag att ansluta en display till STM32 för att visa text och siffror. Hjälten i våra experiment kommer att vara en ganska populär display från Winstar. Ett viktigt förtydligande framkom förresten i kommentarerna att metodiken i princip är densamma för alla skärmar utifrån HD44780. Tack till JekaKey för det viktiga tillägget)

Först måste displayen anslutas till styrenheten. Ladda ner databladet och leta efter WH1602 pinout. Titta här:

Som du vet, display WH1602 har 16 stift. Låt oss titta på var och en separat...

Pins Vss, Vdd och K måste anslutas till jord och ström, det vill säga precis som anges i tabellen, det finns inga överraskningar och inget att diskutera)

Stift nummer 3 används för att justera kontrasten - om vi applicerar +5V där ser vi absolut ingenting, och om vi kortsluter stiftet till jord kommer vi att beundra två rader med svarta rutor 😉 Det här passar oss naturligtvis inte , så vi måste hänga en potentiometer (motstånd) där med variabelt motstånd) för att justera kontrasten. Bästa synlighet av tecken tillhandahålls av en spänning på 0,5-0,7 V vid denna displaystift.

RS-stiftet är redan ett stift som vi själva kommer att styra med hjälp av en mikrokontroller. En låg spänningsnivå (0) på detta stift betyder att ett kommando nu följer, en hög nivå (1) betyder att det nu kommer att finnas data som ska skrivas till displayminnet.

Pin R/W - det är tydligt här, antingen läser vi data (visa upptagen flagga, till exempel), i det här fallet finns det 1 på denna pin, eller så skriver vi kommandot/data till displayen, då har vi 0 här.

DB7 – DB0 – databuss, och det säger allt)

Stift E är den så kallade Enable-signalen. Det är vad han behövs för. För att arbeta med displayen - registrera data eller utfärda ett kommando - måste vi ge en positiv puls till denna stift. Det vill säga, proceduren kommer att se ut så här:

  1. På stift RS, R/W, DB7 - DB0 - de nödvändiga signalerna som motsvarar vårt kommando.
  2. Vi levererar en till stift E.
  3. Zhdems (enligt databladet - minst 150 ns)
  4. Vi tillämpar en låg nivå (0) på stift E.

Du måste sätta 4,2 V på A/Vee-benet för att driva skärmens bakgrundsbelysning.

Så här sker kommunikation med WH1602-skärmen.

Vi har listat ut att ansluta WH1602, men innan vi går vidare till exemplet, låt oss titta på vilka kommandon vår display i allmänhet förstår. För att göra detta går vi in ​​i databladet och hittar en intressant tabell:

Alla kommandon och signaler som ska finnas på motsvarande stift på WH1602 för varje specifikt kommando beskrivs här. Vi vill till exempel rensa displayen, vi tittar på tabellen och här är kommandot vi behöver! Rensa display!

Vi tillämpar nollor på stiften RS, R/W, DB7, DB6, DB5, DB4, DB3, DB2, DB1 och en till stift DB0. Klart! Vad händer härnäst? Det stämmer, en på stift E, vänta sedan ett tag och sänk E till noll igen. Det är allt, displayen rensas 😉 Precis innan du kör nästa kommando måste du pausa, vilket anges i databladet för varje kommando. Det skulle vara mer effektivt att polla upptagetflaggan; så snart den återställs till 0 kan du fortsätta arbeta. Det finns också ett speciellt kommando för att läsa denna flagga, så allt är klart med denna) Låt oss gå vidare...

Och i själva verket är allt med teorin, du kan redan försöka skriva något. För att göra det enklare att arbeta med displayen gjorde jag ett litet bibliotek, nu ska vi se hur det kan användas. Först, ladda ner

Vi får 2 filer till vårt förfogande, MT_WH1602.c och MT_WH1602.h. Vi river av den andra, här måste vi välja stiften och den styrenhet som används.

Förresten, min skärm är ansluten så här:

RS-PC2
R/W – PB10
E–PB14
DB7–PD2
DB6–PC12
DB5–PA8
DB4–PA10
DB3–PA15
DB2–PD11
DB1–PA3
DB0–PA5

Öppna filen MT_WH1602.h:

#define PLATTFORM (STM32F10x)

Välj sedan mikrokontrollerstiften som skärmen är ansluten till. Låt oss bara först ställa in vilka portar vi använder. När jag ansluter använder jag GPIOA, GPIOB, GPIOC och GPIOD, vi skriver:

På samma sätt för andra mikrokontrollerben.

Vi är klara med installationen, låt oss fortsätta) För att anropa kommandona som ges i början av artikeln, innehåller filen MT_WH1602.c följande funktioner (de är namngivna efter namnen på kommandona, så jag tror att allt är klart) :

void MT_WH1602_ClearDisplay(void ) ; void MT_WH1602_ReturnHome(void ) ; void MT_WH1602_EntryModeSet (bool ID-adress, bool shift) ; void MT_WH1602_DisplayOnOff (bool Dbit, bool Cbit, bool Bbit); void MT_WH1602_CursorOrDisplayShift (bool SCbit, bool RLbit) ; void MT_WH1602_FunctionSet (bool DLbit, bool Nbit, bool Fbit); void MT_WH1602_SetCGRAMAddress (uint8_t-adress) ; void MT_WH1602_SetDDRAMAddress (uint8_t-adress) ; bool MT_WH1602_ReadBusy(void) ; void MT_WH1602_WriteData(uint8_t data) ;

För vissa kommandon måste vi skicka parametrar till funktionen, till exempel:

void MT_WH1602_DisplayOnOff (bool Dbit, bool Cbit, bool Bbit);

Låt oss titta på kommandotabellen:

Vi ser att kommandot Display ON/OFF inte bara slår på/stänger av displayen, utan även aktiverar/avaktiverar markören och markörblinkningen. I databladet är dessa kommandobitar betecknade som D, C och B, och vi skickar dem som parametrar till funktionen. Om vi ​​behöver slå på displayen och markören, men inaktivera markörblinkningen, anropar vi kommandot enligt följande:

MT_WH1602_DisplayOnOff(1, 1, 0);

I allmänhet är allt enkelt 😉

Kort sagt, vi skapar ett nytt projekt, lägger till ett bibliotek för att arbeta med WH1602-skärmen, skapar en tom .c-fil och börjar fylla den med kod:

// Inkludera biblioteksfilen#inkludera "MT_WH1602.h" /*******************************************************************/ int main(void) ( // Ring initieringsfunktionen, vi kan inte klara oss utan den =)() ; // Nu måste vi göra den initiala skärmkonfigurationen // Dokumentation och Internet rekommenderar att du gör detta ;) MT_WH1602_FunctionSet(1, 0, 0); MT_WH1602_Delay(1000 ) ; MT_WH1602_FunctionSet(1, 0, 0); MT_WH1602_Delay(1000 ) ; MT_WH1602_FunctionSet(1, 0, 0); MT_WH1602_Delay(1000 ) ; MT_WH1602_FunctionSet(1, 1, 1); MT_WH1602_Delay(1000 ) ; MT_WH1602_DisplayOnOff(1, 0, 0); MT_WH1602_Delay(1000 ) ; MT_WH1602_ClearDisplay() ; MT_WH1602_Delay(2000) ; // Till exempel tog jag de första fördröjningsvärdena som kom att tänka på) // I allmänhet måste du kontrollera displayens upptagetflagga // Låt oss nu visa något, som namnet på vår webbplats MT_WH1602_WriteData(0x6D) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x69) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x63) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x72) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x6F) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x74) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x65) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x63) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x68) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x6E) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x69) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x63) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x73) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x2E) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x72) ; MT_WH1602_Delay(100) ; MT_WH1602_WriteData(0x75) ; MT_WH1602_Delay(100) ; medan (1 ) ( __NOP() ; ) ) /*******************************************************************/

Klart, låt oss kolla)


Som du kan se fungerar allt korrekt)

Förresten, jag tappade på något sätt frågan om vad jag skulle skriva på displayen för att visa den eller den karaktären. Här är plattan från databladet:

Så för att bestämma vilket värde som ska skrivas in i displayminnet måste du ta siffrorna som är skrivna överst och till vänster i den här tabellen för en specifik symbol. Till exempel symbolen "A". Låt oss se - den här symbolen motsvarar kolumn 0100 (0x4) och rad 0001 (0x1). Det visar sig att för att visa symbolen "A" måste du skriva värdet 0x41 i displayen.

Det var det nu =) Vi har löst anslutningen och driften av WH1602-skärmen, så vi ses snart!

P.S. När jag arbetade med biblioteket testade jag inte funktionen att läsa upptagetflaggan, så om något plötsligt inte fungerar som det ska, skriv så kommer vi att reda ut det)