PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer1, Timer2 problem und FuseBits



Darki89
30.04.2009, 15:53
Hi, ich hab ein komisches Problem: Wenn timer1 überläuft, sollen auf meinen 7 Segment Anzeigen nur 0en angezeigt werden. Das klappt auch. Nur das geniale ist jetzt, lösche ich die Einstellungen für timer2 (!) wird garnix angezeigt. Lösch ich die Einstellung timer1, hat das nur positives: Die Anzeige blinkt nichtmehr (was sie vorher tut im ca 1,5sec takt). Aber warum?

edit: So, ich hab mittlerweile neue Erkenntnisse: Wenn ich Die Einstellung für den Prescaler von Timer1 rausnehme, blinkt die Anzeige nichtmehr. Nehm ich allerdings die Einstellung für den Prescaler von Timer2 raus und lass die von Timer1 drin, dann wird garnichts angezeigt. Der Timer2 scheint auch kein Interrupt auszulösen, ich hab den Code ein wenig geändert und wollte nur eine 1 und eine 2 anzeigen lassen, für die Timer halt, aber es wurde immernur die 1 angezeigt.
In der I/O View von AVRStudio sind alle Prescaler richtig, die häcken sind auch an den richtigen stellen (Overflow Intterupt Enable etc) aber trotzdem klappt es nicht :/ ich werd noch wahnsinnig!

Aus Platzgründen hab ich unwichtiges weggekürzt


#define F_CPU 4000000
[Zuweisung von Ports zu den Segmenten]
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

[haufenweise Zuweisungen mit int, volatile, etc]

int main(void)
{
sei();

GIMSK |= (1<<INT1); // Externer Interrupt an Pin INT1 Aktivieren
MCUCR |= (1<<ISC11)|(1<<ISC10); // Externer Interrupt auf Steigender Flanke
TIMSK |= (1<<TOIE1); // Interrupt aktivieren für Overflow, Timer1 (16bit)
TCCR1B |= (1<<CS11)|(1<<CS10); // 64 Prescaler

TIMSK |= (1<<TOIE2); // Interrupt aktivieren für Overflow, Timer2 (8Bit)
TCCR2 |= (1<<CS22)|(1<<CS21)|(1<<CS20); // 1024 Prescaler

DDRB = 0b11111111;
DDRC = 0b11111111;
DDRD = 0b11110111; // Der 4 Letzte ist INT1, Externer Interrupt

PORTB = 0b00000000;
PORTC = 0b00000000;

if (init == 0) {
ziffer[0]= (1<<PB1);
ziffer[1]= (1<<PB2);
ziffer[2]= (1<<PB3);
ziffer[3]= (1<<PB4);
init = 1;
}

while(1) {
n++;

if (n >=4) {
n = 0;
}

if (error == 1) {
output[0] = 0b00111111;
output[1] = 0b00111111;
output[2] = 0b00111111;
output[3] = 0b00111111;
output[4] = 0b00111111;
}

PORTB = ziffer[n];
PORTC = output[n];
_delay_us(100);
PORTB = 0b00000000;
PORTC = 0b00000000;

}

}


ISR (INT1_vect) { //Externer Interrupt
error = 0;
PORTB = 0b00000000;
PORTC = 0b00000000;

timer = TCNT1;
TCNT1 = 0;
[Berechnungen, rausgekürzt]
}

ISR(TIMER1_OVF_vect) {
error = 1;
}

Mein Zweites Problem sind die FuseBits. Forensuche hab ich genutzt, aber irgendwie nichts passendes gefunden.
ich wollte einen externen 16Mhz Quarz am Mega16 mit 2mal 22pF Kondensatoren ans laufen bringen. Leider aber stellte er sich dann tot -.-
Im AVR Studio habe ich eingestellt "Ext. Crystal/Resonator High Freq.; Start-up time: 258 CK + 64 ms" Ist doch wohl der richtige? CKOPT war dabei mal auf 0 und mal auf 1.
was ist denn jetzt richtig? Ich will den nicht nochmal wiederbeleben müssen ;)

