Jak zobrazit znaky a čísla na Display 1x16 2x16 4x16?
Moderátor: Moderátoři
Jak zobrazit znaky a čísla na Display 1x16 2x16 4x16?
začátkem prosince jsem zakoupil z TME vývojový kit Easy8051 v6 pro procesory Atmel na bázi uP 8051. Umí seriově progamovat pomocí On board programovacího interface procesory, které jsou na to vybavené .. např s-ková řada. Kit obsahuje i 1ks AT89s8253. Na boardu je také alfanumerický LCD display 2x16 znaků, zapojený v "nějakém" 4-bitovém modu. Kdysi jsem psal nějaké programy pro přípravky s 89C51 (ty v něm bohužel naprogramovat nelze), ale se zobrazováním na displayi moc zkušenosti nemám a zde použitý 4-bitový mod mi nic neříká. Na internetu jsem našel pouze Datasheet pro alfanum. LCD display LM 162551 firmy Sharp a i tam je to podáno pro mě nezkušeného dosti těžkopádně. Není zde někdo , kdo má se zobrazováním na display, ať již v normálním nebo oním 4-bitovém modu nějaké zkušenosti a mohl by mi poslat návod nebo nějaký DataSheet z kterého je postup snadno pochopitelný i začátečníkovi, případně příklad v assembleru s komentářem, jak se přistupuje po zběrnici na display a jak se docílí zobrazení požadovaného čísla či znaku. Vím, že display má konektoru Datovou sběrnici, řídící signály RS, W/R, En, ovládání jasu a kontrastu a v sobě má znakovou sadu, ze které se dá znak vybrat a zobrazit na pozici , která se musí nějak někam zadat , že se tam dá zadat i pár uživatelských znaků, ale víc toho nevím.
Za vaše odpovědi předem děkuji a nabízím za poštovné možnost naprogramování procesorů, které tento kit zvládne. Jsem z okolí města Ústí nad Orlicí a zájemcům z regionu to mohu naprogramovat na počkání, když mi dají příslušný HEX soubor.
Návod, Datasheet či příklady mi případně můžete poslat na mail: katanykorado@seznam.cz.
- ZdenekHQ
- Významný člen
- Příspěvky: 25519
- Registrován: 21 črc 2006, 00:00
- Bydliště: skoro Brno
- Kontaktovat uživatele:
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?]
Potom bych rád udělal prodram pro nastavování úhlu natočení pomocí krového motoru .. např. pro solární panel.
Uf, uf, tak teď jsem našel většinu toho, co jsem poteboval:
http://elektronika.kvalitne.cz/ATMEL/ne ... atice.html
Jinak ten dislej je určitě s řadičem HD44780 nebo kompatibilním, jakmile vyhledáš np. "hd44780 programming" do googlu tak najdeš úplně všechno co potřebuješ. Například toto: http://www.8052.com/tutlcd2.php
Případně koupit toto: http://shop.ben.cz/cz/121169-prace-s-in ... i-lcd.aspx
Pokud to myslíš s programováním vážně, tak jsi zvolil správný postup. U assembleru pochopíš co a jak v uC funguje. Ale do ničeho většího než ten displej a jednoduchý np. teploměr bych už v assembleru nešel. Vyznat se pak ve stovkách až tisících řádků kódu, řešit meziskoky a hledat chyby bych už znovu nechtěl dobrovolně podstupovat. Nainstaluj si Keil (jsou pro něho i simulátory alfanum. displeje), kup si toto
http://shop.ben.cz/cz/121280-c-pro-mikr ... 89s52.aspx
http://shop.ben.cz/cz/121320-programova ... yce-c.aspx
a můžeš začít naplno. Sám jsem si to před časem zažil a byl jsem mile překvapen, jak se snadno, rychle a přehledně se dají psát kódy (v porovnání k ASM).
-
petrfilipi
- Příspěvky: 2901
- Registrován: 13 zář 2005, 00:00
mohu-li Ti poradit, zkus se podívat sem: http://www.mikroe.com/mikroc/8051/specification/
Je to celé kompletní vývojové prostředí, můžeš si vybrat jazyk C, Pascal (ten jsem si vybral já, ale pro PICy) nebo Basic. Jsou u toho příklady, můžeš samozřejmě přepnout i do assembleru. Je k tomu vývojová deska - ta už ale něco stojí, SW je pro malé aplikace do asi 2kB zadarmo.
Má to hotové všechny knihovny, tzn. podle příkladu navolíš připojení datových vodičů k displeji, ovládacích vodičů a pak už je příkazem např. LCDOUT (1, 5, "Ahoj") zobrazíš na 1. řádku a 5. sloupci text Ahoj. Chceš-li poslat něco po RS232, tak buď má brouk fyzický RS232 a jen ho nadefinuješ a jedním příkazem to pošleš, nebo použiješ jejich knihovnu a vytvoříš si SW seriový port. Prostě je to hodně zaměřené na praktičnost. Na webu mají hromadu přídavných modulů (displeje LCD a LED, teploměry 18B20, čidla, komunikace, ...). Na webu taky mají už hotové projekty, např. teploměry apod., stačí je jen stáhnout.
Neříkám že nemají v programu chyby, ale obvykle stačí stáhnout novější verzi a je po problému.
Takhle vypadá příklad pro LCD v C pro Atmely (tady je pak odkaz na tento a další příklady:http://www.mikroe.com/downloads/get/2009/mikroc_pro_8051_examples.zip) :
/*
* Project name:
Lcd_Test (Demonstration of the LCD library routines)
* Copyright:
(c) Mikroelektronika, 2009.
* Revision History:
20071210:
- initial release;
* Description:
This code demonstrates how to use LCD 4-bit library. LCD is first
initialized, then some text is written, then the text is moved.
* Test configuration:
MCU: AT89S8253
http://www.atmel.com/dyn/resources/prod ... oc3286.pdf
Dev.Board: Easy8051v6 - ac:LCD
http://www.mikroe.com/easy8051/
Oscillator: External Clock 10.0000 MHz
Ext. Modules: Lcd 2x16
http://www.mikroe.com/store/components/various/#other
SW: mikroC PRO for 8051
http://www.mikroe.com/mikroc/8051/
* NOTES:
- Turn on LCD backlight switch on development board (SW7.6).
*/
// LCD module connections
sbit LCD_RS at P2_0_bit;
sbit LCD_EN at P2_1_bit;
sbit LCD_D4 at P2_2_bit;
sbit LCD_D5 at P2_3_bit;
sbit LCD_D6 at P2_4_bit;
sbit LCD_D7 at P2_5_bit;
// End LCD module connections
char txt1[] = "mikroElektronika";
char txt2[] = "Easy8051v6";
char txt3[] = "Lcd4bit";
char txt4[] = "example";
char i; // Loop variable
void Move_Delay() { // Function used for text moving
Delay_ms(500); // You can change the moving speed here
}
void main(){
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
LCD_Out(1,6,txt3); // Write text in first row
LCD_Out(2,6,txt4); // Write text in second row
Delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR); // Clear display
LCD_Out(1,1,txt1); // Write text in first row
LCD_Out(2,5,txt2); // Write text in second row
Delay_ms(2000);
// Moving text
for(i=0; i<4; i++) { // Move text to the right 4 times
Lcd_Cmd(_LCD_SHIFT_RIGHT);
Move_Delay();
}
while(1) { // Endless loop
for(i=0; i<8; i++) { // Move text to the left 7 times
Lcd_Cmd(_LCD_SHIFT_LEFT);
Move_Delay();
}
for(i=0; i<8; i++) { // Move text to the right 7 times
Lcd_Cmd(_LCD_SHIFT_RIGHT);
Move_Delay();
}
}
}
- monterjirka
- Příspěvky: 2855
- Registrován: 14 čer 2003, 00:00
- Bydliště: Blížejov
Korado píše:... Jinak mě zajímá i normální 8-bitový režim. V diskusích ještě píšou něco o nějakém řadiči HD 44780 .. ten asi bude na desce displaye a ten zpracovává posílané instukce.
Ten řadič je jakýsi standard, pro který existuje SW podpora.
Komunikace procesoru s tímto řadičem byla dost pěkně popsaná k KTE magazínu v seriálu o vývojovém modulu Chipon, tady se to dá najít a stahnout:
http://www.jvproject.cz/KTE.htm
tzeď ještě koupit laserovou tiskárnu, abych si mohl dělat masky pro výrobu plošných spojů pomocí UV lampy a horkovzdušnou pistoli na práci se SMD součástkami a snad se časem rozhýbu po několikaleté pause.
- ZdenekHQ
- Významný člen
- Příspěvky: 25519
- Registrován: 21 črc 2006, 00:00
- Bydliště: skoro Brno
- Kontaktovat uživatele:
Bity 4..7 displeje jsou připojeny na p2.0 až p2.3 , řídící signály jsou Bit_rs (p2.4) a Disp_e (dá se použít libovolný volný pin procesoru)
Kód: Vybrat vše
;============================
; OVLADANI DISPLEJE
;============================
;
;Bit_rs = 0 ... instrukce
;Bit_rs = 1 ... data
;timeout 40us, 2ms pro smazani a nast. kurzoru
Init_disp:
;*********
;init 4-bitova sbernice, 2 radkovy displej
;napred horni byte 0010 xxxx - prepne do 4-bit modu
;potom znovu,ale uz cely 2x4bity
;0000 0001 smaz disp a kurzor na zacatek - 2ms !
;0000 0010 vrat kurzor na zacatek radku - 2ms !
; 1kt Kurzor vlevo/vpravo, posun Text ne/ano
;=================================================
;0000 0110 posun kurz vpravo, text se neposouva
;0000 0111 posun textu vlevo
; 1dcb zapne Diplej Kurzor Blikani
;=====================================
;0000 1111 zapnout disp, kurzor a blikani
;0000 1100 vypni kurzor a jeho blikani
;01aa aaaa - prepnuti na zapis + adresa v CG-ram
;1aaa aaaa - prepnuti na zapis + adresa v DD-ram
;dddd dddd + Bit_rs=1 > zapis dat do CG nebo DD ram
;==================================================
;1001 0000 nastav pozici v ddram na 16 (10000b)
;CG ram - 8 vlastnich znaku zzz= 000 .. 111
;zapis dat do CGRram > 01 zzz sss
; sss je 8 sub-radku znaku po 5 bitech dat
; data jsou xxx11111
;t.j. 8x cykl rs=0+adresa, rs=1+data
;posledni radek je 00000 > misto pro kurzor
;3x znak "sloupec vybuzeni" 1,2,3 carky
;3x znak "znacka" - jen 1 carka v urovni 1.,2.,3. carky
;
;DD ram - diplej, pozice kurzoru
; 1.radek 00h
; 2.radek 40hff
; 3.radek 14h
; 4.radek 54h
;pockam na RESETy
;****************
mov a,#0
setb acc.4 ;r/s
mov p2,a
clr Disp_e
call Wait_1ms
;prepnuti na 4 bity
;******************
mov a,#0010b ;HORNI byte inicializace displej
clr Bit_rs
call Posli_d4 ;pouziva aku
;call Wait_1ms
mov a,#0
clr Bit_rs
call Posli_d4 ;pouziva aku
call Wait_1ms
;znovu init, tentokrat uz 4-bitove
;*********************************
mov Znak,#00101000b ;0010 radky font x x
clr Bit_rs
call Posli_d8 ;pouziva Znak
;smazu displej,nastavim kurzor na zacatek
;****************************************
call Smaz_disp
call Vrat_kz
call Kurz_off
ret
;----------------------------------------------------------------------
Clr_disp:
Smaz_disp:
Smaz_dp:
;*********
mov Znak,#00000001b ;smaz disp a kurzor domu - 2ms !
mov Radek,#1
jmp Pd_ck1
Vrat_kz:
;*******
mov Znak,#00000010b ;vrat kurzor domu - 2ms !
mov Radek,#1
Pd_ck1:
clr Bit_rs
call Posli_d8
call Wait_1ms
call Wait_1ms
ret
Enter_dp: ;skoci na dalsi radek
Dp_enter:
;********
inc Radek
mov a,Radek
cjne a,#5,Edp_2
mov Radek,#1 ;zpatky na prvni
Edp_2:
jmp Radek_dp
Smaz_r234:
;*********
call Smaz_rd2
call Smaz_rd3
call Smaz_rd4
ret
Smaz_rd1:
;*********
mov Radek,#1
jmp Smaz_radek
Smaz_rd2:
;*********
mov Radek,#2
jmp Smaz_radek
Smaz_rd3:
;*********
mov Radek,#3
jmp Smaz_radek
Smaz_rd4:
;********
mov Radek,#4
jmp Smaz_radek
Smaz_radek:
;**********
mov Sloupec,#0
call Radek_dp
mov r2,#20
Smz_1:
mov Znak,#' '
call Zapis_dp
djnz r2,Smz_1
ret
Radek_r1:
;*******
mov Radek,#1
;mov Sloupec,#0
jmp Radek_dp
Radek_r2:
;*******
mov Radek,#2
;mov Sloupec,#0
jmp Radek_dp
Radek_r3:
;*******
mov Radek,#3
;mov Sloupec,#0
jmp Radek_dp
Radek_r4:
;*******
mov Radek,#4
;mov Sloupec,#0
jmp Radek_dp
Radek_dp: ;skoci na patricny radek
;*******
mov a,Radek ;1..4
cjne a,#1,Rdp_1
clr a
push acc
jmp Rdp_5
Rdp_1:
cjne a,#2,Rdp_2
mov a,#40h ;00,40,10,50 pro 16x4
push acc
jmp Rdp_5 ;00,40,14,54 pro 20x4
Rdp_2:
cjne a,#3,Rdp_3
mov a,#14h
push acc
jmp Rdp_5
Rdp_3:
cjne a,#4,Rdp_5
mov a,#54h
push acc
jmp Rdp_5
Rdp_5:
;v push acc je adresa
;*********************
pop acc
add a,Sloupec
orl a,#10000000b ;1aaaaaaa
mov Znak,a
mov Sloupec,#0
jmp Pd_ck2
Shift_l:
mov Znak,#00000101b ;posun vlevo + shift
jmp Pd_ck2 ; 00000 1 Incr/Decr Shift
No_shift:
Posun_dp:
;********
mov Znak,#00000110b ;posun kurzoru vpravo,no shift
jmp Pd_ck2 ; 00000 1 Incr/Decr Shift
Kurz_off:
;********
mov Znak,#00001100b ;vypne kurzor
jmp Pd_ck2
Kurz_on:
;********
mov Znak,#00001111b ;zapne kurzor
jmp Pd_ck2
Pd_ck2: ;0000 1 D C B
;======
clr Bit_rs ;D = disp on/off, Cursor, Blink
call Posli_d8
ret
Kp_on:
;*****
mov Znak,#00001110b ;zapne kurzor bey blikani 0000 1 D C B
clr Bit_rs ;D = disp on/off, Cursor, Blink
call Posli_d8
ret
Zapis_mez:
Posli_mez:
Dp_mez:
;*********
;posle mezeru
mov Znak,#' '
jmp Zapis_dp
Dp_car:
Dp_carka:
;*********
;posle carku
mov Znak,#','
jmp Zapis_dp
Dp_dvoj:
Posli_dvojt:
;*********
;posle dvojtecku
mov Znak,#':'
jmp Zapis_dp
Posli_h:
;*******
;posle h
mov Znak,#'h'
jmp Zapis_dp
Posli_v:
;*******
;posle h
mov Znak,#'V'
jmp Zapis_dp
Zapis_dp:
Posli_dp:
Dp_znak:
;********
;znak je v promenne Znak
push acc
setb Bit_rs
call Posli_d8
pop acc
ret
Dp_text:
;*******
;posle text na displej, adresa v DPTR, ukonceni ~ nebo $
mov Pom,#0
Dpt_1:
clr a
movc a,@a+dptr
cjne a,#'~',Dpt_2
;nacten koncovy znak
inc dptr
ret
Dpt_2:
cjne a,#'$',Dpt_3
;poslat DP_ENTER
call Dp_enter
jmp Dpt_4
Dpt_3:
mov Znak,a
call Zapis_dp
Dpt_4:
inc Pom
inc dptr
;kontrola delky
mov a,Pom
cjne a,#Poc_znd,Dpt_1 ;MAX pocet znaku displeje
inc dptr
ret
;=============================
;=== ZAPIS DAT DO DISPLEJE ===
;=============================
Posli_d8:
;*******
;posle Znak 8 bitu na displej
;nejprve horni byte
;******************
mov a,Znak
swap a
call Posli_df
;dolni byte
;**********
mov a,Znak
call Posli_df
;cekaci smycka
;*************
mov r7,#Wait_disp ;doba,nez to pochopi
Pdp_w3:
djnz r7,Pdp_w3
ret
Posli_d4:
;********
;posle 4 bity dat ulozenych v aku + Bit_rs
;pomalejsi varianta, ceka po kazdem pulbyte
orl a,#11110000b ;horni 4bity nepouzivam
;rl a
mov c,Bit_rs
mov acc.4,c
mov p2,a
setb Disp_e ;max. clk=250khz
;zapis sestupnou hranou
call Wait_5us
clr Disp_e
mov r7,#Wait_disp ;doba,nez to pochopi
Pdp_w:
djnz r7,Pdp_w
mov p2,#0ffh
ret
Posli_df:
;********
;posle 4 bity dat ulozenych v aku + Bit_rs
;zrychlena varianta bez cekaci smycky
orl a,#11110000b ;horni 4bity nepouzivam
;rl a
mov c,Bit_rs
mov acc.4,c
mov p2,a
setb Disp_e ;max. clk=250khz
;zapis sestupnou hranou
call Wait_5us
clr Disp_e
;cekaci smycku musi generovat nadrazeny proces !
mov p2,#0ffh
ret
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?]
Kód: Vybrat vše
;**********************************************
;* *
;* test displeje *
;* *
;**********************************************
E_LCD Bit P3.1 ;vybavovaci vystup pro LCD
RS_LCD Bit P3.0 ;data nebo instrukce
RW_LCD bit p3.3
;********************************
; Zacatek programu OK
;********************************
ORG 0H
Start:
call Init ;inicializace LCD
mov A,#0C0H ;nastaveni 2. radku LCD
call LCD_W_INST
mov DPTR,#Uvod1 ;adresa tabulky Uvod1
rpokr1:
CLR A
movc A,@A+DPTR ;nacti byte z tabulky
cjne A,#'`',Ok1 ;test znaku konec reklamy
jmp TEnd1
Ok1:
inc DPTR ;dalsi byte tabulky
call LCD_W_DATA ;zapis A do LCD
jmp RPOKR1 ;pokracuj
Tend1:
mov A,#80H ;nastaveni 1. radku LCD
call LCD_W_INST
mov DPTR,#Uvod2 ;adresa tabulky Uvod1
rpokr2:
CLR A
movc A,@A+DPTR ;nacti byte z tabulky
cjne A,#'`',Ok1 ;test znaku konec reklamy
jmp TEnd2
Ok2:
inc DPTR ;dalsi byte tabulky
call LCD_W_DATA ;zapis A do LCD
jmp RPOKR2 ;pokracuj
Tend2:
;********************************
jmp $ ;cekej
;********************************
BUSY:
CLR E_LCD ;LCD DISABLE
MOV P1,#0FFH
CLR RS_LCD ;INSTRUKCE
SETB RW_LCD ;CTI STAV
NOP
NOP
SETB E_LCD ;LCD ENABLE
BUSY1:
JB P1.7,BUSY1
CLR E_LCD ;LCD DISABLE
CLR RW_LCD ;VRAT NA ZAPIS
RET
;--------------------------------
;LCD KAM CHCI PSAT)
;1. radek A= #1000XXXXB)
LCD_W_INST: ;2. radek A= #1100XXXXB)
CLR RS_LCD ;INSTRUKCE
CLR RW_LCD ;ZAPIS
MOV P1,A ;ODESLI INSTRUKCI
SETB E_LCD ;LCD ENABLE
CALL BUSY
RET
;--------------------------------
LCD_W_DATA:
SETB RS_LCD ;DATA
CLR RW_LCD ;ZAPIS
MOV P1,A ;ODESLI DATA
SETB E_LCD ;LCD ENABLE
CALL BUSY ;VYSTUP NA DISPLEJ
RET
;********************************
INIT:
CALL PAUSE2 ;cekani po privedeni Ucc
CLR A
MOV B,#5
MODS:
MOV DPTR,#INITBL
PUSH ACC
MOVC A,@A+DPTR
CALL LCD_W_INST
CALL PAUSE
POP ACC
INC A
DJNZ B,MODS
RET
;................................
Pause2: ;zpozdeni asi 390ms
mov R4,#255
mov R2,#255
mov R7,#3
Znovu2:
djnz R4,$ ;256 x
mov R4,#255
djnz R2,Znovu2 ;256 x 256 x
mov R2,#255
mov R4,#255
djnz R7,Znovu2 ;256 x 256 x 3
Ret
Pause:
mov R3,#155
djnz R3,$ ;zpozdeni asi 310 microsec
Ret
;................................
;inicializacni tabulka
INITBL:
DB 00000001b ;maze displej a vraci kurzor na poz.0
DB 00000010b ;vypina posun a vraci kurzor na pozici 0.
DB 00000110b ;smer pohybu kurzoru I/D vpravo, posun
;displeje SH vypmut.
DB 00001100b ;displej D zap, kurzor C, blikani B vyp
DB 00111100b ;8 bitu, 2 radky, font 5x10
;********************************
; texty
;*******************************
uvod1: DB '* TEXT 2 LINE *`'
uvod2: DB '* TEXT 1 LINE *`'
;********************************
END
Počítej s tím, že LCD 2x16 ma řadič pro displej 2x 40, proto je mezi koncem 1 řádku a začátkem 2 řádku pamětová díra ale zapisovat a číst tam jde. Já tu paměť drze používal na jiný účely. Stejný to bude asi i u jednořádku a čtyřřádku, ty jsem nezkoumal.
Pokud chceš jet jen po 4 bitech musí se LCD inicializovat jako při 8 bitech a na konci teprv převrátit na 4 bity
Jirka
Kód: Vybrat vše
setb Disp_e ;max. clk=250khz
;zapis sestupnou hranou
call Wait_5us
clr Disp_e
...
;cekaci smycka
;*************
mov r7,#Wait_disp ;doba,nez to pochopi
Pdp_w3:
djnz r7,Pdp_w3
Bývá to něco kolem 40 us na jeden zápis a někdy to může vadit. Řešením je odměřovat doby pomocí časovače nebo se zavěsit na přerušení od BUSSY.