; Exam 2 - 2012 .NOLIST .INCLUDE "m32def.inc" ; contains .EQU's for DDRB, PORTB, and a lot more .LIST .DEF temp=R18 .ORG 0x0 rjmp start .DSEG total: .byte 1 ; length of message2 string message2: .byte 100 ; just allocates SRAM .CSEG ; this means further directives are for the Code Segment .ORG 0x2a ; defines where these instructions start getting placed in Program Memory .ORG 0x14 ; Output Comparator vector rjmp comparator_matchISR ; Initialize the Stack Pointer (SP) CPU register for subsequent use start: ; start of program ldi temp, LOW(RAMEND) ; get low byte of the address of the highest byte in Data Memory we can use out SPL, temp ; load it into the low byte of SP ldi temp, HIGH(RAMEND) ; high byte of address of highest Data Memory byte out SPH, temp ; load it into the high byte of SP ; rcall initMessage2 ; copies Program Memory to SRAM ; rcall countStringLength ; counts string length in SRAM ; rcall initCTCMode ; put TC0 in CTC mode with OCR0 compare-match interrupt enabled ; sei ldi temp, 0xff ; init PortB out DDRB, temp ldi temp, 0xff out PORTB, temp loop: rol temp ; rotate left through carry out PORTB, temp rjmp loop text: .DB "hello world", 0 ; subroutine initMessage2 ; copies text from Program Memory to SRAM initMessage2: push ZL push ZH push XL push XH push temp ldi ZL, LOW(2*text) ; init Z to point to text location in Program Memory ldi ZH, HIGH(2*text) ldi XL, LOW(message2) ; init X to point to message2 location in SRAM ldi XH, HIGH(message2) copy_loop: lpm temp, Z+ ; read char from Program Memory st X+, temp ; write char to SRAM tst temp ; test temp==0 (st does not affect SREG) breq end_copy ; if 0, then null char has been reached; quit copying rjmp copy_loop end_copy: pop temp pop XH pop XL pop ZH pop ZL ret ; end initMessage2 ;subroutine countStringLength ; counts the number of chars in message2 countStringLength: push ZL push ZH push temp ldi XL, LOW(message2) ; init X to point to message2 location in SRAM ldi XH, HIGH(message2) clr temp sts total, temp ; clear total char counter count_loop: ld temp, X+ tst temp ; set SREG bits (ld does not affect SREG) breq end_count lds temp, total ; retrieve count inc temp sts total, temp ; store incremented count rjmp count_loop end_count: pop temp pop ZH pop ZL ret ; end countStringLength ; subroutine initCTCMode ; puts T/C 0 in CTC mode with compare-match interrupt enabled ; output comparator disabled initCTCMode: push temp out TCNT0, temp ; clear Counter0 counter register; this is what Counter0 increments in temp, TCCR0 ; get current state of Timer/Counter0 Control Register andi temp, 0b11111000 ; clear CS02:CS00 that control frequency ori temp, 0b00000101 ; set CS02:CS00 to increment Counter0 every 1024 CPU clock cycles ori temp, 0b00001000 ; set WGM01 bit to indicate CTC mode (count from 0 to OCR0 value and reset) out TCCR0, temp ; counter is now running, TCNT0 is incrementing automatically ; next, enable Counter0 compare-match interrupts in temp, TIMSK ; get state of Timer/Counter Interrupt Mask andi temp, 0b11111100 ; clear TOIE0 and OCIE0; keep other bits ori temp, 0b00000010 ; set bit OCIE0 to enable OCR0 Output Comparator interrupt out TIMSK, temp ldi temp, 254 ; set comparator match value (only used if in CTC or PWM modes) out OCR0, temp ; OCIE0 interrupt will occur with TCNT0 reaches the OCR0 value pop temp ret ; end initCTCMode ; interrupt handler comparator_matchISR ; Purpose: implements the handling of the Output Comparator match comparator_matchISR: push temp clr temp subi temp, 1 ; what is the effect on SREG??? pop temp reti ; end interrupt handler comparator_matchISR