hexdec-lcd.a51
来自「8051 进行加解密的源代码」· A51 代码 · 共 590 行
A51
590 行
;*******************************************;* 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);;******************************************************************************$include (REG_8252.PDF)NAME Tutorial;Stack size (initial value of SP register)StackAddr EQU 0E0H ;stack address (equals size);some of hd44780 (lcd controler) ordersClrScr EQU 01H ;clear screenRetHome EQU 02H ;return to Home pos.CursorLeft EQU 10H ;cursor leftCursorRight EQU 14H ;cursor rightScreenLeft EQU 1CH ;screen leftScreenRight EQU 18H ;screen rightDisplyOn EQU 0CH ;display onDisplyOff EQU 08H ;disply offSetDDRam EQU 80H ;set ddram addressLCDLineLength EQU 20 ;lcd's line lengthLCDRowsNum EQU 4 ;lcd's max.row numberDSEG AT 30Ht_buffer: DS 8 ;transponder receiver buffer (64 bits)LCD_1: DS 20 ;lcd display bufferLCD_2: DS 20LCD_3: DS 20LCD_4: DS 20lcdenable BIT P0.4 ;enable signal for lcd displaylcdread BIT P0.5 ;read signal for lcdlcdreg BIT P0.6 ;when H switch to command register, when L to data registerlcdbusy BIT P2.7 ;data line 7 od lcd, for busy state testingmainprog SEGMENT CODE INBLOCK;interrupt vectorsCODE AT 0H AJMP InitProc ;resetCODE AT 3H AJMP IrqExt0 ;int0CODE AT 0BH AJMP IrqTmr0 ;timer 0CODE AT 13H AJMP IrqExt1 ;int1CODE AT 1BH AJMP IrqTmr1 ;timer 1CODE AT 23H AJMP IrqSPI ;spiCODE AT 30H;external int0IrqExt0: RETI ;timer 0 interruptIrqTmr0: RETI;external int1IrqExt1: RETI;timer 1 interruptIrqTmr1: RETI ;spi interruptIrqSPI: 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 programBlackLoop: 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 controllerOutStatRegLCD: 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 lcdOutLCD: 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 controllerCheckBusyFlag: MOV R6,#3CBF_0: MOV R5,#0FFHCBF_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 dptrDefChars1: CLR A MOVC A,@A+DPTR ;byte from def.table to acc. CJNE A,#0,DefCharsSkip1 ;is it the end of table? JMP DefCharsSkip2DefCharsSkip1: CALL OutLCD ;send a byte INC DPTR ;next position JMP DefChars1DefCharsSkip2: MOV A,#80H ;display mode CALL OutStatRegLCD RET;Delays;very short delay (about 2 ms)Pause: MOV R7,#10H MOV R6,#0FFHPause1: DJNZ R6,Pause1 DJNZ R7,Pause1 RET;about a few secondsLongPause: MOV R5,#0FFHLongPause1: CALL Pause DJNZ R5,LongPause1 RET;about one secondLPause: MOV R5,#21LPause1: CALL Pause DJNZ R5,LPause1 RET;Clear screenClearLCD: 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 PutCharOffsetPutCharOn1: CJNE R1,#2,PutCharOn2 ;is row=2? MOV A,#20 ;yes,ddram start pos.=20 JMP PutCharOffsetPutCharOn2: CJNE R1,#3,PutCharOn3 ;is row=3? MOV A,#84 ;yes,ddram start pos.=84 AJMP PutCharOffsetPutCharOn3: CLR A ;if row=0 then ddram start pos.=0PutCharOffset: ADD A,R2 ;offset for x coordin. ORL A,#SetDDRam ;set ddram CALL OutStatRegLCDPutCharOffSkip: 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 addressWriteCString: CLR A MOVC A,@A+DPTR ;chacter code from rom to acc. CJNE A,#0,WriteCSkip1 ;is it the end of string RETWriteCSkip1: 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 MOV R2,#0 ;&column,start from home pos.CStringSkip2: INC DPTR ;next chacter AJMP WriteCString;write a string from ram memory;R0=address of string in ram memory;R1=row number;R2=column numberWriteAString: MOV A,@R0 ;first char from ram position to acc. CJNE A,#0,WriteASkip1 ;is it the end code? RETWriteASkip1: MOV R3,A MOV A,R0 ;ro save PUSH ACC CALL PutCharOnLCD ;display char. POP ACC ;r0 restore MOV R0,A INC R2 ;next column CJNE R2,#LCDLineLength,AStringSkip2 ;is it max number of column? MOV R2,#0 ;yes,clear column number INC R1 ;and go to the next row CJNE A,#LCDRowsNum,AStringSkip2 ;is it the max number of row? MOV R1,#0 ;yes,clear row number and MOV R2,#0 ;go to the first rowAStringSkip2: INC R0 ;increment pointer address JMP WriteAString;3 bytes of hex number to decimal convertion routine;number in r5,r6,r7 (r5-msb,..,r7-lsb), result in r4,r5,r6,r7;the routine counts, how many times you can subtract the 1000000 from numer, then 100000,10000,1000,100,10,1;each counter equals position of decimal number f.e.:; 1E74 hex - you can subtract 1000 seven (7) times, 100 seven (7) times, 10 nine (9) times and the rest ;is six (6), so your result of conversion is 7796 (equals 1E74)Hex3DecConv: CLR C MOV R4,#0 ;milion counter clearHex3DecLoop1: MOV A,R7 ;how many time we can subtract 10000000 without carry (989680H) SUBB A,#80H MOV R7,A MOV A,R6 SUBB A,#96H MOV R6,A MOV A,R5 SUBB A,#98H MOV R5,A JC Hex3DecSkip1 INC R4 JMP Hex3DecLoop1Hex3DecSkip1: MOV A,R4 PUSH ACC ;push counter onto stack MOV A,R7 ADD A,#80H MOV R7,A MOV A,R6 ADDC A,#96H MOV R6,A MOV A,R5 ADDC A,#98H MOV R5,A CLR C MOV R4,#0Hex3DecLoop2: MOV A,R7 ;how many times we can subtract 1000000 (F4240H) without carry SUBB A,#40H MOV R7,A MOV A,R6 SUBB A,#42H MOV R6,A MOV A,R5 SUBB A,#0FH MOV R5,A JC Hex3DecSkip2 INC R4 JMP Hex3DecLoop2Hex3DecSkip2: MOV A,R4 PUSH ACC ;push counter onto stack MOV A,R7 ADD A,#40H MOV R7,A MOV A,R6 ADDC A,#42H MOV R6,A MOV A,R5 ADDC A,#0FH MOV R5,A CLR C MOV R4,#0Hex3DecLoop3: MOV A,R7 ;100000 (186A0H)? SUBB A,#0A0H MOV R7,A MOV A,R6 SUBB A,#86H MOV R6,A MOV A,R5 SUBB A,#01H MOV R5,A JC Hex3DecSkip3 INC R4 JMP Hex3DecLoop3Hex3DecSkip3: MOV A,R4 PUSH ACC ;onto stack MOV A,R7 ADD A,#0A0H MOV R7,A MOV A,R6 ADDC A,#86H MOV R6,A MOV A,R5 ADDC A,#01H MOV R5,AHex2DecConv: MOV R4,#0 CLR CHex2DecLoop1: MOV A,R7 ;10000 (2710h)? SUBB A,#010H MOV R7,A MOV A,R6 SUBB A,#27H MOV R6,A MOV A,R5 SUBB A,#0 MOV R5,A JC Hex2DecSkip1 INC R4 JMP Hex2DecLoop1Hex2DecSkip1: MOV A,R4 ;onto stack PUSH ACC MOV A,R7 ADD A,#010H MOV R7,A MOV A,R6 ADDC A,#27H MOV R6,A CLR C MOV R4,#0Hex2DecLoop2: MOV A,R7 ;1000 (3E8h)? SUBB A,#0E8H MOV R7,A MOV A,R6 SUBB A,#03H MOV R6,A JC Hex2DecSkip2 INC R4 JMP Hex2DecLoop2Hex2DecSkip2: MOV A,R4 ;onto satck PUSH ACC MOV A,R7 ADD A,#0E8H MOV R7,A MOV A,R6 ADDC A,#03H MOV R6,A CLR C MOV R4,#0Hex2DecLoop3: MOV A,R7 ;100 (64h)? SUBB A,#064H MOV R7,A MOV A,R6 SUBB A,#0H MOV R6,A JC Hex2DecSkip3 INC R4 JMP Hex2DecLoop3Hex2DecSkip3: MOV A,R4 ;onto stack PUSH ACC MOV A,R7 ADD A,#064H MOV R7,A MOV A,R6 ADDC A,#0H MOV R6,A CLR C MOV R4,#0Hex2DecLoop4: MOV A,R7 ;10 (0Ah)? SUBB A,#0AH MOV R7,A JC Hex2DecSkip4 INC R4 JMP Hex2DecLoop4Hex2DecSkip4: MOV A,R4 ;onto stack PUSH ACC ADD A,#0AH ;1 MOV A,R7 ;tens & ones in w R7 ADD A,#0AH MOV R7,A POP ACC SWAP A ADD A,R7 MOV R7,A POP ACC ;thousands & hundreds in R6 MOV R6,A POP ACC SWAP A ADD A,R6 MOV R6,A POP ACC ;tens thousands & hundreds thousands in R5 MOV R5,A POP ACC SWAP A ADD A,R5 MOV R5,A POP ACC ;milins & tens milions in R4 MOV R4,A POP ACC SWAP A ADD A,R4 MOV R4,A RET;Decimal to ascii conversion;decimal in r4(msb),r5,r6,r7(lsb),result in ram buffer LCD_1(0..7);note:numbers are in correct order after hex2dec conversion routine;routine takes each of decimal number (4 bits of 8 bit register) and adds it to 0 ascii code character;f.e. 15 => '0'+1 -> '1' , '0'+5 -> '5'Dec2AsciiConv: MOV A,#LCD_1 MOV R0,A ;pointer to lcd_1 MOV A,R4 ANL A,#0F0H SWAP A ADD A,#'0' MOV @R0,A INC R0 MOV A,R4 ANL A,#0FH ADD A,#'0' MOV @R0,A INC R0 MOV A,R5 ANL A,#0F0H SWAP A ADD A,#'0' MOV @R0,A INC R0 MOV A,R5 ANL A,#0FH ADD A,#'0' MOV @R0,A INC R0 MOV A,R6 ANL A,#0F0H SWAP A ADD A,#'0' MOV @R0,A INC R0 MOV A,R6 ANL A,#0FH ADD A,#'0' MOV @R0,A INC R0 MOV A,R7 ANL A,#0F0H SWAP A ADD A,#'0' MOV @R0,A INC R0 MOV A,R7 ANL A,#0FH ADD A,#'0' MOV @R0,A INC R0 ;put the end of string code MOV A,#0 MOV @R0,A RET;write version procedure,example of writecstring usingWriteVersion: CALL ClearLCD ;clear screen MOV R1,#0 ;first column & first row MOV R2,#0 MOV DPTR,#Copyright CALL WriteCString RET ;definicje znak體Char: DB 0AAH,055H,0AAH,055H,0AAH,055H,0AAH,055H ;#C1: DB 0C0H,0C0H,0FFH,0F1H,0F1H,0F1H,0FFH,0C0H ;blank quadrantC2: DB 0C0H,0C0H,0FFH,0FFH,0FFH,0FFH,0FFH,0C0H ;blak quadrantC3: DB 0E0H,0FFH,0FFH,0FFH,0E0H,0E0H,0E0H,0E0H ;near minusC4: DB 0FFH,0FFH,0F9H,0F3H,0E7H,0F3H,0F9H,0FFH ;LeftC5: DB 0FFH,0FFH,0F3H,0F9H,0FCH,0F9H,0F3H,0FFH ;RightC6: DB 0FFH,0FFH,0FBH,0F1H,0E4H,0EEH,0FFH,0FFH ;UpC7: DB 0FFH,0FFH,0FFH,0EEH,0E4H,0F1H,0FBH,0FFH,0 ;DownCopyright: DB 'LCD 4x40 using example',0ConvDesc: DB '1E87 hex to decimal=',0END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?