Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

still no working interrupt )-:

2007-01-08 by Thomas Keller

I don't get it.  My stand alone interrupt routine works, but I cannot 
seem to get interrupts to work in this program.  here is the code (with 
comments which reveal proprietary information redacted out):

;
;==============================================================================
;
;    NAME:        beacon.asm
;
;    PROJECT:    *** REDACTED ***
;
;    VERSION:    v0.1a
;
;    DATE:        01/03/2007
;
;    AUTHOR:        Thomas J Keller
;
;    COPYRIGHT:    Copyright 2007, All Rights Reserved
;
;    DESCRIPTION:    *** REDACTED***
;
;    HISTORY:
;    +===+=======+======================================================+
;     | who |   date       |   description                              
                                                                         |
;    
+-----+----------+---------------------------------------------------------------------------------+
;     |  tjk   | 07/01/03 |  intialize program file                    
                                                                       |
;    
+-----+----------+---------------------------------------------------------------------------------+
;    |  tjk   | 07/01/08  |  add symbolic names for registers and 
constants, for clarity                                  |
;    
+-----+----------+---------------------------------------------------------------------------------+
;    +==================================================================+


.include "tn25def.inc"

;
; Define the variables
;

;
;    .defines
;

.def    TEMP        =    r16
.def    HICOUNT        =    r21            ; HIGHBYTE byte value for timer 0
.def    LOCOUNT     =    r22            ; LOWBYTE byte value for timer
.def    HILOFLAG    =    r23            ; HIGHBYTE/LOWBYTE byte flag
.def    PWMSET        =    r18            ; value to be passed to PWM 
control register
.def    TABLEADDR     =    r19            ; EEPROM table address register
.def    DIRFLAG        =    r17            ; table traversal direction 
control flag

;
;    .equates
;

.equ    TRUE        =    0xff        ; true value
.equ    FALSE        =    0x00        ; false value
.equ    DOWN        =    0xff        ; up count flag value
.equ    UP            =    0x00        ; down count flag vlaue
.equ    HIGHBYTE    =    0xff        ; HIGHBYTE byte flag value
.equ    LOWBYTE        =    0x00        ; LOWBYTE byte flag value


; Define Reset and interrupt vectors, if any
;
RESET:
   rjmp BEGIN
   reti                          ; Addr $01
   reti                          ; Addr $02
   reti                          ; Addr $03
   reti                          ; Addr $04
   rjmp    TIMER0                  ; timer/counter 0 overfLOWBYTE interrupt
   reti                          ; Addr $06
   reti                          ; Addr $07
   reti                          ; Addr $08
   reti                          ; Addr $09
   reti                          ; Addr $0A
   rjmp    TIMER0                     ; timer/counter 0 compare match A 
interrupt
   reti                          ; Addr $0C
   reti                          ; Addr $0D
   reti                          ; Addr $0E
   reti                         ; Addr $0F
   reti                         ; Addr $10



 
;    this table provides the data for the intensity curve needed for
;    xxxxxxxxxxxxxxx.  the data represent the value sin^3 * 255 for
;    each angle from 0 through 90  at .9 degree increments

    .eseg

TABLE:
    .db    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 5, 6, 6
    .db    8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 24, 26, 29, 31, 34, 36
    .db    39, 44, 48, 52, 55, 59, 62, 66, 70, 74, 78, 82, 86, 90, 94, 99
    .db    103, 108, 112, 117, 121, 126, 130, 135, 140, 144, 149, 153
    .db    158, 163, 167, 172, 176, 180, 185, 189, 193, 197, 201, 205
    .db    209, 212, 216, 219, 223, 226, 229, 232, 234, 237, 239, 242
    .db    244, 246, 247, 249, 250, 252, 253, 254, 255, 255, 255
     
;
     .cseg

;
; Program starts here after Reset
;

BEGIN:

    ldi    TEMP,    RAMEND                    ; initialize stack pointer
    out    SPL,    TEMP

;
;    set timer controsl and interrupts
;
   
    ldi    TEMP,    0x02                    ; set WGM1:0 to 0x02
    out    TCCR0A,    TEMP                    ; and store in TCCR0A
    ldi    TEMP,    0x04                    ; set wgm2 and CS2:0
    out TCCR0B,    TEMP                    ; store in TCCR0B

    ldi    TEMP,    0x40;                    ; enable timer/counter 0 