Hubert.G
30.04.2009, 18:24
Wie verhält es sich wenn das unwichtige weggekürzt ist?

Hier ist was für die Fuses: www.engbedded.com/fusecalc/

Darki89
30.04.2009, 18:42
Das was gekürzt ist, steht oben mit drin in den [].
Ich hab auch schon einiges rausgenommen, zum beispiel die Berechnung die unten angedeutet ist.
Aber es geht ja im prinzip ja nur um das seltsame verhalten der Timer.
Ist euch da was bekannt? Irgendwie Register die doppelt verwendet werden? Oder Einfluss aufeinander haben? Weil bei meinem Problem scheint es ja so zu sein, das der Prescaler von Timer2 Einfluss auf Timer1 hat

Und danke für den Link, den hab ich schon gefunden, allerdings kann ich ja die selben Einstellmöglichkeiten ja im AVRStudio tätigen, bringt mich also nicht wirklich weiter was ist einstellen soll.

McJenso
30.04.2009, 19:58
Hallo,

bin faul und habe nicht alles gelesen, aber


GIMSK |= (1<<INT1); // Externer Interrupt an Pin INT1 Aktivieren
ISR (INT1_vect) { //Externer Interrupt
...
Ok

TIMSK |= (1<<TOIE1); // Interrupt aktivieren für Overflow, Timer1
ISR(TIMER1_OVF_vect) {
...
Ok

TIMSK |= (1<<TOIE2); // Interrupt aktivieren für Overflow, Timer2
???



Gruß

Jens

Darki89
30.04.2009, 20:34
Ups, ja, da fehlt noch ein

ISR(TIMER2_OVF_vect) {

Das hatte ich im laufe der Zeit wohl mit rausgelöscht. Ich habs natürlich mit der Schleife versucht. Also wo ich überprüfen wollte, ob Timer2 überhaupt überläuft, was nicht der fall ist. Bzw löst er keinen Interrupt aus.


ISR(TIMER1_OVF_vect) {
PORTC = 0b00000001;
}
ISR(TIMER2_OVF_vect) {
PORTD = 0b00000001;
}
so in die Richtung hab ich es versucht. Es hat immer nur die LED von PortC geleuchtet.

Hubert.G
30.04.2009, 20:51
Solche Programmfragmente machen keinen Spass. Man kann sie nicht mal ins AVR-Studio laden zum simulieren, da die Hälfte fehlt.

Darki89
30.04.2009, 21:09
Ok ok, hier das Programm wie es momentan ist zum testen. Es wird nur die 1 angezeigt. Auch bei einem Flankenwechsel an INT1 passiert nichts. Auch blinkt die 1 ganz kurz im 1,5Sec Takt. Wenn ich allerdings den 64Prescaler für Timer1 rausnehme, blinkt die Ziffer nichtmehr.

#define F_CPU 4000000

//Anzeigen sind verbunden: Anzeige1: PC2, Anzeige2: PC1, Anzeige3: PC3, Anzeige4: PC4
//Segmente sind verbunden: a: PD0, b: PD1, c: PD2, d: PD3, e: PD5, f: PD6, g: PD7, p: PC0

#define n0 0b00111111; //0: a, b, c, e, f
#define n1 0b00000110; //1: c, b
#define n2 0b01011011; //2: a, b, d, e, g
#define n3 0b01001111; //3: a, b, c, d, g
#define n4 0b01100110; //4: b, c, f, g
#define n5 0b01101101; //5: a, c, d, f, g
#define n6 0b01111101; //6: a, c, d, e, f, g
#define n7 0b00000111; //7: a, b, c
#define n8 0b01111111; //8: a, b, c, d, e, f, g
#define n9 0b01101111; //9: a, b, c, d, f, g

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

volatile int output[5];
volatile int error;
int timer;
int run;
int n;
int anzeige[5];
int ziffer[5];
int init;
signed char tast;

int main(void)
{
sei();

GICR |= (1<<INT1); // Externer Interrupt an Pin INT1 Aktivieren
MCUCR |= (1<<ISC11)|(1<<ISC10); // Externer Interrupt auf fallender Flanke

TIMSK |= (1<<TOIE1); // Interrupt aktivieren für Overflow, Timer1 (16bit)
TCCR1B |= (1<<CS10)|(1<<CS11); // 64 Prescaler


TIMSK |= (1<<TOIE2); // Interrupt aktivieren für Overflow, Timer2 (8Bit)
TCCR2 |= (1<<CS22)|(1<<CS21)|(1<<CS20); // 1024 Prescaler

DDRB = 0b11111111;
DDRC = 0b11111111;
DDRD = 0b11110111; // Der 4 Letzte ist INT1, Externer Interrupt

PORTB = 0b00000000;
PORTC = 0b00000000;

if (init == 0) {
ziffer[0]= (1<<PB1);
ziffer[1]= (1<<PB2);
ziffer[2]= (1<<PB3);
ziffer[3]= (1<<PB4);
init = 1;
}

while(1) {
n++;

if (n >=4) {
n = 0;
}

if (error == 1) {
output[0] = 0b00111111;
output[1] = 0b00111111;
output[2] = 0b00111111;
output[3] = 0b00111111;
output[4] = 0b00111111;
}

PORTB = ziffer[n];
PORTC = output[n];
_delay_us(100);
PORTB = 0b00000000;
PORTC = 0b00000000;

}

}

ISR (INT1_vect) {
output [2] = n3;

}

ISR(TIMER1_OVF_vect) {
output [0] = n1;
}
ISR(TIMER2_OVF_vect) {
output [1] = n2;
}

Hubert.G
30.04.2009, 21:57
IN der Simulation funktioniert es, bist du nicht etwas schnell mit der Anzeige.
Timer1 ist jetzt nicht aktiv.

Darki89
30.04.2009, 22:17
Warum ist Timer1 nicht aktiv? Also bei mir im AVR Studio steht "Running, CLK/64" Auch TCNT1 zählt hoch.
Was meinst denn mit "etwas schnell mit der Anzeige"?

Hubert.G
01.05.2009, 09:24
Was ich ins AVR-Studio geladen hatte war ohne Prescaler, daher nicht aktiv.
100µsec sind sehr kurz, die siehst du nicht.

Darki89
01.05.2009, 10:17
Doch, die sieht man :) Im vergleich zu z.B. 50µsec ist die anzeige fast doppelt so hell. Aber darum geht es ja nicht. Sonst siehst du keinen Fehler im Programm?

Hubert.G
01.05.2009, 10:22
Nein, ich sehe keinen. Es werden alle Interrupts angesprungen

Darki89
01.05.2009, 11:55
Also jetzt geht es oO Der Quellcode ist quasi GENAU der selbe. Ich hab nur einfach einmal nen neues Projekt angelegt, jetzt geht alles wie es soll. Hab dann blockweise die Funktionen eingefügt um zu schauen, wann nichtsmehr geht. Alles klapt jetzt. Ohne das ich etwas geändert hab.
Also ich den Quelltext 1:1 kopiert hab (also alles markiert und paste) ging es nicht, aber als ich ihn dann blockweise aus dem Texteditor rauskopiert hab, ging es. Kann sich das einer erklären?
Und danke für eure Hilfe!

McJenso
01.05.2009, 19:59
Hallo,

ein "Rebuild All" wirkt manchmal Wunder. Oder, wenn man das Projekt im AVR Studio wechselt, ändert sich die hex Datei, die geflasht wird, nicht automatisch.
Das sind halt so gern genutzte Fallstricke. ;-)

Gruß

Jens