1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-01-18 07:52:14 +01:00

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 TWO_PI LITERAL1
LSBFIRST LITERAL1 LSBFIRST LITERAL1
MSBFIRST LITERAL1 MSBFIRST LITERAL1
CHANGE LITERAL1
FALLING LITERAL1
RISING LITERAL1
false LITERAL1 false LITERAL1
true LITERAL1 true LITERAL1
null LITERAL1 null LITERAL1
@ -141,6 +144,8 @@ digitalRead KEYWORD2
pinMode KEYWORD2 pinMode KEYWORD2
analogRead KEYWORD2 analogRead KEYWORD2
analogWrite KEYWORD2 analogWrite KEYWORD2
attachInterrupts KEYWORD2
detachInterrupts KEYWORD2
beginSerial KEYWORD2 beginSerial KEYWORD2
serialWrite KEYWORD2 serialWrite KEYWORD2
serialRead KEYWORD2 serialRead KEYWORD2

View File

@ -47,6 +47,9 @@ UPDATES
0007 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 Replaced avr-lib's uart routines with custom code for handling serial
communication and modified C++ serial commands to call the C serial commands, 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 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,14 +420,15 @@ SIGNAL(SIG_OVERFLOW0)
unsigned long millis() unsigned long millis()
{ {
// timer 0 increments every 64 cycles, and overflows when it reaches 256. // timer 0 increments every 64 cycles, and overflows when it reaches
// we would calculate the total number of clock cycles, then divide by the // 256. we would calculate the total number of clock cycles, then
// number of clock cycles per millisecond, but this overflows too often. // divide by the number of clock cycles per millisecond, but this
// overflows too often.
//return timer0_overflow_count * 64UL * 256UL / (F_CPU / 1000UL); //return timer0_overflow_count * 64UL * 256UL / (F_CPU / 1000UL);
// instead find 1/128th the number of clock cycles and divide by 1/128th // instead find 1/128th the number of clock cycles and divide by
// the number of clock cycles per millisecond // 1/128th the number of clock cycles per millisecond
return timer0_overflow_count * 64UL * 2UL / (F_CPU / 128000UL); return timer0_overflow_count * 64UL * 2UL / (F_CPU / 128000UL);
} }
void delay(unsigned long ms) void delay(unsigned long ms)
@ -607,9 +608,9 @@ int main(void)
// enable a2d conversions // enable a2d conversions
sbi(ADCSRA, ADEN); sbi(ADCSRA, ADEN);
// the bootloader connects pins 0 and 1 to the USART; disconnect them here // the bootloader connects pins 0 and 1 to the USART; disconnect them
// so they can be used as normal digital i/o; they will be reconnected in // here so they can be used as normal digital i/o; they will be
// Serial.begin() // reconnected in Serial.begin()
#if defined(__AVR_ATmega168__) #if defined(__AVR_ATmega168__)
UCSR0B = 0; UCSR0B = 0;
#else #else

View File

@ -51,6 +51,10 @@ extern "C"{
#define LSBFIRST 0 #define LSBFIRST 0
#define MSBFIRST 1 #define MSBFIRST 1
#define CHANGE 1
#define FALLING 2
#define RISING 3
#define min(a,b) ((a)<(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x)) #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 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 setup(void);
void loop(void); void loop(void);
@ -117,6 +124,13 @@ extern pin_t *digital_pin_to_port;
extern pin_t *analog_in_pin_to_port; extern pin_t *analog_in_pin_to_port;
extern int *analog_out_pin_to_timer; 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 #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif