[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] How to handle interrupt vectors ?
From: |
Luiz C. Bruscato |
Subject: |
Re: [avr-gcc-list] How to handle interrupt vectors ? |
Date: |
Wed, 29 Oct 2008 22:18:49 -0200 |
User-agent: |
KMail/1.9.9 |
/*
The following is an example of a ISR code, take a look the main for(;;)waits
indefinitely for an interrupt.
Thanks Joerg for the example.
Luiz C. Bruscato
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Joerg Wunsch wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you
think
* this stuff is worth it, you can buy me a beer in return. Joerg
Wunsch
* ----------------------------------------------------------------------------
*
* Demo combining C and assembly source files.
*
* This demo implements an RC model type PWM decoder. The incoming
* PWM signal consists of a pulse sequence with a pulse width of 920
* microseconds up to 2120 microseconds (1520 microseconds being the
* neutral point). Depending on the value of the decoded incoming
* PWM, an outgoing PWM is controlled between 0 and 100 %.
*
* The project is intented to be run on an ATtiny13 that has only one
* timer channel (timer 0), so both the incoming signal discrimination
* as well as the outgoing PWM need to run on the same timer.
*
* For verification purposes, the same project can also be run on an
* ATtiny25/45/85, where timer 1 can be used to evaluate the incoming
* PWM signal, and timer 0 to generate the outgoing PWM. In that
* case, no additional assembly code is needed.
*
* $Id: asmdemo.c,v 1.1.2.1 2006/08/29 19:48:39 joerg_wunsch Exp $
*/
/*
* This is the main C source file for the demo.
*/
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include "project.h"
volatile uint16_t pwm_incoming;
volatile struct
{
uint8_t pwm_received: 1;
}
intbits;
void
ioinit(void)
{
counter_hi = 0;
flags = 0;
/*
* Timer 0 runs as phase-correct PWM at full clock, OC0B connects to
* the PWM engine.
*/
TCCR0A = (1 << COM0B1) | (1 << WGM00);
TCCR0B = (1 << CS00);
OCR0A = 255;
#if defined(__AVR_ATtiny13__)
TIMSK0 = (1 << TOIE0) | (1 << OCIE0A);
# define F_CPU 1200000ul
/* Minimal PWM pulse width is 920 us. */
# define MIN_PWM_VAL ((920ul * F_CPU) / 1000000ul)
/* Maximal PWM pulse width is 2120 us */
# define MAX_PWM_VAL ((2120ul * F_CPU) / 1000000ul)
#elif defined(__AVR_ATtiny25__) ||\
defined(__AVR_ATtiny45__) ||\
defined(__AVR_ATtiny85__)
# define F_CPU 1000000ul
/*
* We use a prescaler of 16 here to avoid the 32-bit calculations
* below.
*/
/* Minimal PWM pulse width is 920 us. */
# define MIN_PWM_VAL ((920ul * F_CPU) / 16 / 1000000ul)
/* Maximal PWM pulse width is 2120 us */
# define MAX_PWM_VAL ((2120ul * F_CPU) / 16 / 1000000ul)
#else
# error "Don't know how to run on your MCU_TYPE."
#endif
PCMSK = (1 << 4);
GIFR = (1 << PCIF);
GIMSK = (1 << PCIE);
DDRB = (1 << PB1);
PORTB = 0;
sei();
}
#if defined(__AVR_ATtiny25__) ||\
defined(__AVR_ATtiny45__) ||\
defined(__AVR_ATtiny85__)
ISR(PCINT0_vect)
{
uint8_t tcnt1;
if (PINB & (1 << 4))
{
/* Start timer 1 with a prescaler of 16. */
TCNT1 = 0;
TCCR1 = (1 << CS12) | (1 << CS10);
return;
}
/* Stop timer 1, current value is pulse width. */
tcnt1 = TCNT1;
TCCR1 = 0;
GIMSK &= ~(1 << PCIE);
pwm_incoming = tcnt1;
intbits.pwm_received = 1;
}
#endif /* ATtinyX5 */
int
main(void)
{
ioinit();
for (;;)
{
if (intbits.pwm_received)
{
intbits.pwm_received = 0;
#if defined(__AVR_ATtiny13__)
if (pwm_incoming < MIN_PWM_VAL)
pwm_incoming = MIN_PWM_VAL;
else if (pwm_incoming > MAX_PWM_VAL)
pwm_incoming = MAX_PWM_VAL;
OCR0B = (pwm_incoming - MIN_PWM_VAL) * 255ul / (MAX_PWM_VAL -
MIN_PWM_VAL);
#else
OCR0B = (pwm_incoming - MIN_PWM_VAL) * 255u / (MAX_PWM_VAL -
MIN_PWM_VAL);
#endif
GIFR = (1 << PCIF);
GIMSK |= (1 << PCIE);
}
sleep_mode();
}
}
On Wednesday 29 October 2008 04:31:53 pm Joerg Wunsch wrote:
> Charalampos Alexopoulos <address@hidden> wrote:
> > Yes i have seen the code for the ISR and i have no understanding of
> > the mechanism because i don't know what that vector is.
>
> I have already explained you that, and you can take my word that you
> don't stand a chance using the existing gcrt1.S file. That's not to
> say it could not be done at all, but you'd have to start over from
> scratch, writing your own C run-time startup code in a different way
> than the existing code is done.
>
> You could perhaps seek up some old (maybe about 4 years old)
> suggestion from Marek Michalkiewicz about what changes would be needed
> in order to allow for arbitrarily-named interrupt vectors. Offhand, I
> can't tell you though whether it has been discussed here on
> avr-gcc-list, or on avr-libc-dev instead.
- Re: [avr-gcc-list] How to handle interrupt vectors ?,
Luiz C. Bruscato <=