* * Ex4.asm ---- Example program 4 for the Ep2711E9 Rev.C board * (c)2003, EVBplus.com, Written by Wayne Chu * * Function: It displays the word 'SCAn" on the 7 segment LED display, * scans the keypad and displays the key number on the * 7 segment LED display if a key is down. * Instruction: Connect a 4 x 4 keypad to the keypad header J6. * * * The 68HC11 control register address is the offset address from the * register base address $1000, so index addressing mode can also be used, * otherwise only extended addressing mode can be used. * * ORG $c4 *** Vector jump table for BUFFALO monitor *** JSCI RMB 3 JSPI RMB 3 JPAIE RMB 3 JPAO RMB 3 JTOF RMB 3 JTOC5 RMB 3 JTOC4 RMB 3 JTOC3 RMB 3 JTOC2 RMB 3 JTOC1 RMB 3 JTIC3 RMB 3 JTIC2 RMB 3 JTIC1 RMB 3 JRTI RMB 3 JIRQ RMB 3 JXIRQ RMB 3 JSWI RMB 3 JILLOP RMB 3 JCOP RMB 3 JCLM RMB 3 * portg: equ $2200 ; port B data register of the 65C22 ddrg: equ $2202 ; port B direction registr of the 65C22 * DB0 equ 1 DB1 equ 2 DB6 equ $40 NOTDB6 equ $bf portb: equ 4 portd: equ 8 ddrd: equ 9 toc2: equ $18 tctl1: equ $20 tmsk1: equ $22 tflg1: equ $23 REGBLK: equ $1000 TB5MS: equ 10000 ; time base of 10,000 instruction cycles * ; = 10,000 x 0.5us = 5ms at 8MHz org $00 ; data RAM starts here * ram: rmb 1 temp: rmb 1 key_flag: rmb 1 select: rmb 1 d5ms_flag: rmb 1 disp_data: rmb 4 disptn: rmb 4 ramend: rmb 1 ALLRAM: equ ramend-ram ;total ram used STACK: equ $8FFF * org $FFA0 ; Buffalo I/O routines upcase: rmb 3 wchek: rmb 3 dchek: rmb 3 init_sci: rmb 3 input: rmb 3 output: rmb 3 outlhlf: rmb 3 outrhlf: rmb 3 outa: rmb 3 out1byt: rmb 3 out1bsp: rmb 3 out2bsp: rmb 3 outcrlf: rmb 3 outstrg: rmb 3 outstrg0: rmb 3 inchar: rmb 3 * org $D000 ; user program starts at $D000 jmp start * Binary number: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F * Converted to segment code: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F * * Binary number: $10,$11,$12,$13,$14,$15,$16,$17 * Converted to segment code: G H h J L n o o * * Binary number: $18,$19,$1A,$1B,$1C,$1D,$1E,$1F,$20 * Converted to segment code: P r t U u y _ -- Blank * segm: fcb $3f,$06,$5b,$4f,$66,$6d,$7d,$07 ;0-7 fcb $7f,$6f,$77,$7c,$39,$5e,$79,$71 ;8-$0f fcb $3d,$76,$74,$1e,$38,$54,$63,$5c ;10-17 * G, H, h, J L n o o fcb $73,$50,$78,$3e,$1c,$6e,$08,$40 ;18-1f * P, r, t, U, u Y - - fcb $00,$01,$48,$41,$09,$49 ;20-23 * blk, -, =, =, =, = * seven_segment: pshx pshb ldx #segm psha anda #$3f tab abx ldaa 0,x ; get segment pulb andb #$80 ; add DP aba pulb pulx rts * clrall: pshx ldx #ram clrr clr 0,x inx deca bne clrr pulx rts * this routine moves 4 bytes of data into display * pattern and converts the pattern to seven segment code. * @ enter, x points the source address * move: ldy #disptn mnext: ldaa 0,x jsr seven_segment ; convert Accu A to segment pattern, bit 7= DP staa 0,y inx iny cpy #disptn+4 bne mnext rts nop * * keypad scan * at exit: if a key is down, the carry bit =1 and the accumulator b * holds the key number * if no key is dwon the carry bit =0 * keybrd: * ldaa #00001111b ldaa #$0F ; pg0-pg3 are outputs, pg4-pg7 are inputs staa ddrg ldab #16 * ldaa #11110111b ldaa #$F7 ; pg3=low, pg0-pg2=high staa temp ; save it at emp next_row: staa portg nop ; add delay before checking key down nop nop nop ldaa portg anda #$F0 ; only read 4 MSBs pg4-pg7 cmpa #$F0 bne keyin ; a key is pressed subb #4 beq no_keyin ; after 4 tests, accu B will be 0 sec ror temp ldaa temp jmp next_row * no_keyin: clc rts ; no key input keyin: decb rola bcs keyin sec rts * start: lds #STACK ldx #REGBLK * ldaa #11111111b ldaa #$ff ; turn off 7-segment display staa portd,x * ldaa #11111100b ; 0 =input, 1 = output ldaa #$fc staa ddrd,x * ldaa #ALLRAM jsr clrall ldaa #5 ; letter 'S' staa disp_data ldaa #$0C ; letter 'C' staa disp_data+1 ldaa #$0A ; letter 'A' staa disp_data+2 ldaa #$15 ; letter 'n' staa disp_data+3 ldx #REGBLK ldaa #DB6 staa tmsk1,x cli * begin: ldx #REGBLK jsr keybrd bcc no_key brset key_flag DB0 was_set ; key already down bset key_flag DB0 jmp dead_key was_set: brset key_flag DB1 dead_key ; key already processed bset key_flag DB1 * stab disp_data stab disp_data+1 stab disp_data+2 stab disp_data+3 jmp dead_key no_key: clr key_flag dead_key: ldx #disp_data jsr move jsr sel_digit * wait: tst d5ms_flag beq wait ; wait for 5ms timeup clr d5ms_flag jmp begin * * multiplexing display one digit at a time * sel_digit: ldx #REGBLK inc select ldab select andb #3 tstb beq digit3 decb beq digit2 decb beq digit1 * digit0: ldaa disptn+3 staa portb,x bclr portd,x 4 ; turn on digit 0 bset portd,x 8 ; turn off all other digits bset portd,x $10 bset portd,x $20 rts digit1: ldaa disptn+2 staa portb,x bset portd,x 4 bclr portd,x 8 ; turn on digit 1 bset portd,x $10 bset portd,x $20 rts digit2: ldaa disptn+1 staa portb,x bset portd,x 4 bset portd,x 8 bclr portd,x $10 ; turn on digit 2 bset portd,x $20 rts digit3: ldaa disptn staa portb,x bset portd,x 4 bset portd,x 8 bset portd,x $10 bclr portd,x $20 ; turn on digit 3 rts tmr6oc2: ldx #REGBLK * in an interrupt servicing routine the x register will be saved automatically * the rti instruction will pop the x register off stack. inc d5ms_flag ldd #TB5MS ; reload the count for 5 ms time base addd toc2,x std toc2,x bclr tflg1,x NOTDB6 rti * org JTOC2 ; BUFFALO RAM vector for OC2 jmp tmr6oc2 ; jmp to OC2 service routine end