compare match A interrupt
    out    TIMSK,    TEMP                    ; store to timer/counter 0 
Interrupt mask register

    sei                                    ; enable global interrupts

;
;    set up timer delay for ~~.01 second
;
;    counter clock will be prescaled by 256 to make the .01 second count 
easier
;

    ldi    LOCOUNT,    0x38                ;  load LOWBYTE byte of delay 
count
    ldi    HICOUNT,    0xff                ; load HIGHBYTE byte value 
for delay count
    out    OCR1A,    HICOUNT                    ; store in timer/counter 
register   

    ldi    TEMP,    0xe5                    ; load the control value for 
TCCR1
                                        ; CTC1 set, PWMa set, COM1A set to
                                        ; toggle on match, timer clock set
                                        ; for system clock divided by 256
`    out    TCCR1,    TEMP                    ; store in TCCR1

   
    ldi    HILOFLAG,    HIGHBYTE                ; HIGHBYTE/LOWBYTE byte 
flag for timer
                                        ; control (see interrupt handler 
for more)

;
;    this code sets the default initial table adress at 0
;

    ldi    TABLEADDR,    0x00                ; first addresss in EEPROM 
table data
    ldi DIRFLAG,    UP                    ; direction control byte, 0 = up

    rjmp    MAIN                        ; go to the main loop in the code

NEXT:

    ldi    TEMP,    UP                        ; compare value
    cp    TEMP,    DIRFLAG                    ; check direction bit for 
value
    breq    UPCNT                        ; it's set for an up count
   
    ldi    TEMP,    UP                        ; compare value
    dec    TABLEADDR                        ; count the table pointer 
down one
    cp    TABLEADDR,    TEMP                ; at the bottom yet?
    breq    CONT0                        ; nope. continue
    RJMP    QUIT0                        ; all done, depart

UPCNT:
    ldi    TEMP,    0x63                    ; compare value
    inc    TABLEADDR                        ; increment table pointer
    cp    TABLEADDR,     TEMP                ; 99 decimal, end of table
    breq    FIXIT0                        ; deal with table overfLOWBYTE
    rjmp    QUIT0                        ; all done, depart

CONT0:

    ldi    DIRFLAG,    UP                    ; set to count up again
    rjmp    QUIT0

FIXIT0:

    ldi    DIRFLAG,    DOWN                ; reset direction flag for 
down count
           
QUIT0:

    ret                                    ; return from subrouttine 
call   

;
;    read a value from the EEPROM table
;

TABLEDATA:

    out    EEARL,     TABLEADDR                        ; move table 
value address to EEPROM
                                        ; address register LOWBYTE byte

    rcall    NEXT                        ; go grab next tabel address    
                       
    sbi EECR,EERE
    in    PWMSET,        EEDR                ; read data from EEPROM 
data register
    out    OCR1A,    PWMSET                    ; output to PWM control 
register

    ret                                    ; all done, go home   

;
;    timer interrupt handler
;

TIMER0:

    ldi    TEMP,    HIGHBYTE
    cp    HILOFLAG,    TEMP                ; LOWBYTE byte or HIGHBYTE/
    breq    HIGHBYTEFIX                    ; this is the LOWBYTE bytem 
go fix it for the HIGHBYTE byte

LOOP1:
    ldi    HILOFLAG,    LOWBYTE                ; reset for next LOWBYTE 
byte count
    out    OCR0A,     LOCOUNT                    ; reload the timer for 
the countdown, LOWBYTE byte

    rcall    TABLEDATA                    ; go do the output needed
   
    reti                                ; go to sleep until next timer 
interrupt

HIGHBYTEFIX:

    ldi    HILOFLAG,    HIGHBYTE                ; set flag to HIGHBYTE 
byte indicator
    out    TCNT1,    HICOUNT                    ; set the timer for the 
HIGHBYTE byte countdown
    rjmp    LOOP1                        ; now go finish interrupt handler

;
;    this is the main control loop, an infinite loop
;

MAIN:

;    rcall    TABLEDATA
    sleep
    rjmp    MAIN                        ; go back to sleep until next 
interrupt
                                        ; in other words, loop forever

    .exit

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.