Hi,
probier hier jetzt schon seit einer Weile mit einem Atmega8 auf einem STK500 und einem ADXl202 Beschleunigungssensor rum.
die Analogen Signale die aus dem ADXl kommen konnte ich shcon auswerten, jetzt woltl ich mal probieren die PWM Signale die der ADXL ausgibt mir gilfe des Atmega8 auszuwerten, aber irgendwie klappt das alles nicht.
Wahrscheinlich habe ich nur irgendwelche Register falsch gesetzt.
so wie ich es der Beschreibung entnhemen konnte habe ich folgende Register gesetzt:
DDRB = 0xff;
PORTB = 0xff;
DDRD = 0xff; //für die Ausgabe über LEDs
PORTD = 0xff;
ACSR = (1<<ACIC);
TCCR1B |= (1<<WGM13); // fallende Flanke
//TCCR1B = (1<<ICES1); // steigende Flanke
while(TIFR & (1<<ICF1)); //warten bis das ICF1 Flag gesetzt
wurde
result= ICR1L; //lesen der Werte
result1= ICR1H;
if(result>>0 & 0x01) //ausgabe der WErte über
LEDs
PORTD &= ~(1<<PD0);
if(result>>1 & 0x01)
PORTD &= ~(1<<PD1);
if(result>>2 & 0x01)
PORTD &= ~(1<<PD2);
if(result>>3 & 0x01)
PORTD &= ~(1<<PD3);
if(result>>4 & 0x01)
PORTD &= ~(1<<PD4);
if(result>>5 & 0x01)
PORTD &= ~(1<<PD5);
if(result>>6 & 0x01)
PORTD &= ~(1<<PD6);
if(result>>7 & 0x01)
PORTD &= ~(1<<PD7);
bin über jede hilfe dankbar
So ist es.Zitat von Grave80
Zitat von Grave80Das ist nicht was du willst. Ich vermute mal, du willst dem ICP1 (PB0) als Eingang verwenden, und nicht den AIN0/AIN1 (PD6/PD7), den du zudem als Ausgang geschaltet hast.Zitat von ATMega8:199
Der ICP1 (PB0) muss als Eingang geschaltet werden, nicht als Ausgang. Sonst schmort's im Mega8 oder im ADXL -- oder in beiden.Zitat von --bugfix--
Vor du den InputCapture musst du nochZitat von --bugfix--
Zitat von --bugfix--Zitat von --bugfix--Das alleine reicht für eine PWM-Auswertung aber noch nicht, es sind nur ein paar Bausteine, die du brauchen wirst. Am besten geht so was in einer ISR:Zitat von --bugfix--
Das nur als Vorschlag. Das ist ein ad-hoc-Code und nicht getestet.Code:#include <avr/signal.h> #include <avr/interrupt.h> ... volatile uint8_t icr1_update = 0; uint16_t _icr1_hi, _icr1_low; uint16_t icr1_hi, icr1_low; ... { ... TIMSK = _BV (TICIE1); sei(); while (1) { while (0 == icr1_update) ; cli(); icr1_hi = _icr1_hi; icr1_low = _icr1_low; icr1_update = 0; sei(); PORTD = icr1_low & 0x00ff; } } SIGNAL (SIG_INPUT_CAPTURE1) { TCNT1 = 0; uint8_t tccr1b = TCCR1B; if (tccr1b & _BV(ICES1)) _icr1_low = ICR1; else _icr1_hi = ICR1; TCCR1B = tccr1b ^ _BV(ICES1); TIFR |= _BV(ICF1); icr1_update = 1; }
Disclaimer: none. Sue me.
Hi Sprinter,
danke für deine Antwort, eine Antwort kommt so spät weil ich etwas arg im stress war die letzten Tage, doch jetzt hab ich mich damit mal wieder beschäftigt.
Habs jetzt erstmal soweit geschafft das überhaupt schon mal was flakert, kann ja den Code hier mal posten, auf das ihr mir vielleicht noch etwas unter die arme greifen könn/würdet wie auch immer.mfG der GraveCode:#include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> int main(void) { int T1,T2; DDRB &= ~(1<<PB0); PORTB &= ~(1<<PB0); DDRD = 0xff; //für die Ausgabe über LEDs PORTD = 0xff; while(1) { //ACSR &= ~(1<<ACIC); //Zähler starten ohne vorteiler TCCR1B = 0; TCCR1B |= (1<<CS10); TCCR1B |= (1<<ICES1); TCCR1B |= (1<<ICNC1); sei(); TIMSK = (1<<TICIE1); //Interrupt für ICP sei(); //einschalten für erste messung //nach der ersten flanke wird der timer gestartet //nach der zweiten Flanke ist die Periodendauer //ermittelt //es wird der gespeicherte wert aus dem ICR1 //register zur berechnung verwendet while(TIFR & (1<<ICF1)); TCCR1B = 0; //Zähler stoppen TCNT1= 0; T1=T2=0; T1 = ICR1; T2 = ICR1H; TIFR &= ~(1<<ICF1);// oder das hier beides TIMSK = 0; // nach unten if(T1>>0 & 0x01) PORTD &= ~(1<<PD0); if(T1>>1 & 0x01) PORTD &= ~(1<<PD1); if(T1>>2 & 0x01) PORTD &= ~(1<<PD2); if(T1>>3 & 0x01) PORTD &= ~(1<<PD3); if(T1>>4 & 0x01) PORTD &= ~(1<<PD4); if(T1>>5 & 0x01) PORTD &= ~(1<<PD5); if(T1>>6 & 0x01) PORTD &= ~(1<<PD6); if(T1>>7 & 0x01) PORTD &= ~(1<<PD7); } }
Wenn du ohne ISR arbeitest, dann wird irgendwann eine IRQ ausgelöst und du landest im Nirvana, genauer bei __bad_interrupt, was auf einen Soft-Reset angebildet wird.
Wenn du sei() benutzt, musst du ISRs für alle IRQs zur Verfügung stellen, die auftreten können (hier: SIG_INPUT_CAPTURE1).
Offenbar willst du aber erst mal ohne Interrupts arbeiten.
Dann wirf das sei() raus und lass erst mal die Finger von TIMSK
Bevor du auf das ICF1-Flag wartest, musst du es erst mal rücksetzen auf 0. Des geht, indem man eine 1 hinschreibt wie oben gesagt. Die anderen Flags werden nicht angefasst durch das 0-Schreiben.
TIFR = _BV(ICF1);
Danach wartest du:
while (!(TIFR & _BV(ICF1))) // Flag==0 --> *schnarch*
...
Dann wirst du die Flanke umschalten wollen, falls du nicht auf beide Flanken konfiguriert hast.
Nach dem Flanken-Umschalt und vor dem nächsten Warten: wieder ICF1 resetten.
Disclaimer: none. Sue me.
so habs das wochenden endlich mal alles zum laufen gebracht und funktioniert jetzt prima, danke für deine Hilfe
mfg der Grave
Hat das Auswerten von PMW-Signalen einen Vorteil gegenüber den Werten der Analogausgänge?
Lesezeichen