HF SHOOTER
05.11.2007, 19:02
Hallo
Mit dem unten stehenden Code habe ich meine Probleme:
// richtige 7-Segment-Anzeige freischalten (Masse schalten)
switch(Ziffer)
{
case 0: break;
case 1: PORTB_temp &= ~(1 << PB2); PORTB_temp |= (1 << PB0); break;
case 2: PORTB_temp &= ~(1 << PB0); PORTB_temp |= (1 << PB2); break;
}
Die Variable Ziffer (uint8_t) hat entweder den Wert 0, 1 oder 2. Egal welcher Wert diese hat, es wird immer nur der Teil hinter case 1 ausgeführt, wenn Ziffer eine 2 hat wird trotzdem case 1 ausgeführt.
Habe euch ein Bild beim Debugen mit angehängt.
EDIT: Auch wenn cihd as ganze mit IF-Bedingung filtern möchte wird immer davon ausgegangen das Ziffer 1 ist, auch wenn es 2 ist. Folgender Code führt auch wenn Ziffer 2 ist den Teil bei Ziffer 1 aus:
if (Ziffer == 1)
{
PORTB_temp &= ~(1 << PB2);
PORTB_temp |= (1 << PB0);
}
if (Ziffer == 2)
{
PORTB_temp &= ~(1 << PB0);
PORTB_temp |= (1 << PB2);
}
Aber warum funktioniert es dann bei diesem Codeabschnitt ohne Probleme?
// Segmente einstellen
switch(StelleZahl[Ziffer - 1])
{
// Segment: gfedcba
case 0: SEGMENT = 0b00111111; break;
case 1: SEGMENT = 0b00000110; break;
case 2: SEGMENT = 0b01011011; break;
case 3: SEGMENT = 0b01001111; break;
case 4: SEGMENT = 0b01100110; break;
case 5: SEGMENT = 0b01101101; break;
case 6: SEGMENT = 0b01111100; break;
case 7: SEGMENT = 0b00000111; break;
case 8: SEGMENT = 0b01111111; break;
case 9: SEGMENT = 0b01100111; break;
// Segment: gfedcba
}
Und falls jemand den kompletten Code einsehen will, hier ist er:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Projekt: Drehzahlmesser
Anzeige der Drehzahl auf 5 7-Segment-Anzeigen.
Anzeigen werden im Multiplexverfahren angesteuert,
die Drehzahl alle 100ms aktualisiert.
Später sollen noch max. Drehzahlspeicherung sowie eine
Begrüßung beim Einschalten hinzukommen.
AUTOR: Benjamin Ruppert
DATUM: 01.11.2007 - gute Frage
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/interrupt.h>
/* Variablendeklaration */
uint8_t Ziffer; // 1 - 5, 1 links, 5 rechts
uint16_t Zahl; // Drehzahl, max 5-stellig
uint8_t StelleZahl[5] = {1,2,5,7,9};
uint8_t SEGMENT;
uint8_t PORTB_temp;
uint8_t PORTC_temp;
/* Prototypendekleration */
/* Interruptserviceroutinen */
ISR(TIMER0_OVF_vect)
{
Ziffer++;
if (Ziffer > 2) { Ziffer = 1; }
}
int main(void)
{
/* Ein- / Ausgänge definieren */
DDRC = 0b00111111; // PC0 - PC5 als Ausgang
DDRB = 0b00000111; // PB0 - PB1 als Ausgang
/* Timer einstellen */
TCCR0 |= (0 << CS00) | (1 << CS01); // Vorteiler 64
/* Interrupts einschalten / festlegen */
TIMSK |= (1<<TOIE0);
sei();
// DEBUG Settings
Ziffer = 1;
//Zahl = 2;
while(1)
{
// Segmente einstellen
switch(StelleZahl[Ziffer - 1])
{
// Segment: gfedcba
case 0: SEGMENT = 0b00111111; break;
case 1: SEGMENT = 0b00000110; break;
case 2: SEGMENT = 0b01011011; break;
case 3: SEGMENT = 0b01001111; break;
case 4: SEGMENT = 0b01100110; break;
case 5: SEGMENT = 0b01101101; break;
case 6: SEGMENT = 0b01111100; break;
case 7: SEGMENT = 0b00000111; break;
case 8: SEGMENT = 0b01111111; break;
case 9: SEGMENT = 0b01100111; break;
// Segment: gfedcba
}
PORTB_temp = PORTB; //oder PINB?!?!?!?!?!!?!?
PORTB_temp &= ~(1 << PB1); // PB1 auf 0
PORTC_temp = 0x00;
// Ausgänge setzen, wie 7-Segment angeschlossen ist
if (SEGMENT & (1 << 0)) { PORTC_temp |= 0b00001000; } //a an PC3
if (SEGMENT & (1 << 1)) { PORTC_temp |= 0b00010000; } //b an PC4
if (SEGMENT & (1 << 2)) { PORTC_temp |= 0b00000001; } //c an PC0
if (SEGMENT & (1 << 3)) { PORTC_temp |= 0b00000010; } //d an PC1
if (SEGMENT & (1 << 4)) { PORTB_temp |= 0b00000010; } //e an PB1
if (SEGMENT & (1 << 5)) { PORTC_temp |= 0b00000100; } //f an PC2
if (SEGMENT & (1 << 6)) { PORTC_temp |= 0b00100000; } //g an PC5
//PORTC = 0x00; // PC0 - PC5 auf 0
//PORTB &= ~(1 << 1); // PB1 auf 0
// richtige 7-Segment-Anzeige freischalten (Masse schalten)
switch(Ziffer)
{
case 0: break;
case 1: PORTB_temp &= ~(1 << PB2); PORTB_temp |= (1 << PB0); break;
case 2: PORTB_temp &= ~(1 << PB0); PORTB_temp |= (1 << PB2); break;
}
PORTC = PORTC_temp;
PORTB = PORTB_temp;
}
}
Ich bekomm es im Moment einfach nicht ein meine Kopf rein warum er immer davon ausgeht das Ziffer 1 ist (alos case 1 ausführt) obwohl doch aus dem Bild ganz klar hervorgeht das Ziffer 2 ist, aber nein es wird trotzdem case 1 ausgeführt.
Für Hilfe bin ich sehr dankbar.
mfg
Benny
Mit dem unten stehenden Code habe ich meine Probleme:
// richtige 7-Segment-Anzeige freischalten (Masse schalten)
switch(Ziffer)
{
case 0: break;
case 1: PORTB_temp &= ~(1 << PB2); PORTB_temp |= (1 << PB0); break;
case 2: PORTB_temp &= ~(1 << PB0); PORTB_temp |= (1 << PB2); break;
}
Die Variable Ziffer (uint8_t) hat entweder den Wert 0, 1 oder 2. Egal welcher Wert diese hat, es wird immer nur der Teil hinter case 1 ausgeführt, wenn Ziffer eine 2 hat wird trotzdem case 1 ausgeführt.
Habe euch ein Bild beim Debugen mit angehängt.
EDIT: Auch wenn cihd as ganze mit IF-Bedingung filtern möchte wird immer davon ausgegangen das Ziffer 1 ist, auch wenn es 2 ist. Folgender Code führt auch wenn Ziffer 2 ist den Teil bei Ziffer 1 aus:
if (Ziffer == 1)
{
PORTB_temp &= ~(1 << PB2);
PORTB_temp |= (1 << PB0);
}
if (Ziffer == 2)
{
PORTB_temp &= ~(1 << PB0);
PORTB_temp |= (1 << PB2);
}
Aber warum funktioniert es dann bei diesem Codeabschnitt ohne Probleme?
// Segmente einstellen
switch(StelleZahl[Ziffer - 1])
{
// Segment: gfedcba
case 0: SEGMENT = 0b00111111; break;
case 1: SEGMENT = 0b00000110; break;
case 2: SEGMENT = 0b01011011; break;
case 3: SEGMENT = 0b01001111; break;
case 4: SEGMENT = 0b01100110; break;
case 5: SEGMENT = 0b01101101; break;
case 6: SEGMENT = 0b01111100; break;
case 7: SEGMENT = 0b00000111; break;
case 8: SEGMENT = 0b01111111; break;
case 9: SEGMENT = 0b01100111; break;
// Segment: gfedcba
}
Und falls jemand den kompletten Code einsehen will, hier ist er:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Projekt: Drehzahlmesser
Anzeige der Drehzahl auf 5 7-Segment-Anzeigen.
Anzeigen werden im Multiplexverfahren angesteuert,
die Drehzahl alle 100ms aktualisiert.
Später sollen noch max. Drehzahlspeicherung sowie eine
Begrüßung beim Einschalten hinzukommen.
AUTOR: Benjamin Ruppert
DATUM: 01.11.2007 - gute Frage
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/interrupt.h>
/* Variablendeklaration */
uint8_t Ziffer; // 1 - 5, 1 links, 5 rechts
uint16_t Zahl; // Drehzahl, max 5-stellig
uint8_t StelleZahl[5] = {1,2,5,7,9};
uint8_t SEGMENT;
uint8_t PORTB_temp;
uint8_t PORTC_temp;
/* Prototypendekleration */
/* Interruptserviceroutinen */
ISR(TIMER0_OVF_vect)
{
Ziffer++;
if (Ziffer > 2) { Ziffer = 1; }
}
int main(void)
{
/* Ein- / Ausgänge definieren */
DDRC = 0b00111111; // PC0 - PC5 als Ausgang
DDRB = 0b00000111; // PB0 - PB1 als Ausgang
/* Timer einstellen */
TCCR0 |= (0 << CS00) | (1 << CS01); // Vorteiler 64
/* Interrupts einschalten / festlegen */
TIMSK |= (1<<TOIE0);
sei();
// DEBUG Settings
Ziffer = 1;
//Zahl = 2;
while(1)
{
// Segmente einstellen
switch(StelleZahl[Ziffer - 1])
{
// Segment: gfedcba
case 0: SEGMENT = 0b00111111; break;
case 1: SEGMENT = 0b00000110; break;
case 2: SEGMENT = 0b01011011; break;
case 3: SEGMENT = 0b01001111; break;
case 4: SEGMENT = 0b01100110; break;
case 5: SEGMENT = 0b01101101; break;
case 6: SEGMENT = 0b01111100; break;
case 7: SEGMENT = 0b00000111; break;
case 8: SEGMENT = 0b01111111; break;
case 9: SEGMENT = 0b01100111; break;
// Segment: gfedcba
}
PORTB_temp = PORTB; //oder PINB?!?!?!?!?!!?!?
PORTB_temp &= ~(1 << PB1); // PB1 auf 0
PORTC_temp = 0x00;
// Ausgänge setzen, wie 7-Segment angeschlossen ist
if (SEGMENT & (1 << 0)) { PORTC_temp |= 0b00001000; } //a an PC3
if (SEGMENT & (1 << 1)) { PORTC_temp |= 0b00010000; } //b an PC4
if (SEGMENT & (1 << 2)) { PORTC_temp |= 0b00000001; } //c an PC0
if (SEGMENT & (1 << 3)) { PORTC_temp |= 0b00000010; } //d an PC1
if (SEGMENT & (1 << 4)) { PORTB_temp |= 0b00000010; } //e an PB1
if (SEGMENT & (1 << 5)) { PORTC_temp |= 0b00000100; } //f an PC2
if (SEGMENT & (1 << 6)) { PORTC_temp |= 0b00100000; } //g an PC5
//PORTC = 0x00; // PC0 - PC5 auf 0
//PORTB &= ~(1 << 1); // PB1 auf 0
// richtige 7-Segment-Anzeige freischalten (Masse schalten)
switch(Ziffer)
{
case 0: break;
case 1: PORTB_temp &= ~(1 << PB2); PORTB_temp |= (1 << PB0); break;
case 2: PORTB_temp &= ~(1 << PB0); PORTB_temp |= (1 << PB2); break;
}
PORTC = PORTC_temp;
PORTB = PORTB_temp;
}
}
Ich bekomm es im Moment einfach nicht ein meine Kopf rein warum er immer davon ausgeht das Ziffer 1 ist (alos case 1 ausführt) obwohl doch aus dem Bild ganz klar hervorgeht das Ziffer 2 ist, aber nein es wird trotzdem case 1 ausgeführt.
Für Hilfe bin ich sehr dankbar.
mfg
Benny