Sida 1 av 2
Kört fast med att få en hd47780 display att fungera. [LÖS
Postat: 24 februari 2007, 15:21:28
av eriikh
EDIT:Det har löst sig, kolla min sista post i denna tråd.
Sitter här och kodar mitt assembler program för att försöka få en 2x16 hd47780 display att fungera i 4bit mode.
Jag kollade först på piclist om det fanns några lämpliga projekt, hittade
detta.
Han som skrev det tycker jag var väldigt dålig på att kommentera koden så till slut skrev jag en egen. Kan ni försöka att kolla vad som kan vara fel?
Kod: Markera allt
; LCD Test Program v1.0 made by Erik Henriksson
; This program is ment to run at 20Mhz.
;
;*********************************************
; Start of program
;*********************************************
; What to do when reset
;*********************************************
Org 0x001
Goto Start
;*********************************************
; End
;*********************************************
; Alias declarations
;*********************************************
PORTA Equ 0x005
PORTB Equ 0x006
trisa Equ 0x085
trisb Equ 0x086
isr Equ 0x004
status Equ 0x003
En Equ 5
RS Equ 6
RW Equ 7
;*********************************************
; End of Alias declarations
;*********************************************
; Variable declaration
;*********************************************
;Avalible RAM in bank0: 0x0020-0x06F
;
; Delay variables
d1 Equ 0x020
d2 Equ 0x021
d3 Equ 0x022
d4 Equ 0x023
; Lcd variables
Hi_bits Equ 0x024
Lo_bits Equ 0x025
;*********************************************
; End of Variable declaration
;*********************************************
; Timer interrupt
;*********************************************
Org isr
; Do nothing
;*********************************************
; End of Timer interrupt
;*********************************************
; Subroutines
;*********************************************
Delay_5ms ; Make a delay of exactly 5ms = 25000cykles
;24993 cycles
movlw 0x86
movwf d1
movlw 0x14
movwf d2
Delay_5ms_0
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_5ms_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
;******
Delay_160us ; Make a delay of exactly 160us = 800cykles
;793 cycles
movlw 0x9E
movwf d1
movlw 0x01
movwf d2
Delay_160us_0
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_160us_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
;******
Enable
movlw 0x20
bsf portb, En ; pulse the LCD Enable high
nop
nop
nop
nop
nop
nop
nop
nop
bcf portb, En ; pulse the LCD Enable low
nop
nop
return
;******
Sendin4bit
; Send W to lcd trought 4bit interface
; You must set RS first if you are sending a character
clrf hi_bits
clrf lo_bits
bcf STATUS,0 ; clear C which could skrew up the bitshifts
; Load W into lo_bits and hi_bits
movwf hi_bits
movwf lo_bits
;lo_bits preparation
movlw 0x0F
andwf lo_bits, 1 ; Remove the high bits and store in lo_bits
;hi_bits preparation
movlw 0xF0
andwf hi_bits, 1 ; Remove the low bits so they dont affect the carry bit
rrf hi_bits, 1
rrf hi_bits, 1
rrf hi_bits, 1
rrf hi_bits, 1
;Send the bits
;Hi:
movfw hi_bits ; Move hi_bits to W
addwf portb ; Add the bits so you can set RS before if you want
call Enable
call delay_160us ; lcd busy delay
subwf portb
;Lo
movfw lo_bits ; Move hi_bits to W
addwf portb ; Add the bits so you can set RS before if you want
call Enable ; Set enable for 3,2us
call delay_160us ; lcd busy delay
subwf portb
;Done
return
;*********************************************
; End of Subroutines
;*********************************************
; Start
;*********************************************
Start
Clrf porta ; Init porta
Clrf portb ; Init portb
Banksel trisb ; Select bank1
Movlw 0x00 ; Data direction value, 0 = output
Movwf trisb ; Write to trisb
Movlw 0xFF
Movwf trisa
Banksel portb ; Select bank0
;*********************************************
; End of Start
;*********************************************
; Main
;*********************************************
Call delay_5ms
Call delay_5ms
Call delay_5ms
Call delay_5ms ; Wait for lcd to start
Movlw 0x03
Movwf portb
Call Enable ; Send 0x03
Call delay_5ms
Call Enable ; Send 0x03
Call delay_160us
Call Enable ; Send 0x03
Call delay_160us
Movlw 0x02
Movwf portb
Call Enable ; Send 0x02
Call delay_160us
Movlw 0x28 ; Interface length is: 4bit, 2 lines, 5x7
Call Sendin4bit
Movlw 0x10 ; Turn off the display
Call Sendin4bit
Movlw 0x01 ; Clear the display
Call Sendin4bit
Movlw 0x06 ; Shift cursor on every written byte
Call Sendin4bit
Movlw 0x0F ; Turn display on, cursor on, cursor blinking on
Call Sendin4bit
;Init done
Movlw 0x45 ; Send 'E'
Call Sendin4bit
;*********************************************
; End of Main
;*********************************************
; End of Program
;*********************************************
END
Postat: 24 februari 2007, 15:32:27
av sodjan
__CONFIG direktiv saknas.
LIST direktiv saknas.
INCLUDE av "device" filen saknas.
> PORTA Equ 0x005
Finns i INCLUDE filen...
Men sen, vad händer (inte) ??
Postat: 24 februari 2007, 15:48:55
av eriikh
När jag kör programmet i PIC Simulator (Oshon soft) så matar pic:en ut allt jag skrivit i koden, men ingen reaktion av lcd:n. Funkar varken i simulatorn eller i verkligheten. Får ingen cursor, ingen reaktion alls.
sodjan: Tillagt i koden, blev inte bättre.
EDIT: Mao så är det själva tillvägagångsättet i koden som är problemet... Har någon en kod för 4bit som fungerar så jag kan jämföra eller ser ni fel rakt av redan nu?
Postat: 24 februari 2007, 16:06:49
av sodjan
> PIC Simulator (Oshon soft)
Kör med MPLAB/MPSIM.
> Tillagt i koden,
Ser ingen skillnad.......
Postat: 24 februari 2007, 16:13:27
av eriikh
Får samma resultat i MPSIM, all output är som jag vill. Men varför startar inte lcd:n?
Kod: Markera allt
; LCD Test Program v1.0 made by Erik Henriksson
; This program is ment to run at 20Mhz.
;
;*********************************************
; Start of program
;*********************************************
; CONFIG, INCLUDE & LIST
;*********************************************
__CONFIG 0x036A
INCLUDE p16f628a.inc
LIST p=16f628A
;*********************************************
; End
;*********************************************
; What to do when reset
;*********************************************
Org 0x001
Goto Start
;*********************************************
; End
;*********************************************
; Alias declarations
;*********************************************
ISR Equ 0x004
En Equ 5
RS Equ 6
RW Equ 7
;*********************************************
; End of Alias declarations
;*********************************************
; Variable declaration
;*********************************************
;Avalible RAM in bank0: 0x0020-0x06F
;
; Delay variables
d1 Equ 0x020
d2 Equ 0x021
d3 Equ 0x022
d4 Equ 0x023
; Lcd variables
Hi_bits Equ 0x024
Lo_bits Equ 0x025
;*********************************************
; End of Variable declaration
;*********************************************
; Timer interrupt
;*********************************************
Org isr
; Do nothing
;*********************************************
; End of Timer interrupt
;*********************************************
; Subroutines
;*********************************************
Delay_5ms ; Make a delay of exactly 5ms = 25000cykles
;24993 cycles
movlw 0x86
movwf d1
movlw 0x14
movwf d2
Delay_5ms_0
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_5ms_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
;******
Delay_160us ; Make a delay of exactly 160us = 800cykles
;793 cycles
movlw 0x9E
movwf d1
movlw 0x01
movwf d2
Delay_160us_0
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_160us_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
;******
Enable
movlw 0x20
bsf portb, En ; pulse the LCD Enable high
nop
nop
nop
nop
nop
nop
nop
nop
bcf portb, En ; pulse the LCD Enable low
nop
nop
return
;******
Sendin4bit
; Send W to lcd trought 4bit interface
; You must set RS first if you are sending a command
clrf hi_bits
clrf lo_bits
bcf STATUS,0 ; clear C which could screw up the bitshifts
; Load W into lo_bits and hi_bits
movwf hi_bits
movwf lo_bits
;lo_bits preparation
movlw 0x0F
andwf lo_bits, 1 ; Remove the high bits and store in lo_bits
;hi_bits preparation
movlw 0xF0
andwf hi_bits, 1 ; Remove the low bits so they dont affect the carry bit
rrf hi_bits, 1
rrf hi_bits, 1
rrf hi_bits, 1
rrf hi_bits, 1
;Send the bits
;Hi:
movfw hi_bits ; Move hi_bits to W
addwf portb, 1 ; Add the bits so you can set RS before if you want. Store in portb
call Enable
call delay_160us ; lcd busy delay
subwf portb, 1 ; Store in portb
;Lo
movfw lo_bits ; Move hi_bits to W
addwf portb, 1 ; Add the bits so you can set RS before if you want . Store in portb
call Enable ; Set enable for 3,2us
call delay_160us ; lcd busy delay
subwf portb, 1 ; Store in portb
;Done
return
;*********************************************
; End of Subroutines
;*********************************************
; Start
;*********************************************
Start
Clrf porta ; Init porta
Clrf portb ; Init portb
Banksel trisb ; Select bank1
Movlw 0x00 ; Data direction value, 0 = output
Movwf trisb ; Write to trisb
Movlw 0xFF
Movwf trisa
Banksel portb ; Select bank0
;*********************************************
; End of Start
;*********************************************
; Main
;*********************************************
Call delay_5ms
Call delay_5ms
Call delay_5ms
Call delay_5ms ; Wait for lcd to start
Movlw 0x03
Movwf portb
Call Enable ; Send 0x03
Call delay_5ms
Call Enable ; Send 0x03
Call delay_160us
Call Enable ; Send 0x03
Call delay_160us
Movlw 0x02
Movwf portb
Call Enable ; Send 0x02
Call delay_160us
Movlw 0x28 ; Interface length is: 4bit, 2 lines, 5x7
Call Sendin4bit
Movlw 0x10 ; Turn off the display
Call Sendin4bit
Movlw 0x01 ; Clear the display
Call Sendin4bit
Movlw 0x06 ; Shift cursor on every written byte
Call Sendin4bit
Movlw 0x0F ; Turn display on, cursor on, cursor blinking on
Call Sendin4bit
;Init done
Movlw 0x45 ; Send 'E'
Call Sendin4bit
;*********************************************
; End of Main
;*********************************************
; End of Program
;*********************************************
END
Postat: 24 februari 2007, 16:18:22
av sodjan
Felkopplat ?
Ingen spänning till LCD'n ?
Lösa trådar ?
Kan vara i princip vad som helst...
Postat: 24 februari 2007, 17:24:10
av eriikh
Isf skulle det väl funka i simulatorn?
Inställningar i Pic Sim för er intresserade:
LCD Module
16x1
4bit low interface
RS: portb, 6
EN: portb, 5
RW, not connected
Postat: 24 februari 2007, 17:32:30
av sodjan
> Isf skulle det väl funka i simulatorn?
OK, den där andra prylen. Ingen aning...
> RW, not connected
Vad har du för alternativ till "not connected" ?
Postat: 24 februari 2007, 17:36:12
av eriikh
Jag kan ställa in vilken pinne den ska vara ansluten till. Not connected = dragen till jord, det har funkat förut när den har vart konfigurerad så. Dock inte med asm som språk...
Du råkar inte sitta på ett välkommenterat 4bits lcd-exempel? Skulle vara mycket tacksamt isf.
Postat: 24 februari 2007, 17:40:55
av Icecap
På min hemsida, under "Freebies", finns det en komplett manual om hur man pratar med dessa displays.
Postat: 24 februari 2007, 17:47:41
av sodjan
Jag har slängt ihop korta testprog (asm) när jag har behövt bilder till
mina LCD auktioner i Tradera, men inget som jag har sparat (jag kollade
tidigare idag).
Men vänta, jag kollade igen och hittade nedanstående.
Det *bör* skriva ut text på en 16x2 LCD i 4-bit mode.
Inte speciellt snyggt men du får det gratis...
Kod: Markera allt
list p=16f870 ; list directive to define processor
#include <p16f870.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _DEBUG_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF & _CPD_OFF & _WRT_ENABLE_OFF
;INT_VAR UDATA_SHR
;w_temp RES 1 ; variable used for context saving
;status_temp RES 1 ; variable used for context saving
;
;digit_reg RES 1
;
;rotate_temp RES 1
;rotate_count RES 1
#define LCD_PORT PORTB
LCD_DB0 equ 0
LCD_DB1 equ 1
LCD_DB2 equ 2
LCD_DB3 equ 3
LCD_RS equ 5
LCD_E equ 4
;LCD_RD equ 6
start code h'0000'
goto main
main_code code
main
banksel trisb
clrf TRISB
banksel portb
call delay_1s
call delay_1s
call delay_1s
call delay_1s
call delay_1s
; bcf TRISA, RA0
; bcf LATA, RA0
; call LCD_init
;loop
; call LCD_test
call delay_1s
movlw h'01'
call LCD_send_command
call delay_1s
movlw h'0C'
call LCD_send_command
call delay_1s
; movlw h'E7'
; call LCD_send_command
movlw d'2'
call LCD_set_line1_pos_W
call delay_1s
movlw a'E'
call LCD_send_byte
movlw a'D'
call LCD_send_byte
movlw a'T'
call LCD_send_byte
movlw a' '
call LCD_send_byte
movlw a'E'
call LCD_send_byte
movlw a'W'
call LCD_send_byte
movlw a'2'
call LCD_send_byte
movlw a'0'
call LCD_send_byte
movlw a'4'
call LCD_send_byte
movlw a'0'
call LCD_send_byte
movlw a'0'
call LCD_send_byte
movlw a'Y'
call LCD_send_byte
movlw a'R'
call LCD_send_byte
; movlw a'1'
; call LCD_send_byte
; movlw a'J'
; call LCD_send_byte
movlw d'1'
call LCD_set_line2_pos_W
call delay_1s
movlw a'H'
call LCD_send_byte
movlw a'D'
call LCD_send_byte
movlw a'4'
call LCD_send_byte
movlw a'4'
call LCD_send_byte
movlw a'7'
call LCD_send_byte
movlw a'8'
call LCD_send_byte
movlw a'0'
call LCD_send_byte
movlw a' '
call LCD_send_byte
movlw a'k'
call LCD_send_byte
movlw a'o'
call LCD_send_byte
movlw a'm'
call LCD_send_byte
movlw a'p'
call LCD_send_byte
movlw a'a'
call LCD_send_byte
movlw a't'
call LCD_send_byte
movlw a'i'
call LCD_send_byte
movlw a'b'
call LCD_send_byte
movlw a'e'
call LCD_send_byte
movlw a'l'
call LCD_send_byte
movlw d'0'
call LCD_set_line3_pos_W
call delay_1s
movlw a'D'
call LCD_send_byte
movlw a'e'
call LCD_send_byte
movlw a'n'
call LCD_send_byte
movlw a'n'
call LCD_send_byte
movlw a'a'
call LCD_send_byte
movlw a' '
call LCD_send_byte
movlw a't'
call LCD_send_byte
movlw a'e'
call LCD_send_byte
movlw a'x'
call LCD_send_byte
movlw a't'
call LCD_send_byte
movlw a' '
call LCD_send_byte
movlw a's'
call LCD_send_byte
movlw a'k'
call LCD_send_byte
movlw a'r'
call LCD_send_byte
movlw a'i'
call LCD_send_byte
movlw a'v'
call LCD_send_byte
movlw a'e'
call LCD_send_byte
movlw a'n'
call LCD_send_byte
movlw d'0'
call LCD_set_line4_pos_W
call delay_1s
movlw a'm'
call LCD_send_byte
movlw a'e'
call LCD_send_byte
movlw a'd'
call LCD_send_byte
movlw a' '
call LCD_send_byte
movlw a'e'
call LCD_send_byte
movlw a'n'
call LCD_send_byte
movlw a' '
call LCD_send_byte
movlw a'P'
call LCD_send_byte
movlw a'I'
call LCD_send_byte
movlw a'C'
call LCD_send_byte
movlw a'1'
call LCD_send_byte
movlw a'6'
call LCD_send_byte
movlw a'F'
call LCD_send_byte
movlw a'8'
call LCD_send_byte
movlw a'7'
call LCD_send_byte
movlw a'0'
call LCD_send_byte
movlw a' '
call LCD_send_byte
movlw a':'
call LCD_send_byte
movlw a'-'
call LCD_send_byte
movlw a')'
call LCD_send_byte
; movlw 0x35
; call LCD_send_bcd_byte
;
; call LCD_test
; call LCD_test
; call LCD_test
; call LCD_test
; call LCD_test
loop
goto loop
;delay code
delay_vars UDATA_SHR
CNT1 res 1
CNT2 res 1
CNT3 res 1
del_code code
delay_1s
movlw 0x00
movwf CNT1
movlw 0x00
movwf CNT2
movlw 0x00
movwf CNT3
dly_loop
decfsz CNT2, f
goto dly_loop
movlw 0x01
movwf CNT2
decfsz CNT1, f
goto dly_loop
decfsz CNT3, f
goto dly_loop
return
delay_w_value
; loop number of microsec as in w
;
movwf cnt1
delay_w_value2
nop
decfsz cnt1, f
goto delay_w_value2
return
LCD_init code
LCD_init
; set LCD to 4-bit interface
;
call delay_1s
nop
bsf PORTB, LCD_E
nop
bcf LCD_PORT, LCD_RS
nop
bcf LCD_PORT, LCD_DB3
nop
bcf LCD_PORT, LCD_DB2
nop
bsf LCD_PORT, LCD_DB1
nop
bsf LCD_PORT, LCD_DB0
nop
call LCD_toggle_E
nop
bcf LCD_PORT, LCD_DB3
nop
bcf LCD_PORT, LCD_DB2
nop
bsf LCD_PORT, LCD_DB1
nop
bsf LCD_PORT, LCD_DB0
nop
call LCD_toggle_E
nop
bcf LCD_PORT, LCD_DB3
nop
bcf LCD_PORT, LCD_DB2
nop
bsf LCD_PORT, LCD_DB1
nop
bcf LCD_PORT, LCD_DB0
nop
call LCD_toggle_E
nop
bsf LCD_PORT, LCD_RS
nop
bcf LCD_PORT, LCD_DB3
nop
bcf LCD_PORT, LCD_DB2
nop
bcf LCD_PORT, LCD_DB1
nop
bcf LCD_PORT, LCD_DB0
nop
call LCD_toggle_E
nop
call LCD_toggle_E
nop
return
LCD_test
bsf LCD_PORT, LCD_RS
bcf LCD_PORT, LCD_DB3
bsf LCD_PORT, LCD_DB2
bcf LCD_PORT, LCD_DB1
bcf LCD_PORT, LCD_DB0
call LCD_toggle_E
bcf LCD_PORT, LCD_DB3
bcf LCD_PORT, LCD_DB2
bcf LCD_PORT, LCD_DB1
bsf LCD_PORT, LCD_DB0
call LCD_toggle_E
return
LCD_toggle_E
movlw h'08'
call delay_w_value
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
bcf LCD_PORT, LCD_E
movlw h'08'
call delay_w_value
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
bsf LCD_PORT, LCD_E
movlw h'08'
call delay_w_value
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
return
LCD_send_byte_vars UDATA_SHR
LCD_byte_NIBBLE_H res 1
LCD_byte_NIBBLE_L res 1
LCD_send_byte_code code
LCD_send_byte
; Send byte in W to LCD as 2 4-bit nibbles.
bsf LCD_PORT, LCD_RS
movwf LCD_byte_NIBBLE_L
movwf LCD_byte_NIBBLE_H
swapf LCD_byte_NIBBLE_H, f
movlw 0x0F
andwf LCD_byte_NIBBLE_H, f
andwf LCD_byte_NIBBLE_L, f
movf LCD_PORT, w
andlw 0xF0
iorwf LCD_byte_NIBBLE_H, w
movwf LCD_PORT
call LCD_toggle_E
movf LCD_PORT, w
andlw 0xF0
iorwf LCD_byte_NIBBLE_L, w
movwf LCD_PORT
call LCD_toggle_E
call delay_1s
return
LCD_send_command_vars udata_shr
LCD_command_NIBBLE_H res 1
LCD_command_NIBBLE_L res 1
LCD_SEND_BCD_TMP1 res 1
LCD_SEND_BCD_TMP2 res 1
LCD_SEND_BCD_H res 1
LCD_SEND_BCD_L res 1
LCD_send_command_code code
LCD_send_command
bcf LCD_PORT, LCD_RS
movwf LCD_command_NIBBLE_L
movwf LCD_command_NIBBLE_H
swapf LCD_command_NIBBLE_H, f
movlw 0x0F
andwf LCD_command_NIBBLE_H, f
andwf LCD_command_NIBBLE_L, f
movf LCD_PORT, w
andlw 0xF0
iorwf LCD_command_NIBBLE_H, w
movwf LCD_PORT
call LCD_toggle_E
movf LCD_PORT, w
andlw 0xF0
iorwf LCD_command_NIBBLE_L, w
movwf LCD_PORT
call LCD_toggle_E
return
LCD_set_line1_pos_W
addlw h'00'
goto LCD_set_line_pos_W
LCD_set_line2_pos_W
addlw h'40'
goto LCD_set_line_pos_W
LCD_set_line3_pos_W
addlw h'14'
goto LCD_set_line_pos_W
LCD_set_line4_pos_W
addlw h'54'
LCD_set_line_pos_W
addlw h'80'
call LCD_send_command
return
LCD_send_bcd_byte
; Send BCD value in W as two ASCII chars.
movwf LCD_SEND_BCD_TMP1
movwf LCD_SEND_BCD_TMP2
swapf LCD_SEND_BCD_TMP2, w
andlw 0x0F
addlw 0x30
call LCD_send_byte
movf LCD_SEND_BCD_TMP1, w
andlw 0x0F
addlw 0x30
call LCD_send_byte
return
end
Postat: 24 februari 2007, 18:14:34
av eriikh
Tack!
Vad har du för frekvens på kristallen?
Det är ju främst init jag är intresserad av, du skickar så här:
Kod: Markera allt
0x3 RS off
0x3 RS off
0x2 RS off
0x0 RS on ;Tjänar dessa något till, och isf vad?
0x0 RS on ;
Jag skickar så här:
Kod: Markera allt
0x3 RS off ; Onödigt?
;5ms paus ;
0x3 RS off
0x3 RS off
0x2 RS off
----
0x2 RS off ; Inställningar
0x8 RS off
0x1 RS off
0x0 RS off
0x0 RS off
0x1 RS off
0x0 RS off
0x6 RS off
0x0 RS off
0xF RS off
;Nu ska cursorn blinka, det gör den dock inte.
Vad är den första 3:an jag skickar till för?
Postat: 24 februari 2007, 19:05:38
av sodjan
> Vad har du för frekvens på kristallen?
Minns inte men kan inte se att det spelar någon större roll för LCD
interfacet.
En del säger att man ska skicka flera 03 "för säkerhets skull". Jag vet inte...
Postat: 24 februari 2007, 19:29:55
av eriikh
Okej..
Vad har 00, som du skickar två gånger med RS på, för funktion då?
Postat: 24 februari 2007, 19:53:25
av Icecap
eriikh: nog dags att du läser databladet på min hemsida, kolla speciellt sida 16 (sidnummer 14)!