;------------------------------------------------------------------- ;ENSC 151 Sample File ;------------------------------------------------------------------- ;AUTHOR(S): Bill De Vries ;VERSION: 1.0 Module Created 99-01-20 (Bill De Vries) ;VERSION: 1.1 Comments added 00-01-22 (Veljko Jovanovic) ;VERSION: 2.0 IRQ Capabilities added 00-01-28 (Rob Trost) ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; This program is the sample code to show how to use interrupts. ;------------------------------------------------------------------- ;------------------------------------------------------------------- ; LOCAL DEFINITIONS ;------------------------------------------------------------------- PORTA: equ $00 ;Port A Data Register PORTB: equ $01 ;Port B Data Register DDRA: equ $02 ;Port A Data Direction Register DDRB: equ $03 ;Port B Data Direction Register PORTC: equ $04 ;Port C Data Register DDRC: equ $06 ;Port C Data Direction Register PORTE: equ $08 ;Port E Data Register DDRE: equ $09 ;Port E Data Direction Register PEAR: equ $0A ;Port E Assigment Register MODE: equ $0B ;Mode Register PUCR: equ $0C ;Pull Up Control Register RDRIV: equ $0D ;Reduced Drive of I/O Lines Register INITRM: equ $10 ;Initialization of Internal RAM Position Register INITRG: equ $11 ;Initialization of Internal Register Position Register INITEE: equ $12 ;Inittaps IRQVEC: equ $0B32 ;Address of IRQ jump vector TOFVEC: equ $0B1E ; TOF Jump vector location ;------------------------------------------------------------------- ; LOCAL DEFINITIONS ;------------------------------------------------------------------- INTCR: equ $001E ; Interrupt Control Register TSCR: equ $0086 ; Timer System Control Register TFLG2: equ $008F ; Timer Interrupt Flag 2 TMSK2: equ $008D ; Timer Interrupt Mask 2 EDGE: equ %11100000 ; Set IRQ to be edge sensitive TOI: equ %10000000 ; Timer Overflow Interrupt Enableand TOF: equ %10000000 ; Timer Overflow Flag Reset TEN: equ %10000000 ; Timer Enable CLRSCR: equ %00000001 ; LCD clear screen and return cursor home ONE_SEC: equ !122 ; To time one second since 122*65536=8,000,000 (8MHz Clock) STROBE: equ $04 ;Bit 2 for LCD Enable (Strobing in Data) CMDREG: equ $00 ;Bit 0 is RS, Bit 1 is R/W (write instructions to the LCD) DATAREG: equ $01 ;Bit 0 is RS, Bit 1 is R/W (write data to the LCD CG or DD RAM) ;------------------------------------------------------------------- ;------------------------------------------------------------------- ; INITIALIZATION CODE ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; This section of the code initializes the LCD display and sets up ; all of the sub functions required for proper operation. This ; includes the WRITE_LCD subroutine and specific delay ; counters. ;------------------------------------------------------------------- ***************** Main Program ***************** ORG $0800 ; beginning of RAM ldaa #%00000111 ; Set lower 3 bits of Port A staa DDRA ; to output mode ldaa #%11111111 ; Set all bits of Port B staa DDRB ; to output mode jsr LCD_INIT ; Initialize the LCD ;------------------------------------------------------------------- ; INITIALISE DATA ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; Set the first character to be written as 'A', and set the ; TOF_CNT to the appropriate value for a one second timer. ;------------------------------------------------------------------- movb #'1',CHAR ; Set Character to A movb #ONE_SEC,TOF_CNT ; Set TOF_CNT for one second ;------------------------------------------------------------------- ; INITIALISE INTERRUPTS ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; This section of the code initializes the interrupts. IRQ_PROC ; is the procedure to handle all IRQ interrupts, and TOF_PROC is ; used to handle the TOF interrupts. The IRQ is also set to be edge ; sensitive. The timer and TOF are enabled, and set with a prescaler ; value of 1. Finally the TOF flag is reset and the interrupts are enabled. ;------------------------------------------------------------------- INIT movw #IRQ_PROC,IRQVEC ; install IRQ procedure address in jump vector table. movw #TOF_PROC,TOFVEC ; install TOF procedure address in jump vector table. movb #EDGE,INTCR ; Set IRQ edge sensitive movb #TEN,TSCR ; Enable timer circuitry movb #TOI,TMSK2 ; Enable timer interrupt movb #TOF,TFLG2 ; Reset timer overflow flag cli ; enable the interrupt. IDLE bra IDLE ; Do nothing ********************* End Main Program ********************* ;------------------------------------------------------------------- ; TIMER OVERFLOW INTERUPT PROCEDURE ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; After every 122 (ONE_SECOND) interrupts the next digit (1 to 9) will ; be written to the LCD display. The display will be cleared one second ; following a '9' being written and the count will start again. ;------------------------------------------------------------------- TOF_PROC dec TOF_CNT bne END_TOF ; If 1 second has passed write to LCD ldaa #'9' cmpa CHAR bhs NO_CLEAR ; If next digit to write is greater than '9' movb #'1',CHAR ; Reset digit to '1' and clear LCD ldaa #CMDREG ldab #CLRSCR jsr WRITE_LCD ldab #$0F ; Wait for LCD clear to finnish jsr LONGPAUSE NO_CLEAR ldaa #DATAREG ldab CHAR ; Then write a digit to LCD jsr WRITE_LCD inc CHAR ; Select next degit movb #ONE_SEC,TOF_CNT ; Reset TOF_CNT for one second END_TOF movb #TOF,TFLG2 ; Reset timer overflow flag rti ;------------------------------------------------------------------- ; IRQ INTERUPT PROCEDURE ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; When a button is pressed, the IRQ_PROC will simply clear the LCD ;------------------------------------------------------------------- IRQ_PROC ldaa #CMDREG ldab #CLRSCR ; Clear LCD Display jsr WRITE_LCD rti ;------------------------------------------------------------------- ; PROCEDURE: WRITE_LCD ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; Strobes the correct control lines to write an instruction or data ; into the LCD. The insturcion or data must be stored in ACCB before ; executing. The appropriate values of the RS, R/W and Enable bits ; must be stored in ACCA (RS = 0/1 if writing instruction/data, ; R/W = 0 since we are writing, E = 0 to start). ;------------------------------------------------------------------- WRITE_LCD ; Assume data/instruction in ACCB stab PORTB ; Write data to Port B staa PORTA ; Write RS, R/W, E to Port A jsr PAUSE eora #STROBE ; Set the Enable bit staa PORTA ; Strobe the instruction/data jsr PAUSE ; into the LCD. eora #STROBE ; Clear the Enable bit staa PORTA jsr PAUSE rts ;------------------------------------------------------------------- ; PROCEDURE: WRITE_MESSAGE ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; Writes a message (a string of characters) to the LCD. ;------------------------------------------------------------------- WRITE_MSG ldaa #DATAREG ; Set RS bit (write data) NEXT_CHAR ldab 0,X ; Load string into ACCB cmpb #$00 ; Check for the end of the string beq END_MSG jsr WRITE_LCD inx ; Increment string pointer bra NEXT_CHAR END_MSG rts ;------------------------------------------------------------------- ; PROCEDURE: LCD_INIT ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; Initializes the LCD display for required operation (2x16 mode) ;------------------------------------------------------------------- LCD_INIT ldaa #CMDREG ; Clear RS bit (write instruction) ldab #$30 ; Set Data Interface Length to 8bits jsr WRITE_LCD ldab #!15 jsr LONGPAUSE ldab #$38 ; Set Number of Display Lines to 2 jsr WRITE_LCD ldab #$08 ; Turn Off Display, Cursor & Blink jsr WRITE_LCD ldab #$01 ; Clear Display jsr WRITE_LCD ldab #!4 jsr LONGPAUSE ldab #$06 ; Set Cursor Move Direction - jsr WRITE_LCD ; Increment After Each Byte Written ldab #$0C ; Turn On Display jsr WRITE_LCD rts ;------------------------------------------------------------------- ; PROCEDURE: Delays ;------------------------------------------------------------------- ; DESCRIPTION: ; ~~~~~~~~~~~~ ; Delay functions for proper timing interface with the LCD. ;------------------------------------------------------------------- LONGPAUSE ; Executes the PAUSE subroutine as stab COUNTER ; many times as the value in ACCB LOOK tst COUNTER ; indicates. beq FINISH ; Delay = ~COUNT value * 0.2msec dec COUNTER jsr PAUSE bra LOOK FINISH rts PAUSE ldy #$00FF ; Delay for ~0.2msec AGAIN dey ; Counts down the contents of the cpy #$0000 ; Y index register. bne AGAIN ; Delay = #counts/processing speed. rts ;------------------------------------------------------------------- ***************** User Data ***************** COUNTER RMB 1 ; Counter for timing long pauses CHAR RMB 1 ; Stores value of next character to be displayed TOF_CNT RMB 1 ; Counts the number of TOF Interrupts