Hallo allerseits,
nachdem mir letztens hier so nett weitergeholfen wurde, gleich noch eine Frage zu einem Programm.
Mir ist so eine schöne 4 stellige 7 Segment Anzeige in die Hände gefallen, welche ich natürlich gleich mal testen musste. Das Programm funktioniert auch schon weitgehend, nur besteht das kleine Problem, dass bei der 10er-Stelle die Balken von der 1er-Stelle schwach mitleuchten. Gleiches gilt für die 100er und 1000er Stelle.
An der Interruptdauer habe ich schon etwas rumgespielt, brachte aber keine Verbesserung.
Vielleicht wisst ihr ja wieder einen guten Rat.
Edit: Habe gerade mal das Oszi an die Anoden der einzelnen Segmente geklemmt. Kein schöner Anblick: Nachdem der Transistor vom µC abgeschaltet wurde, klingt die Spannung am Segment innerhalb etwa 800µs ab, das nächste wird aber sofort zugeschaltet.
Werde es dann wohl mal mit Gegentakttreibern für die Anoden probieren - falls keiner eine bessere Idee hat.
Mathias
nachdem mir letztens hier so nett weitergeholfen wurde, gleich noch eine Frage zu einem Programm.
Mir ist so eine schöne 4 stellige 7 Segment Anzeige in die Hände gefallen, welche ich natürlich gleich mal testen musste. Das Programm funktioniert auch schon weitgehend, nur besteht das kleine Problem, dass bei der 10er-Stelle die Balken von der 1er-Stelle schwach mitleuchten. Gleiches gilt für die 100er und 1000er Stelle.
An der Interruptdauer habe ich schon etwas rumgespielt, brachte aber keine Verbesserung.
Vielleicht wisst ihr ja wieder einen guten Rat.
Code:
#include <avr/io.h>
#define F_CPU 1e6
#include <util/delay.h>
#include <avr/interrupt.h>
/*
#define Modul0 PORTD, PORTD0
#define Modul1 PORTD, PORTD1
#define Modul2 PORTD, PORTD2
#define Modul3 PORTD, PORTD3
*/
//Anschlussbelegung der 7Seg. Anzeige am Port B
#define SEGa PORTB, PORTB7 //19
#define SEGb PORTB, PORTB6 //18
#define SEGc PORTB, PORTB5
#define SEGd PORTB, PORTB4
#define SEGe PORTB, PORTB3
#define SEGf PORTB, PORTB2
#define SEGg PORTB, PORTB1 //13
#define setbit(IO) __setbit(IO)
#define __setbit(PORT, BIT) PORT |= (1<<BIT)
#define clearbit(IO) __clearbit(IO)
#define __clearbit(PORT, BIT) PORT &=~ (1<<BIT)
//Entprell-Routine übernommen von "http://www.mikrocontroller.net/attachment/67964/debounce.c"
#define debounce( port, pin ) \
({ \
static uint8_t flag = 0; /* new variable on every macro usage */ \
uint8_t i = 0; \
\
if( flag ){ /* check for key release: */ \
for(;;){ /* loop ... */ \
if( !(port & 1<<pin) ){ /* ... until key pressed or ... */ \
i = 0; /* 0 = bounce */ \
break; \
} \
_delay_us( 20 ); /* * 256 = 25ms */ \
if( --i == 0 ){ /* ... until key >25ms released */ \
flag = 0; /* clear press flag */ \
i = 0; /* 0 = key release debounced */ \
break; \
} \
} \
}else{ /* else check for key press: */ \
for(;;){ /* loop ... */ \
if( (port & 1<<pin) ){ /* ... until key released or ... */ \
i = 0; /* 0 = bounce */ \
break; \
} \
_delay_us( 20 ); /* * 256 = 25ms */ \
if( --i == 0 ){ /* ... until key >25ms pressed */ \
flag = 1; /* set press flag */ \
i = 1; /* 1 = key press debounced */ \
break; \
} \
} \
} \
i; /* return value of Macro */ \
})
volatile uint16_t zaehler=0;
volatile int8_t digit[4];
//Initialisierung
void init( void )
{
DDRB = 0xFF; //Port B Ausgang
PORTB = 0x00; //Alle Pins LOW
DDRD = 0b0001111; //Port D Pin 4,5,6 Eingänge; Pin 0..4 Ausgänge
PORTD = 0b1111111; //Alle PullUp-Widerstände 4,5,6 ein; Ausgänge auf HIGH (PNP-Treiber aus)
}
//gemeinsame Anode, clearbit schaltet Segment
void SiebenSegAnz(uint8_t a)
{
switch(a)
{
case 9: // abcdefg
{ //PORTB = 0b0010000x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
setbit (SEGe);
clearbit(SEGf);
clearbit(SEGg);
}break;
case 8:
{ //PORTB = 0b0000000x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
clearbit(SEGe);
clearbit(SEGf);
clearbit(SEGg);
}break;
case 7:
{ //PORTB = 0b1111000x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
setbit (SEGd);
setbit (SEGe);
setbit (SEGf);
setbit (SEGg);
}break;
case 6:
{ //PORTB = 0b0000010x;
clearbit(SEGa);
setbit (SEGb);
clearbit(SEGc);
clearbit(SEGd);
clearbit(SEGe);
clearbit(SEGf);
clearbit(SEGg);
}break;
case 5:
{ //PORTB = 0b0010010x;
clearbit(SEGa);
setbit (SEGb);
clearbit(SEGc);
clearbit(SEGd);
setbit (SEGe);
clearbit(SEGf);
clearbit(SEGg);
}break;
case 4:
{ //PORTB = 0b0011001x;
setbit (SEGa);
clearbit(SEGb);
clearbit(SEGc);
setbit (SEGd);
setbit (SEGe);
clearbit(SEGf);
clearbit(SEGg);
}break;
case 3:
{ //PORTB = 0b0110000x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
setbit (SEGe);
setbit (SEGf);
clearbit(SEGg);
}break;
case 2:
{ //PORTB = 0b0100100x;
clearbit(SEGa);
clearbit(SEGb);
setbit (SEGc);
clearbit(SEGd);
clearbit(SEGe);
setbit (SEGf);
clearbit(SEGg);
}break;
case 1:
{ //PORTB = 0b1111001x;
setbit (SEGa);
clearbit(SEGb);
clearbit(SEGc);
setbit (SEGd);
setbit (SEGe);
setbit (SEGf);
setbit (SEGg);
}break;
case 0:
{ //PORTB = 0b1000000x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
clearbit(SEGe);
clearbit(SEGf);
setbit (SEGg);
}break;
default:
{ //PORTB = 0b0111111x;
clearbit(SEGa);
clearbit(SEGb);
clearbit(SEGc);
clearbit(SEGd);
clearbit(SEGe);
clearbit(SEGf);
setbit (SEGg);
}
}
}
void Print(uint16_t num)
{
uint8_t i=0;
uint8_t j;
if(num>9999) return;
while(num)
{
digit[i]=num%10;
i++;
num=num/10;
}
for(j=i;j<4;j++) digit[j]=0;
}
int main(void)
{
init();
//uint16_t i=0;
TCCR0A = (1<<WGM01);
OCR0A = 124; // 1MHz Systemtakt, Interrupt-Periodendauer = 1ms
TIMSK |= (1<<OCIE0A);
TCCR0B = (1<<CS01); //Prescaler 8
sei();
for(;;)
{
if( debounce( PIND, PD6 ) ) zaehler++;
if( debounce( PIND, PD5 ) ) zaehler--;
if(zaehler>9999) zaehler=9999; //Zählerstand bei 9 begrenzen
if(zaehler<1) zaehler=0; //Zählerstand bei 0 begrenzen
if( debounce( PIND, PD4 ) ) zaehler=0;
Print(zaehler);
/* Schneller Zählerdurchlauf für Testzwecke
for(i=0;i<10000;i++)
{
Print(i);
_delay_ms(500);
}
if( debounce( PIND, PD6 ) ) i=0;
*/
}
}
ISR(TIMER0_COMPA_vect)
{
static uint8_t z=0;
if(z==3) z=0;
else z++;
PORTD=~(1<<z);
SiebenSegAnz(digit[z]);
}
Edit: Habe gerade mal das Oszi an die Anoden der einzelnen Segmente geklemmt. Kein schöner Anblick: Nachdem der Transistor vom µC abgeschaltet wurde, klingt die Spannung am Segment innerhalb etwa 800µs ab, das nächste wird aber sofort zugeschaltet.
Werde es dann wohl mal mit Gegentakttreibern für die Anoden probieren - falls keiner eine bessere Idee hat.
Mathias