PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit INT0 ATtiny84A



_Lupo_
06.09.2021, 09:55
Leider bekomme ich nachstehendes Programm auch nach Durchsicht aller Forums Beiträge/Tutorials nicht zum laufen.

Mit dem Programm soll die Dauer von RC-Impulse gemessen werden.

Zum Einsatz kommt ein ATtiny84 zum Einsatz. Programmiert wird mit Atmel Studio 7.

Nun zu meinem Code:


/********** ATtiny84A 8MHz ***************/



#include<avr/io.h>
#include <avr/interrupt.h>




#define F_CPU 8000000UL




uint16_t start_puls,end_puls,laenge_puls;
uint8_t steigend, fallend;




void init_timer_0 (void)
{
TCCR0A = 0x00;
TCCR0B = (1<<CS01) + (1<<CS00);
TIMSK0 = (1<<TOIE0) ;
TCNT0 =131;




}




void init_timer_1(void)
{
TCCR1A=0x00;
TCCR1B= (1<<CS11);

}


ISR (INT0_vect)
{
if (steigend == 1)
{
start_puls=TCNT1;
steigend=0;
MCUCR |= (1<<ISC01);
MCUCR &= ~(1<<ISC00);
}
else
{
end_puls=TCNT1;
laenge_puls=end_puls-start_puls;
steigend=1;
MCUCR |= (1<<ISC01);
MCUCR |= (1<<ISC00);
}

}

int main(void)
{
init_timer_1();

DDRA = 0xFF;

DDRB &= ~(1<<PORTB2);
MCUCR |= (1<<ISC01) | (1<<ISC00); // INT0 auf steigende Flanke
GIMSK |= (1<<INT0);

sei();

while(1)
{
if (laenge_puls<1300)
{
PORTA = 0b00000001;
}
if ((laenge_puls>1300)&&(laenge_puls<1700))
{
PORTA = 0b00000010;
}
if(laenge_puls>1700)
{
PORTA = 0b00000100;
}
}
}




Hoffe es findet sich jemand, der so freundlich ist und mir weiter hilft.

oberallgeier
06.09.2021, 11:15
.. PORTA = 00000001; .. PORTA = 00000010; .. PORTA = 00000100; ..Hmmm. Nullen sind nur am Konto und bei Managern wichtig - umso besser (wichtiger), je mehr Nullen dahinter stehen.

Meine Frage, bevor ich weiter lese oder überlege: das sollten doch binäre Zahlen (dann z.B. PORTB = 0b11001111.;.) sein oder sind das Dezimalzahlen? Wenn dez - wozu dann die führenden Nullen? Und - WENN "PORTA = 00000100;" dann ist PA6 high, PA5 high und PA2 high. Sprich: PORTA = 0b01100100 !

wkrug
06.09.2021, 14:08
Also erstmal sollte die Interrupt Routine vor der main Routine stehen, weil er sonst evtl nicht richtig initialisiert wird.
Zum zweiten dürfte ISC 1 - 1 nicht funktionieren.
Wenn Ich mich recht entsinne bleibt dabei der Controller in der Interrupt Schleife hängen so lange an dem Interrupt Port eine 1 anliegt.

Schalte das Interupt sensing auf 0 - 1 ( = steigende Flanke ) dann wird der Controller auf die steigende Flanke reagieren.
In dieser Interrupt Routine schaltest Du dann das sensing auf 1 - 0.
Der Controller reagiert dann auf die fallende Flanke und Du kannst die Zeit des Impulses ermitteln.
Die Interrupt Routine wird also in 2 Teilen programmiert und das Sensing bei jedem Aufruf umgeschaltet.

Für solche Zwecke gibt's aber auch den Input Capture Interrupt - Wenn Dein ATTINY84 den hat ( Datenblatt!? ) .
Da wird dann gleich der aktuelle TCNT Zählerstand im Input Capture Register gespeichert und somit Jitter vermieden.

_Lupo_
06.09.2021, 16:05
Erst mal Herzlichen Dank für die schnellen Antworten. Wieso das "0b" verschwunden ist ??????????????????????? ,war im Orginal Code richtig, Die Sache mit dem Interrupt sensig ist mir noch unklar, meine dies mit den entsprechenden Zuweiungen im MCUCR Register (ISC01 und 1<<ISC00) zu machen, oder?
Es ist mir aufgefallen das nach dem Build folgende Warnmeldung erscheint " 'INT0_vect' appears to be a misspelled signal handler, missing __vector prefix [-Wmisspelled-isr] ".
Den INT0 Interrupt hab ich verschoben, ohne Auswirkung.
Das Programmlisting am Anfang habe ich entsprechen aktualisert.
Habe im Moment wohl ein Brett vorm Kopf.

Holomino
06.09.2021, 16:47
Dann kann eigentlich nur ein in der IDE falsch ausgewählter Controllertyp (falsche inkludierte Header-Datei) oder eine veraltete Header-Datei die Ursache sein.

Bei mir in der iotnx4.h ist der Vektor allerdings auch mehrfach deklariert:
#define INT0_vect _VECTOR(1)
#define EXT_INT0_vect _VECTOR(1)
#define SIG_INTERRUPT0 _VECTOR(1)

wkrug
06.09.2021, 18:33
Also im Simulator funktioniert es bei mir!

/*
* Servopuls.cpp
*
* Created: 06.09.2021 19:19:49
* Author : USER
*/

/********** ATtiny84A 8MHz ***************/



#include<avr/io.h>
#include<avr/interrupt.h>




#define F_CPU 8000000UL




uint16_t start_puls,end_puls,laenge_puls;
uint8_t steigend, fallend;




void init_timer_0 (void)
{
TCCR0A = 0x00;
TCCR0B = (1<<CS01) + (1<<CS00);
TIMSK0 = (1<<TOIE0) ;
TCNT0 =131;




}




void init_timer_1(void)
{
TCCR1A=0x00;
TCCR1B= (1<<CS11);

}


ISR (INT0_vect)
{
if (steigend == 1)
{
start_puls=TCNT1;
steigend=0;
MCUCR |= (1<<ISC01);
MCUCR &= ~(1<<ISC00);
}
else
{
end_puls=TCNT1;
laenge_puls=end_puls-start_puls;
steigend=1;
MCUCR |= (1<<ISC01);
MCUCR |= (1<<ISC00);
}

}

int main(void)
{
init_timer_1();

DDRA = 0xFF;

DDRB &= ~(1<<PORTB2);
MCUCR |= (1<<ISC01) | (1<<ISC00); // INT0 auf steigende Flanke
GIMSK |= (1<<INT0);

sei();

while(1)
{
if (laenge_puls<1300)
{
PORTA = 0b00000001;
}
if ((laenge_puls>1300)&&(laenge_puls<1700))
{
PORTA = 0b00000010;
}
if(laenge_puls>1700)
{
PORTA = 0b00000100;
}
}
}