avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Timer Overflow interrupt problem


From: Bart Friederichs
Subject: [avr-gcc-list] Timer Overflow interrupt problem
Date: Wed, 21 Apr 2004 10:45:13 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040117

Hi,

I have been doing some experimenting with external and counter overflow interrupts, and I am stuck now on the last one. I think I do everything I need to do (according to the docs, both the ATMega16 datasheet and the avr-libc documentation example), but it seems like the interrupt is never called. I had some problems earlier with the external interrupt, and found out that it is not possible to set output ports (something to do with a taskswitch?)

I included the code that is not working verbatim. There are some things still in there, that do something with external interrupts. Ignore them. I haven't tested them, don't if it works or not (of course, if you find an error, please tell me;-)).

Thanks in advance
Bart Friederichs


---------------------- CODE STARTS HERE -------------------------------
/*
* project: robotwars
* file: receiver.c version 0.1
* author: bart friederichs
*
* Signal processing of the receiver:
* o Reading of the four channels of the receiver
* o Test of quality of signal
*/

/* calculation of prescaler bits:
* We want a scale of 0-255 for each channel, which gives us
* 1ms/256 = 1/256ms per step. When running at 8 MHz, the
* prescaler gives us:
* 1/1          0.125 us
* 1/8          1.000 us = 1/1000ms
* 1/64         8.000 us = 1/125ms
* 1/256        64.00 us
* 1/1024       125.0 us = 1/8ms
*
* The prescaler is set to 1/8, so the steps are accurate enough,
* we will be off by maximum of 4. When the signal length will be
* 2ms (maximum ON), the counter will be 2000. The longest OFF
* length will be 20ms - (4*1ms) = 16ms, which yields to 26000 in
* the counter. The 16 bits register will be very pleased to hold
* these magical numbers.
*/

#include "receiver.h"
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>

/* Volatile environment:
* sigN: signal register for channel N
* (sig5 is the whitespace counter after channel 4)
* errorN: error counter per channel
* channel_select: selection of the channel
* signal_flags:
*   bit0  : signal_ok
*   bit1-7: reserved
* ctr0: overflow counter
*/
volatile unsigned int signals[5];
volatile unsigned char channel_select, signal_flags;
volatile unsigned char errors[5];
volatile unsigned int ctr0;

/* Interrupt 0 is the pin on which the signal is
* connected to the uC. Whenever this gets HI, an
* interrupt is triggered and the correct register is
* being (re)set
*/
SIGNAL (SIG_INTERRUPT0) {
 /* save counter state and reset counter */
 signals[channel_select] = TCNT1;
/* pretty bare error detection:
  * the OFF period after channel 4 cannot exceed 16ms
  * the pulse widths per channel cannot exceed 2 ms
  */
 if (channel_select == 4)
   if (signals[channel_select] > 16000) errors[channel_select]++;
 else
   if (signals[channel_select] > 2000) errors[channel_select]++;
TCNT1 = 0x0000; /* start counting for next channel */
 if (++channel_select > 4)
   channel_select = 0;

}

SIGNAL (SIG_OVERFLOW0) {
/*  ctr0++;*/
   ctr0 = 0;
}

/* Initialise all the registers, counters and other
* players
*/
void main() {
 /* disable interrupts, we don't want them messing
  * with our initialisation */
 cli();

 /* init regs */
channel_select = 4; /* so the receiver starts with ch0 */
 signals[0] =
   signals[1] =
   signals[2] =
   signals[3] =
   signals[4] = 0;
/* init external interrupts */
 MCUCR = (1<<ISC00)|(1<<ISC01);        /* INT0 is RISING int */
 GICR = (1<<INT0);                     /* enable INT0 */

 /* init counter 1 */
 TCCR1B = (1<<CS11);                   /* prescaler 1/8 */

 /* init counter 0 */
 TCCR0 = (1<<CS00); /* | (1<<CS02);*/  /* prescaler 1/1024 */
 TIMSK = (1<<TOIE0);                   /* int enable overflow counter 0 */
 TCNT0 = 0x0F;
 ctr0 = 1;

 /* i/o ports
  * B0:2  channel_select to mux
  * B3    buzzer
  */
 DDRA = 0xFF;                          /* all OUT */
 DDRB = 0xFF;                          /* all OUT */
 PORTB = 0x00;

 sei();                                /* enable interrupts */
 run();
}

/* the loop */
void run() {
 while (1) {
   PORTA = ctr0;
 }
}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]