PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Externe Interrupts



BomberD
11.11.2004, 11:11
Hi,

der AVR ATMega hat ja nur 2 externe Interrupt-Quellen. aber ich möchte zwischen 6 und 8 Ereignisse per interrupt abfangen.
Es wird, so meine Idee, mit dem schalten des Pins gleichzeitig der Int ausgelöst. (zur zeit drücke ich erst den Pin Taster auf dem STK board und dann löse ich den Int aus)
Also hab ich mir gedacht ich kann doch im der Interrupt Behandlung abfragen welcher Pin zusammen mit dem Int geschaltet ist.

Hierzu der Quellcode:


SIGNAL(SIG_INTERRUPT0){
/*if(PORTB==0x00)
PORTB=0xff;
else
PORTB=0x00;*/
//todo: 6 Tasten abfgragen, welche den int ausgelöst hat. und entsprechende LED Anschalten
if(PORTD&(1<<PD3)) PORTB=0x08; //PortB Pin 4
else if(PORTD&(1<<PD4)) PORTB=0x10; //PortB Pin 5
else if(PORTD&(1<<PD5)) PORTB=0x20; //PortB Pin 6
else if(PORTD&(1<<PD6)) PORTB=0x40; //PortB Pin 7
else if(PORTD&(1<<PD7)) PORTB=0x80; //PortB Pin 8
}

Leider bewirken die If Anweisungen keine Änderung bei der anzeige der LED's.
Der interrupt wird ausgeführt. das seh ich daran, dass die oben auskommentierten komandos ausgeführt werden.

Wo hab ich mich vertan? Geht meine Idee überhaupt?

Dino Dieter
11.11.2004, 11:21
Hallo

Eingänge werden über PIND eingelsen.

MFG
Dieter

BomberD
11.11.2004, 11:25
Hi,

Danke. Das wusste ich echt nicht :(

11.11.2004, 11:45
Wenn die Pins auf Eingang geschalten sind, dann kann man über PORT*= den Pullup Widerstand einschalten.

BomberD
11.11.2004, 11:51
Huhu,

Es war noch ein wenig mehr.
Beim STK500 sind irgendwie die Ein- und Ausgänge negiert.
Also hats zuerst mit deinem Tipp allein nicht geklappt.

hier jetzt der lauffähige Code.


#include <avr/io.h>
#include "SeriellBiblio.h"
#include <progmem.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/string.h>
//Arbeitstakt angeben
#define SYSCLK 8000000UL

//usart ansprechen

volatile unsigned char *data[12];
//volatile unsigned char *pdata=data[0];
volatile int count=0;
volatile int i;
volatile unsigned char b;

void timer (void){
TIMSK = _BV(TOIE0); //overflow flag setzen--> ab jetzt kan overflow interrupt ausgelöst werden
TCNT0 = 0; //Rücksetzen des Timers
TCCR0 = _BV(CS02); //Prescaler 256
sei (); //interrupts ein
}

void TasterInt(void){
MCUCR = _BV(ISC01); //interrupt bei fallender Flanke
GIMSK = _BV(INT0); //interrupt an
}

int main(void) {
i=0;
b='0';
USART_Init ();
timer ();
TasterInt();
//sei();
//unsigned char data = 0;
DDRB = 0xff;
PORTB = 0xff;//PortB = Ausgabe
DDRD = 0x00;//PortD = Eingabe
PORTD = 0xff;//alle Pullups ein
for (;;) {
//data = USART_receive ();
//darf erst vergleichen wenn nicth mehr gesendet wird... hmmm
if(b=='1'){
if (strstr((char*)data, "1\n")){
PORTB = 0x00;
//data[]="";
}
else if (strstr((char*)data, "0\n")){
PORTB = 0xff;
//data="";
}
else if (strstr((char*)data, "Steffen")){
USART_transmit_string("Hallo Steffen");//(char*)data
//data="";
}
else if (strstr((char*)data, "Jana")){
USART_transmit_string("Hallo Jana");//(char*)data
//data="";
}
PORTB|=(1<<PB7);
b='0';
}
}
return 0;
}
//intterrupt wenn byte empfangen
SIGNAL (SIG_UART_RECV){
PORTB&=~(1<<PB7);
unsigned char temp=UDR;
*data[i++]=temp;//hänge neues byte an
if (temp=='\n'){
b='1'; //prüft ob Receive complete
i=0;
}
}

//lässt led blinken
SIGNAL (SIG_OVERFLOW0) {
count++;
if (count==4){
if(PORTB & (1<<PB0)){
PORTB&=~(1<<PB0);
count=0;
}
else{
PORTB|=(1<<PB0);
count=0;
}
}
}

//interruptmethode für externen interrupt 0
SIGNAL(SIG_INTERRUPT0){
/*if(PORTB==0x00)
PORTB=0xff;
else
PORTB=0x00;*/
//todo: 6 Tasten abfgragen, welche den int ausgelöst hat. und entsprechende LED Anschalten
if(!(PIND&(1<<PD3))) PORTB=0xF7; //PortB Pin 4
else if(!(PIND&(1<<PD4))) PORTB=0xEF; //PortB Pin 5
else if(!(PIND&(1<<PD5))) PORTB=0xDF; //PortB Pin 6
else if(!(PIND&(1<<PD6))) PORTB=0xBF; //PortB Pin 7
else if(!(PIND&(1<<PD7))) PORTB=0x7F; //PortB Pin 8
}


Danke dir. Hab grad entsprechend deinem Hinweis gelesen :
Bei Mikrocontroller.net (http://www.mikrocontroller.net/wiki/AVR-GCC-Tutorial#Eing.E4nge_.28Wie_kommen_Signale_in_den_. B5C.29)

churchi
11.11.2004, 15:18
Wenn die Pins auf Eingang geschalten sind, dann kann man über PORT*= den Pullup Widerstand einschalten.

das war ich - hab in der Schule vergessen mich einzuloggen... #-o

BomberD
12.11.2004, 05:35
Geht mir auch manchmal so ;)
Es gibt wohl zu viele PC's in meinem Leben *g*.