;=========================================================================== ;= ;= Companion code for the application note "Using the DS89C450 as a Static ;= LCD Controller". ;= ;= Compiler: MASM 8051 generic assembler ;= ;=========================================================================== ; Register definitions for DS89C4x0. Some of these may have to be commented ; out depending on the assembler/compiler that you use. P0 equ 080H ; Port 0 SP equ 081H ; Stack pointer DPL equ 082H ; Data pointer low DPH equ 083H ; Data pointer high DPS equ 086H ; Data pointer select PCON equ 087H ; Power control TCON equ 088H ; Timer/counter control TMOD equ 089H ; Timer mode control TL0 equ 08AH ; Timer 0 LSB TL1 equ 08BH ; Timer 1 LSB TH0 equ 08CH ; Timer 0 MSB TH1 equ 08DH ; Timer 1 MSB CKCON equ 08EH ; Clock control P1 equ 090H ; Port 1 EXIF equ 091H ; External interrupt flags CKMOD equ 096H ; Timer clock mode SCON0 equ 098H ; Serial port 0 control SBUF0 equ 099H ; Serial port 0 data buffer ACON equ 09DH ; Address control P2 equ 0A0H ; Port 2 IE equ 0A8H ; Interrupt enable SADDR0 equ 0A9H SADDR1 equ 0AAH P3 equ 0B0H ; Port 3 IP1 equ 0B1H IP2 equ 0B8H SADEN0 equ 0B9H SADEN1 equ 0BAH SCON1 equ 0C0H ; Serial port 1 control SBUF1 equ 0C1H ; Serial port 1 data buffer ROMSIZE equ 0C2H ; ROM size select PMR equ 0C4H ; Power management STATUS equ 0C5H ; Status register TA equ 0C7H ; Timed access T2CON equ 0C8H ; Timer 2 control T2MOD equ 0C9H ; Timer 2 mode RCAP2L equ 0CAH ; Timer 2 capture/auto-reload LSB RCAP2H equ 0CBH ; Timer 2 capture/auto-reload MSB TL2 equ 0CCH ; Timer 2 LSB TH2 equ 0CDH ; Timer 2 MSB PSW equ 0D0H ; Program status word WDCON equ 0D8H ; Watchdog control ACC equ 0E0H ; Accumulator EIE equ 0E8H B equ 0F0H EIP1 equ 0F1H EIP0 equ 0F8H ;=========================================================================== ;= Scratch Pad Variables = ;=========================================================================== ; [000h - 007h] Register bank 0; equates defined for direct push/pop of R0-R7. R00 equ 00H R01 equ 01H R02 equ 02H R03 equ 03H R04 equ 04H R05 equ 05H R06 equ 06H R07 equ 07H DigitP1 equ 08H DigitP2 equ 09H DigitP3 equ 0AH Count equ 0BH CountMax equ 0CH ;*************************************************************************** ;* ;* Flash entry point and interrupt vectors. ;* org 0000h ; Power up, reset ljmp Start org 0003h ; External interrupt 0 ljmp Start org 000Bh ; Timer 0 interrupt ljmp IntTimer0 org 0013h ; External interrupt 1 ljmp Start org 001Bh ; Timer 1 interrupt ljmp Start org 0023h ; Serial port 0 interrupt ljmp Start org 002Bh ; Timer 2 interrupt ljmp Start org 0033h ; Power-fail interrupt ljmp Start org 003Bh ; Serial port 1 interrupt ljmp Start org 0043h ; External interrupt 2 ljmp Start org 004Bh ; External interrupt 3 ljmp Start org 0053h ; External interrupt 4 ljmp Start org 005Bh ; External interrupt 5 ljmp Start org 0063h ; Watchdog interrupt ljmp Start ;*************************************************************************** ;* ;* IntTimer0 (INTT0) ;* ;* Timer interrupt service routine ;* IntTimer0: push ACC ; Save off accumulator and R0 push R00 mov R0, Count ; Only increment LCD digits every [CountMax] ; interrupt cycles djnz R0, INTT0_Done inc DigitP1 ; Increment ones digit on display mov A, DigitP1 cjne A, #10, INTT0_Continue ; Check for rollover mov DigitP1, #0 inc DigitP2 ; Increment tens digit on display mov A, DigitP2 cjne A, #10, INTT0_Continue ; Check for rollover mov DigitP2, #0 inc DigitP3 ; Increment hundreds digit on display mov A, DigitP3 cjne A, #10, INTT0_Continue ; Check for rollover mov DigitP3, #0 INTT0_Continue: mov R0, CountMax ; Reset to starting cycle count INTT0_Done: mov Count, R0 ; Update cycle counter pop R00 pop ACC ; Restore accumulator and R0 reti ;*************************************************************************** ;* ;* Firmware entry point. ;* Start: mov DigitP1, #0 ; Set initial display to "000" mov DigitP2, #0 mov DigitP3, #0 mov Count, #20 ; Increment LCD counter every [CountMax] mov CountMax, #20 ; Timer 0 interrupt cycles mov SCON0, #0 mov SCON1, #0 mov SP, #080h ; Initialize stack pointer mov TMOD, #021h ; Timer 1: 8-bit auto-reload from TH1 ; Timer 0: 16-bit mov TCON, #050h ; Enable timers 0 and 1 mov CKMOD, #038h ; Use system clock for all timer inputs mov IE, #082h ; Enable timer 0 interrupt Main: mov IE, #080h ; Disable timer 0 interrupt temporarily mov R2, DigitP1 ; Grab local copies of digit variables mov R3, DigitP2 mov R4, DigitP3 mov IE, #082h ; Re-enable timer 0 interrupt mov A, R2 call getDigit ; Calculate segment pattern for ones digit anl A, #01111111b ; Ensure COM (P1.7) is driven low mov P1, A mov A, R3 call getDigit ; Calculate segment pattern for tens digit mov P2, A mov A, R4 call getDigit ; Calculate segment pattern for hundreds digit mov P3, A ;;;; Delay loop ;;;; mov R0, #0FFh L1A: mov R1, #0FFh L1B: djnz R1, L1B djnz R0, L1A ;;;;;;;;;;;;;;;;;;;;;; mov A, R2 call getDigit ; Calculate segment pattern for ones digit cpl A ; Inverse of the pattern driven on the first frame half orl A, #10000000b ; Ensure COM (P1.7) is driven high mov P1, A mov A, R3 call getDigit ; Calculate segment pattern for tens digit cpl A ; Inverse of the pattern driven on the first frame half mov P2, A mov A, R4 call getDigit ; Calculate segment pattern for hundreds digit cpl A ; Inverse of the pattern driven on the first frame half mov P3, A ;;;; Delay loop ;;;; mov R0, #0FFh L2A: mov R1, #0FFh L2B: djnz R1, L2B djnz R0, L2A ;;;;;;;;;;;;;;;;;;;;;; ljmp Main ; Go back for another frame cycle (endless loop) ;*************************************************************************** ;* ;* getDigit ;* ;* Returns an LCD segment pattern (in Acc) for the decimal digit (0-9) ;* input (also in Acc) ;* getDigit: cjne A, #0, getDigit_not0 ; xgfedcba mov A, #00111111b ; Zero ret getDigit_not0: cjne A, #1, getDigit_not1 ; xgfedcba mov A, #00000110b ; One ret getDigit_not1: cjne A, #2, getDigit_not2 ; xgfedcba mov A, #01011011b ; Two ret getDigit_not2: cjne A, #3, getDigit_not3 ; xgfedcba mov A, #01001111b ; Three ret getDigit_not3: cjne A, #4, getDigit_not4 ; xgfedcba mov A, #01100110b ; Four ret getDigit_not4: cjne A, #5, getDigit_not5 ; xgfedcba mov A, #01101101b ; Five ret getDigit_not5: cjne A, #6, getDigit_not6 ; xgfedcba mov A, #01111101b ; Six ret getDigit_not6: cjne A, #7, getDigit_not7 ; xgfedcba mov A, #00000111b ; Seven ret getDigit_not7: cjne A, #8, getDigit_not8 ; xgfedcba mov A, #01111111b ; Eight ret getDigit_not8: cjne A, #9, getDigit_not9 ; xgfedcba mov A, #01101111b ; Nine ret getDigit_not9: mov A, #0 ret end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;