Gerade beschäftige ich mich mit verschiedenen Programmen für meinen MotorMega32. Dieser soll folgende Funktionen können:
- Batteriespannung AD einlesen und als Bargraph anzeige ausgeben (10 gelbe LEDs)

- 2 Sharp IR Sensoren (vorn und hinten) auslesen und Wert über RS232 ausgeben

- Motorstrom für Motor 1 und 2 ausgeben über RS232

- Kommunikation über I²C mit MainController

- Status und Notaus LED ansteuern

- 2 Motoren mit L298 steuern.

Soweit bin ich jetzt und jedes der Module funktioniert für sich und in der Summe wunderbar.

ABER:

Ich schaff es nicht die beiden Inkrementalgeber auszulesen und den Wert anzeigen zu lassen. Aus einem alten Projekt hab ich mir nochmal die Interrupt Routine angesehen für einen Inkrementalgeber (leider ist der Code damals nicht von mir geschrieben worden), ich schaffs aber nicht diesen Code auf zwei Interruptquellen zu erweitern.

Jetzt hoffe ich, dass einer von euch, dieses Problem schon einmal gelöst hat oder zumindest weis wo ich suchen muss, ich komm nämlich nimmer weiter. Vermutlich haben es schon tausende vor mir gemacht da zwei Inkrementalgeber einlesen nicht so exotisch ist. Ich find aber nichts.

Hier noch der Code den ich bisher verwende für 1 Quelle. Zukünftig würde ich gerne die Quellen INT0 und INT1 (Port PD2 und PD3 am Mega32) verwenden:

Code:
/*
Autor: Daniel Reitmair
Datum: 14.12.2008
Vers.: 1.0
*/

#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/delay.h>

#define BAUD        19200UL
#define F_CPU       7372800UL
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)


//Globale Variablen
//*****************

	int32_t durchSens_counter = 0;	//Counter fuer Durchflusssensor
	int8_t timer_counter = 0;		//Counter fuer Timer_IRQ jede 1sec.
	int impulse = 0; 

static int
uart_putchar(char c, FILE *stream)
{
	// ... warten bis der Sendepuffer leer ist ...
    while ( !( UCSRA & (1<<UDRE)) )
        ;
	UDR = c;
	
	return 0;
}


static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);

void IRQ_init(void){
//IRQ initialisieren

	//SREG = Status Register
	//I (bit 7) = Global Interrupt Disable
	//SREG |= (0<<7);
	// alle Interrupts abschalten
	cli();

	//externen IRQ setzen
	//===================
	//GICR = General Interrupt Control Register
	//External Interrupt Request Disable fuer INT2
	GICR |= (0<<INT2); 

	//MCUCSR = MCU Control and Status Register
	//ISC2 = Interrupt Sense Control 2: 0= falling edge; 1=rising edge auf PB2(INT2/AIN0)
	MCUCSR |= (1<<ISC2);

	//GIFR = General Interrupt Flag Register
	//INTF2 = External Interrupt Flag 2: Loeschen mit logischer 1
	GIFR |= (1<<INTF2);

	//External Interrupt Request Enable
	GICR |= (1<<INT2);

	//Timer Overflow IRQ setzen
	//=========================
	TIMSK |= (1<<TOIE0);	//Timer Overflow Enable


	//SREG = Status Register
	//I = Global Interrupt Enable
	//SREG |= (1<<7);
	//alle Interrupts erlauben
	sei();

}


void uart_init(void)
{
    // Baudrate einstellen ( Normaler Modus )
    UBRRH = (unsigned char) (UBRR_BAUD>>8);
    UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);

    // Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts
    UCSRB = (1<<RXEN)|(1<<TXEN);

    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}


//IRQ fuer Durchflussensor
ISR(INT2_vect){
	durchSens_counter++;
}

ISR(TIMER0_OVF_vect){
//IRQ fuer Counter Overflow

	uint8_t tmp_SREG;

	timer_counter++;
		
	if (timer_counter == 125){
		tmp_SREG = SREG;
		cli();					// IRQ frei ausfuehrung des folgenden Programmcodes
		

		//Durchflusssensor
		// pumpe_steuern();
		impulse = durchSens_counter; 
		durchSens_counter = 0; 
			
		timer_counter = 0;		// Counter Variable Reset
		// PORTB |= PINB ^ (1<<PB4);

		SREG = tmp_SREG;		// Status register wiederherstellen
		

		TCNT0 = 6;				// Counter Register auf 6 setzen; zaehlen von 6 bis 255
		SFIOR |= (0<<PSR10);	// Counter Reset
			
	}	
}



void IO_init(void){
	//PB2: Eingang für IRQ (Durckflussensor)
	//PB4: Ausgang für rote LED
	//PB3: Ausgang für grüne LED 
	DDRB = (0 << DDB2) | (1<<DDB4) | (1 << DDB3);

	//Timer/Counter Control Register 0
	//WGM00 und WGM01: Counter im Normalmodus zaehlen
	//CS02, CS01 und CS00: Prescale auf 256
	//TCCR0 |= (0<<WGM00) | (0<<WGM01) | (0<<COM01) | (0<<COM00) | (1<<CS02) | (0<<CS01) | (0<<CS00);
	TCCR0 = (1<<CS02) | (0<<CS01) | (0<<CS00);

	//Timer/Counter Register 0
	TCNT0 = 6;	// Wert mit 6 init --> zählen von 6 bis 255 --> nach 125 Counter Overflow ist 1 sec vorrueber

}



int main (void){

	IRQ_init();
	IO_init();
	uart_init();
    

	PORTB |= (1<<PB3); // Grün

	stdout = &mystdout;
    
	uint16_t value = impulse; 
	    

	while(1){ 
	 	value = impulse / 10; // Value in ml
	 	
		printf_P(PSTR("Der Wert des Sensors betraegt: %i ml/s \n \r "), value);
	 	_delay_ms(2000); 

		

	}
}
Bitte helft mir, damit ich Wall E fahren lassen kann!