attachInterrupt() and detachInterrupt(): from Wiring, with changes to automatically enable and disable the relevant interrupt and to specify the trigger.

This commit is contained in:
David A. Mellis 2006-11-24 17:12:32 +00:00
parent b3d300dd35
commit 514a74849a
5 changed files with 118 additions and 9 deletions

View File

@ -11,6 +11,9 @@ HALF_PI LITERAL1
TWO_PI LITERAL1
LSBFIRST LITERAL1
MSBFIRST LITERAL1
CHANGE LITERAL1
FALLING LITERAL1
RISING LITERAL1
false LITERAL1
true LITERAL1
null LITERAL1
@ -141,6 +144,8 @@ digitalRead KEYWORD2
pinMode KEYWORD2
analogRead KEYWORD2
analogWrite KEYWORD2
attachInterrupts KEYWORD2
detachInterrupts KEYWORD2
beginSerial KEYWORD2
serialWrite KEYWORD2
serialRead KEYWORD2

View File

@ -47,6 +47,9 @@ UPDATES
0007
Added attachInterrupt() and detachInterrupt() functions for handling of
external interrupts on pins 2 and 3.
Implemented shiftOut() routine; see reference for details.
Replaced avr-lib's uart routines with custom code for handling serial
communication and modified C++ serial commands to call the C serial commands,
saving ~1 KB of space; the code may behave slightly differently in border

86
targets/arduino/WInterrupts.c Executable file
View File

@ -0,0 +1,86 @@
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Wiring project - http://wiring.uniandes.edu.co
Copyright (c) 2004-05 Hernando Barragan
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
Modified 24 November 2006 by David A. Mellis
*/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include "WConstants.h"
volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
// volatile static voidFuncPtr twiIntFunc;
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
intFunc[interruptNum] = userFunc;
if (interruptNum == 0) {
MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
GICR |= (1 << INT0);
} else {
MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
GICR |= (1 << INT1);
}
}
}
void detachInterrupt(uint8_t interruptNum) {
if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
if (interruptNum == 0)
GICR &= ~(1 << INT0);
else
GICR &= ~(1 << INT1);
intFunc[interruptNum] = 0;
}
}
/*
void attachInterruptTwi(void (*userFunc)(void) ) {
twiIntFunc = userFunc;
}
*/
SIGNAL(SIG_INTERRUPT0) {
if(intFunc[EXTERNAL_INT_0])
intFunc[EXTERNAL_INT_0]();
}
SIGNAL(SIG_INTERRUPT1) {
if(intFunc[EXTERNAL_INT_1])
intFunc[EXTERNAL_INT_1]();
}
/*
SIGNAL(SIG_2WIRE_SERIAL) {
if(twiIntFunc)
twiIntFunc();
}
*/

View File

@ -420,13 +420,14 @@ SIGNAL(SIG_OVERFLOW0)
unsigned long millis()
{
// timer 0 increments every 64 cycles, and overflows when it reaches 256.
// we would calculate the total number of clock cycles, then divide by the
// number of clock cycles per millisecond, but this overflows too often.
// timer 0 increments every 64 cycles, and overflows when it reaches
// 256. we would calculate the total number of clock cycles, then
// divide by the number of clock cycles per millisecond, but this
// overflows too often.
//return timer0_overflow_count * 64UL * 256UL / (F_CPU / 1000UL);
// instead find 1/128th the number of clock cycles and divide by 1/128th
// the number of clock cycles per millisecond
// instead find 1/128th the number of clock cycles and divide by
// 1/128th the number of clock cycles per millisecond
return timer0_overflow_count * 64UL * 2UL / (F_CPU / 128000UL);
}
@ -607,9 +608,9 @@ int main(void)
// enable a2d conversions
sbi(ADCSRA, ADEN);
// the bootloader connects pins 0 and 1 to the USART; disconnect them here
// so they can be used as normal digital i/o; they will be reconnected in
// Serial.begin()
// the bootloader connects pins 0 and 1 to the USART; disconnect them
// here so they can be used as normal digital i/o; they will be
// reconnected in Serial.begin()
#if defined(__AVR_ATmega168__)
UCSR0B = 0;
#else

View File

@ -51,6 +51,10 @@ extern "C"{
#define LSBFIRST 0
#define MSBFIRST 1
#define CHANGE 1
#define FALLING 2
#define RISING 3
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
@ -89,6 +93,9 @@ unsigned long pulseIn(int pin, int state);
void shiftOut(int dataPin, int clockPin, int endianness, byte val);
void attachInterrupt(uint8_t, void (*)(void), int mode);
void detachInterrupt(uint8_t);
void setup(void);
void loop(void);
@ -117,6 +124,13 @@ extern pin_t *digital_pin_to_port;
extern pin_t *analog_in_pin_to_port;
extern int *analog_out_pin_to_timer;
#define EXTERNAL_INT_0 0
#define EXTERNAL_INT_1 1
#define EXTERNAL_NUM_INTERRUPTS 2
typedef void (*voidFuncPtr)(void);
#ifdef __cplusplus
} // extern "C"
#endif