Kod: Markera allt
;**********************************************************************
; Enkelt test av HD44780 LCD display.
; Använder en standard 16x2 LCD.
; För PIC16F886
;
;**********************************************************************
; *
; Filename: HD44780_16F886.asm
; Date: 20070702
; File Version: 1.0
;
; Author: Jan-Erik Söderholm
; Company: Jan-Erik Söderholm Consulting AB
;
;**********************************************************************
;
; Files required: P16F886.INC
; 16F690.LKR
;
;**********************************************************************
;
; Notes:
; Använder intosc på 4 Mhz.
;
; E : RC0
; RS: RC1
; D4-D7 : RC4-RC7
; R/W kopplad till GND (d.v.s ingen läsning av Busy-signalen).
;
;**********************************************************************
;
;
list p=16f690 ; list directive to define processor
#include <p16F690.inc>
;__CONFIG ( _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT)
;
__CONFIG _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
ERRORLEVEL -224 ; supress annoying message from tris
ERRORLEVEL -302 ; supress message from page change
;
cblock 0x20
Delay1 ; Assign an address to label Delay1
Delay2
Display ; define a variable to hold the diplay
Direction
LookingFor
endc
;
#define LCD_E PORTA, 1
#define LCD_RS PORTA, 0
#define LCD_PORT PORTC
;
;
;**********************************************************************
RESET_VECTOR CODE 0x000 ; processor reset vector
goto start ; go to beginning of program
;
;
INT_VECTOR CODE 0x004 ; interrupt vector location
retfie ; Ingen interrupt kod...
;
;
;**********************************************************************
; Macro för att skicka en text till LCD.
;
lcd_text macro text_label
banksel eeadr ; byt till rätt bank...
movlw high text_label ; bit 8-15 av adressen till texten
movwf eeadrh
movlw low text_label ; bit 0-7 av adressen till texten
movwf eeadr
;
; Nu är de två adressregistren laddade med rätt adress.
; Anropa subrutinen för att hämta texten och skriva ut den.
;
call lcd_send_text
banksel porta ; Lämna rutinen i bank 0.
;
endm
;
;**********************************************************************
; Huvudkoden.
; Här hamnar vi vid reset eller power-on (från RESET_VECTOR)
;
;
MAIN CODE
start
;
; Först normal uppstart ej specifik för LCD
;
banksel ansel ; Stäng av alla analoga funktioner
clrf ansel
clrf anselh
banksel trisa ; Alla pinnar utgångar...
clrf trisa
clrf trisb
clrf trisc
movlw b'00000000'
MOVWF TRISA
;
banksel intcon
clrf intcon
banksel porta ; se till att vi är på bank 0.
clrf porta
clrf portb
clrf portc
clrf Direction
clrf LookingFor
;
; Så då var grundinställningen av processorn klar.
; Nu går vi vidare med LCD hanteringen...
;
call lcd_init_hd44780 ; Ställ in LCD'n.
;
; Skriv ut ett par texter på LCD'n...
;
;
;
MainLoop:
btfsc LookingFor,0
goto LookingFor1
LookingFor0:
btfsc PORTA,3 ; is the switch pressed (0)
goto Rotate
bsf LookingFor,0 ; yes Next we'll be looking for a 1
movlw 0xFF ; load the W register incase we need it
xorwf Direction,f ; yes, flip the direction bit
movlw b'00000010' ; Display/curs home
call lcd_send_cmd
movlw b'00000001' ; Display clear
call lcd_send_cmd
goto Rotate
LookingFor1:
btfsc PORTA,3 ; is the switch pressed (0)
bcf LookingFor,0
Rotate:
bcf STATUS,C ; ensure the carry bit is clear
btfss Direction,0
goto RotateLeft
RotateRight:
lcd_text lcd_text1
lcd_text lcd_text2
goto MainLoop
RotateLeft:
lcd_text lcd_text3
lcd_text lcd_text4
goto MainLoop
return
;
loop goto loop ; Gör ingenting....
;
;**********************************************************************
; Subs för HD44780
;
; Nägra temp variabler som används av LCD rutinerna.
; Lägger dom i "shared memory" så slipper vi banksel...
;
LCD_VARS UDATA_SHR
LCD_TMP1 RES 1
LCD_TMP2 RES 1
;
; Slut på variabler, här kommer koden...
;
LCD_CODE CODE
;
lcd_init_hd44780
;
call delay_1s ; Ge LCD'n tid att starta...
bcf LCD_E ; Se till att E och RS är
bcf LCD_RS ; nollade...
;
; Skicka initkoder enligt manual för HD44780.
; För detaljer, se manual för HD44780 eller datablad för en LCD.
;
movlw h'30'
call lcd_send_4_bit
call delay_5ms
movlw h'30'
call lcd_send_4_bit
call delay_5ms
movlw h'30'
call >till LCD som "data".
;
banksel lcd_port
bsf LCD_RS ; RS = "1" för data
call lcd_send_byte ; Skicka
call delay_100us ; Ge LCD'n tid att bearbeta datat.
return
;
lcd_send_byte
; Data i W överförs till LCD som två 4-bitars bitar.
;
movwf lcd_tmp2 ; Spara W tillfälligt
movlw B'11110000' ; Mask för bit 4-7
andwf lcd_tmp2, w ; Nolla bit 0-3
call lcd_send_4_bit ; Skicka bit 4-7
swapf lcd_tmp2, f ; Byt plats på 0-3 <-> 4-7
movlw B'11110000' ; Mask för bit 4-7 (nu 0-3 !!)
andwf lcd_tmp2, w ; Nolla bit 0-3 (nu 4-7 !!)
call lcd_send_4_bit ; Skicka bit 4-7 (nu 0-3 !!)
return
;
lcd_send_text
; Sänd en fast text till LCD.
; När rutinen anropas ska EEADR och EEADRH vara initierade
; med adressen i flash till text-bufferten. T.ex genom det
; lcd_text macro som finns i detta program.
; Beräkningen av rad/kol -> LCD-pos är just nu anpassad
; till 16x2 LCD'er. Får justeras för att passa andra...
;
; Läs första positionen i texten ("LCD-rad")
;
call read_flash
movwf lcd_tmp1 ; Lagra (radnummer på LCD)
;
; Hämta nästa pos i textraden (pos på LCD raden...)
;
call inc_eeadr
call read_flash
movwf lcd_tmp2 ; Lagra (position på raden på LCD)
;
; Justering av rad/pos väden
;
decf lcd_tmp1, f ; Rad 1-2 => 0-1
bcf status, c
rrf lcd_tmp1, f
rrf lcd_tmp1, f
rrf lcd_tmp1, f ; Nu är lcd_tmp1 h'00' eller h'40'...
decf lcd_tmp2, f ; Pos 1-40 => 0-39
;
; Nu är rad och pos färdiga att addera ihop och skicka till LCD'n...
;
movlw h'80' ; Bas-kommandot för LCD-position.
addwf lcd_tmp1, w ; Lägg till rad (h'00' eller h'40')
addwf lcd_tmp2, w ; Lägg till pos.
call lcd_send_cmd ; Skicka kommandot (i W-reg)
;
; Nu läser vi resten av texten fram till h'00' poch skickar
; till LCD'n.
;
send_text_loop
;
; Läs nästa position ("LCD-text") och skicka.
; Avsluta om datat/tecknet = h'00'
;
call inc_eeadr
call read_flash
btfsc status, z ; Var det h'00' (slut på text) ?
goto send_text_end ; Ja, avsluta.
; Nej, fortsätt...
call lcd_send_data ; Skicka tecken med data i W-reg.
goto send_text_loop ; Om igen...
;
send_text_end
; Slut på text...
;
return
;
read_flash
;
; Läs en byte från flash
; EEADR och EEADRH ska redan vara initierade.
;
banksel eecon1
bsf eecon1, eepgd ; Läs från flash...
bsf eecon1, rd ; Sätt läs-flaggan...
nop ; Vänta på att läsning
nop ; ska gå klart...
banksel eedat
movf eedat, w ; Nu har vi värdet i W-reg.
return
;
; Räkna fram eeadr/eeadrh till nästa position
;
inc_eeadr
banksel eeadr
incf eeadrh, f ; öka först eeadrh
incfsz eeadr, f ; öka eeadr, = 0 ?
decf eeadrh, f ; eeadr <> 0, återställ eeadrh...
return
;
;
;**********************************************************************
; Diverse delay rutiner.
; Alla delay rutiner generade med kodgeneratorn här :
; http://www.piclist.com/techref/piclist/codegen/delay.htm
; OBS generatade för 4 Mhz processorhastighet.
;
DLY_VAR UDATA_SHR
d1 RES 1
d2 RES 1
d3 RES 1
;
;
DLY_CODE CODE
;
delay_1s
movlw 0x08
movwf d1
movlw 0x2F
movwf d2
movlw 0x03
movwf d3
Delay_1s_0
decfsz d1, f
goto $+2
decfsz d2, f
goto $+2
decfsz d3, f
goto Delay_1s_0
goto $+1
nop
return
;
delay_5ms
movlw 0xE7
movwf d1
movlw 0x04
movwf d2
Delay_5ms_0
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_5ms_0
goto $+1
return
;
delay_100us
movlw 0x21
movwf d1
Delay_100us_0
decfsz d1, f
goto Delay_100us_0
return
;
;**********************************************************************
LCD_texts CODE
; Fasta texter för LCDn.
; Två första värderna i varje text är rad (1,2,3 eller 4)
; och position (1-40). Resten är text fram till h'00'.
;
lcd_text3 data d'1', d'1', 'I', 'N', 'N', 'E', ':','2','2', 0xDF,'C', h'00'
lcd_text4 data d'2', d'1', 'U', 'T', 'E', ':', '2','1',0xDF,'C', h'00'
lcd_text1 data d'1', d'1', 'V','V', ':', '6','0',0xDF,'C', h'00'
lcd_text2 data d'2', d'1', 'V','B', ':', '2','8',0xDF,'C', h'00'
;
;**********************************************************************
end
Hjälp tack