PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Anfängerhilfe: Zähler zählt nicht (ATtiny45)



Jazz
04.12.2011, 09:00
Hallo,

ich möchte gern den tiny45 als Basis für diverse kleine Projekte benutzen und habe mir als Anfang vorgenommen, ein Servosignal einzulesen und damit über einen MosFET eine Glühkerze zu dimmen.
-Alle 20ms kommt ein Puls von 1..2ms
-Pulslänge messen, ggf. verwerfen
-Wert erzeugen
-neue PWM am Ausgang erzeugen

Aber so weit bin ich noch nicht—wie man sehen kann, ist das Programm auch noch Baustelle. Die ISR funktioniert schon und wenn ich in dieser je nach gestiegener oder gefallener Flanke auch den Ausgang mit einer LED schalte, dann bekomme ich quasi dort eine Kopie des Eingangsignals (1 Servokanal).

Nun möchte ich aber gern die LED erst mal aussen vor lassen und im Programm einfach eine Variable führen, die bei mir "int Dauer" heisst. Ich hatte mir das eigentlich so vorgestellt, dass ich den Timer mit einem Prescaler versehe und bei fallender Flanke den Zählerstand immer in diese Variable übergebe.

Aber: es funktioniert nicht. Sie bleibt immer Null.

Hat einer 'ne Idee, wo hier der Denkfehler ist?

Danke, Stefan


#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define LED PB4


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

int hi=0;
int Dauer=0;

void Initialisierung(){
DDRB |= (1 << LED); // Set direction register output
GIMSK |= (1<<PCIE); // Pin Change Interrupt Enable
PCMSK |= (1<<PCINT0); // Enable external interrupts PCINT0
MCUCR |= (1<<ISC01); // PCINT0 is triggered on any change
TCCR1 |= (1<<CS13);
TCCR1 |= (1<<CS12);
TCNT1 = 0x00;
sei();

}

ISR (PCINT0_vect) // Interrupt on PCINT0 vector
{
if (PINB&1){
TCNT1=0x00;
} else {
Dauer=TCNT1;
}
}

int main(void){
Initialisierung();
while (1){
if (Dauer==0){
PORTB |= (1<<PB4);
} else {
PORTB &= ~(1<<PB4);
}
}
}

radbruch
04.12.2011, 09:18
Hallo

So vielleicht:

volatile int Dauer=0;

"Eine zweite Schwierigkeit ergibt sich, wenn der Compiler den Code optimiert. Bei normalem Programmfluss kann der Compiler ausnutzen das einige Ausdrücke konstant bleiben, oder Variablen nicht ins SRAM schreiben, sondern nur in den Registern belassen. Durch die Interrupts gehen diese Voraussetzungen verloren und viele Optimierungen können nicht mehr durchgeführt werden, oder liefern nicht mehr lauffähigen Code. Um den Compiler darauf hinzuweisen gibt es das Schlüsselwort volatile. Damit werden Variablen gekennzeichnet die sich anders als durch den normalen Programmfluss verändern können. Das sind typischerweise Variablen die im Hauptprogramm und in einer ISR benutzt werden. Wenn ein Programm nur ohne Optimierung lauffähig ist, ist oft ein fehlendes volatile die Ursache."
(Zitat aus http://www.rn-wissen.de/index.php/C-Tutorial/Interrupt-Programmierung)

http://de.wikibooks.org/wiki/C-Programmierung:_static_%26_Co.#volatile
http://tigcc.ticalc.org/doc/keywords.html#volatile

Gruß

mic

Jazz
04.12.2011, 11:14
OK, das hast's also schon mal gebracht. Läuft. Ich hatte mir natürlich noch nie Gedanken darüber gemacht, WO diese Variable eigentlich stehen soll, ansonsten wäre mir vielleicht aufgefallen, dass die ja irgendwo im Registerbereich Platz haben muss.

Vielen Dank!
Stefan