📄 hexdec-lcd.a51.asm
字号:
;*******************************************
;* Tutorial: *
;* 1. Hex to Decimal converting routine *
;* 2. Decimal to Ascii converting rout. *
;* 3. LCD (4x40) driving functions *
;*******************************************
;This program was written using Raisonance RIDE MA-51
;my email: jacek.bogusz@ep.com.pl
;at89s8252 at 11.0592 MHz
;******************************************************************************
; LCD connections:
;
; Pin description | AT89S8252
; ---------------------------------------
; enable | P0.4(35)
; read lcd | P0.5(34)
; reg.select | P0.6(33)
; d0..d7 | P2.0 .. P2.7 (21..28)
;
;******************************************************************************
;Stack size (initial value of SP register)
StackAddr EQU 0E0H ;stack address (equals size)
;some of hd44780 (lcd controler) orders
ClrScr EQU 01H ;clear screen
RetHome EQU 02H ;return to Home pos.
CursorLeft EQU 10H ;cursor left
CursorRight EQU 14H ;cursor right
ScreenLeft EQU 1CH ;screen left
ScreenRight EQU 18H ;screen right
DisplyOn EQU 0CH ;display on
DisplyOff EQU 08H ;disply off
SetDDRam EQU 80H ;set ddram address
LCDLineLength EQU 20 ;lcd's line length
LCDRowsNum EQU 4 ;lcd's max.row number
DSEG AT 30H
t_buffer: DS 8 ;transponder receiver buffer (64 bits)
LCD_1: DS 20 ;lcd display buffer
LCD_2: DS 20
LCD_3: DS 20
LCD_4: DS 20
lcdenable BIT P0.4 ;enable signal for lcd display
lcdread BIT P0.5 ;read signal for lcd
lcdreg BIT P0.6 ;when H switch to command register, when L to data register
lcdbusy BIT P2.7 ;data line 7 od lcd, for busy state testing
mainprog SEGMENT CODE INBLOCK
;interrupt vectors
CODE AT 0H
AJMP InitProc ;reset
CODE AT 3H
AJMP IrqExt0 ;int0
CODE AT 0BH
AJMP IrqTmr0 ;timer 0
CODE AT 13H
AJMP IrqExt1 ;int1
CODE AT 1BH
AJMP IrqTmr1 ;timer 1
CODE AT 23H
AJMP IrqSPI ;spi
CODE AT 30H
;external int0
IrqExt0: RETI
;timer 0 interrupt
IrqTmr0: RETI
;external int1
IrqExt1: RETI
;timer 1 interrupt
IrqTmr1: RETI
;spi interrupt
IrqSPI: RETI
;------------------------------------------------
; MAIN PROGRAM
;
; Note: this is a part of bigger program, which
; is working as a machine controller, so you
; have to change some of orders for your own
; application!
;------------------------------------------------
InitProc: MOV SP,#StackAddr ;stack pointer setting
MOV P0,#11101110B ;initial value of each port
MOV P1,#10000111B
MOV P2,#0FFH ;P2 is used for LCD data line (8 bits)
CALL InitLCD ;lcd init - 8 bit interface
CALL DefChars ;lcd special chacters def.
MOV R7,#80 ;black lcd at the start of the program
BlackLoop: MOV A,#0FFH
CALL OutLCD ;OUTLCD outputs value from ACC to LCD video ram
DJNZ R7,BlackLoop
CALL LPause ;a little break (about 0.8 sec)
CALL WriteVersion ;write start information (about version etc)
CALL LongPause ;a few seconds of delay
CALL ClearLCD ;clear lcd's screen
;example of WriteCString using
MOV R1,#0 ;row no.0
MOV R2,#0 ;column no.0
MOV DPTR,#ConvDesc ;address of string from rom in dptr
CALL WriteCString
;example of hex to dec converting
MOV R5,#0
MOV R6,#1EH
MOV R7,#87H
CALL Hex3DecConv ;result in r5,6,7
CALL Dec2AsciiConv ;result in lcd_1 (ram memory buffer)
;display the result of conversion (example of WriteAString using)
MOV R1,#1 ;row no.1
MOV R2,#0 ;column no.0
MOV R0,#LCD_1 ;r0 contains address of ram buffer
CALL WriteAString
AJMP $ ;here stops the program
;Out data to status control register (of LCD)
;status control register is using to input control codes for lcd controller
OutStatRegLCD: CLR lcdreg ;choose status register
CLR lcdread ;& write mode
NOP
SETB lcdenable
MOV P2,A ;move acc.content to P2
CLR lcdenable ;data latched by enable signal
CALL CheckBusyFlag
RET
;Display char at cursor position
;this routine outputs char contained in acc. to video ram of lcd
OutLCD: SETB lcdreg ;choose data register
CLR lcdread ;& write mode
NOP
SETB lcdenable
MOV P2,A ;move acc.content to P2
CLR lcdenable ;data latched by enable signal
CALL CheckBusyFlag
RET
;Delay instead of busy line checking
;if you want, you can check the value of P0.7 (d7 of lcd)
;logic H on this line is for BUSY state of lcd controller
CheckBusyFlag: MOV R6,#3
CBF_0: MOV R5,#0FFH
CBF_1: DJNZ R5,CBF_1
DJNZ R6,CBF_0
RET
;Initializing of lcd (8 bit體)
InitLCD: CALL LPause
CLR lcdreg
CLR lcdread
CLR lcdenable
SETB lcdenable ;enable H, then L
MOV P2,#30H
CLR lcdenable
CALL Pause
SETB lcdenable ;enable H, then L
MOV P2,#30H
CLR lcdenable
CALL Pause
SETB lcdenable ;enable H, then L
MOV P2,#30H
CLR lcdenable
CALL Pause
MOV A,#3CH
CALL OutStatRegLCD
MOV A,#08H
CALL OutStatRegLCD
MOV A,#01H
CALL OutStatRegLCD
MOV A,#06H
CALL OutStatRegLCD
MOV A,#0CH ;lcd "on display"
CALL OutStatRegLCD
RET
;Own char definitioning - definitions are in CHAR table at the ROM memory (program segment)
;at the end of the table you have to put byte 0 - this is the end of definition table
;at this version of lcd display you can define 10 your own characters
;please read the lcd's programming manual for details.
DefChars: CLR A ;start address of CGRAM
ORL A,#40H ;cgram definition mode (b6=1)
CALL OutStatRegLCD
MOV DPTR,#Char ;start address of definition to dptr
DefChars1: CLR A
MOVC A,@A+DPTR ;byte from def.table to acc.
CJNE A,#0,DefCharsSkip1 ;is it the end of table?
JMP DefCharsSkip2
DefCharsSkip1: CALL OutLCD ;send a byte
INC DPTR ;next position
JMP DefChars1
DefCharsSkip2: MOV A,#80H ;display mode
CALL OutStatRegLCD
RET
;Delays
;very short delay (about 2 ms)
Pause: MOV R7,#10H
MOV R6,#0FFH
Pause1: DJNZ R6,Pause1
DJNZ R7,Pause1
RET
;about a few seconds
LongPause: MOV R5,#0FFH
LongPause1: CALL Pause
DJNZ R5,LongPause1
RET
;about one second
LPause: MOV R5,#21
LPause1: CALL Pause
DJNZ R5,LPause1
RET
;Clear screen
ClearLCD: MOV A,#ClrScr ;"clear screen" code
CALL OutStatRegLCD
RET
;display char on lcd
;R1 <- row number (0 - n)
;R2 <- column number (0 - n)
;R3 <- ascii char code (code of character from rom char.generator of lcd)
PutCharOnLCD: PUSH ACC
MOV A,R1 ;save r1
MOV R7,A
CJNE R1,#1,PutCharOn1 ;is row=1?
MOV A,#64 ;yes,ddram start position=64
JMP PutCharOffset
PutCharOn1: CJNE R1,#2,PutCharOn2 ;is row=2?
MOV A,#20 ;yes,ddram start pos.=20
JMP PutCharOffset
PutCharOn2: CJNE R1,#3,PutCharOn3 ;is row=3?
MOV A,#84 ;yes,ddram start pos.=84
AJMP PutCharOffset
PutCharOn3: CLR A ;if row=0 then ddram start pos.=0
PutCharOffset: ADD A,R2 ;offset for x coordin.
ORL A,#SetDDRam ;set ddram
CALL OutStatRegLCD
PutCharOffSkip:
MOV A,R3
CALL OutLCD ;Out char on screen
MOV A,R7 ;R1 recall
MOV R1,A
POP ACC
RET
;write a string from rom memory
;r1= row number
;r2=column number
;dptr=string address
WriteCString: CLR A
MOVC A,@A+DPTR ;chacter code from rom to acc.
CJNE A,#0,WriteCSkip1 ;is it the end of string
RET
WriteCSkip1: MOV R3,A
CALL PutCharOnLCD ;put char on lcd
INC R2 ;next column
CJNE R2,#LCDLineLength,CStringSkip2 ;is it max column?
MOV R2,#0 ;yes,clear column number
INC R1 ;next row
CJNE A,#LCDRowsNum,CStringSkip2 ;is max row number?
MOV R1,#0 ;yes-clear row number
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -