C Noch mal 7-Seg. Anzeige mit multiplex (nachleuchtende Balken)

PSR B1257

Neues Mitglied
14. Sep. 2012
20
0
0
Sprachen
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.

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
 
Hi
Von C hab ich zwar keine Ahnung, aber von deinem "Fehler" schon.... Vermutlich schaltest du die Anzeige nicht aus, wenn du die nächste Stelle beschreibst.
Ich hab das so gelöst:
Im Speicher werden die Anzeige - Codes für die Ziffern aufbereitet und stehen in einem Puffer direkt im 7 - Segment Code. Daher greift die Timer-ISR nur auf die Bits zur Ansteuerung der Segmente.
Es gibt eine Zählvariable für die Stelle und ein Schieberegister, um eine Stelle zu selektieren
Zuerst wird das Bit zur Anzeigenstelle abgeschaltet. Alle Anzeigen aus !
Dann Adresszeiger erhöhen und Grenze prüfen, evtl. wieder von vorn anfangen. (kommt auf die Stellen der Anzeige drauf an) Das Schieberegister für die entsprechende Stelle muß ebenfalls angepasst werden.
Dann neuen Code für die Ziffer laden und ausgeben. Die Anzeige ist immer noch aus. Dann die angezeigte Stelle zuschalten. Wenn du die Stelle nicht ausschaltest, dann kommt es zum Nachleuchten. Vielleicht hast du auch Treibertransistoren zwischen geschaltet, dann reduzier mal die Basiswiderstände. Es könnte sein, das sie zu langsam schalten. Ich betreibe eine 12 stellige 7 Segmentanzeige ( 2mal 6 Stellen parallel) mit dem Timer mit 1 mSek. Interrupt. Da flackert nix und es leuchtet auch nichts nach.
Gruß oldmax
 
... ielleicht hast du auch Treibertransistoren zwischen geschaltet, dann reduzier mal die Basiswiderstände. Es könnte sein, das sie zu langsam schalten...

...Nachdem der Transistor vom µC abgeschaltet wurde, klingt die Spannung am Segment innerhalb etwa 800µs ab, das nächste wird aber sofort zugeschaltet...
800µs wären bei 20MHz Taktfrequenz immerhin 16000 Takte, also 'ne Ewigkeit, nur um mal 'ne Vorstellung zu bekommen.
Für die Vorwiderstände: Ein AVR-Pin kann ca 20mA liefern/ziehen, aber für die Ports und den ganzen Chip gibts auch Grenzen -> Datenblatt
...falls keiner eine bessere Idee hat...
Was spricht gegen einen BCD-Encoder pro Digit (sind dann 4 Leitungen für die Ziffer, und je eine Latch-Leitung pro Digit, wenn ich mich recht erinner)
 
800µs wären bei 20MHz Taktfrequenz immerhin 16000 Takte
Wo hast du denn die 20MHz her? Der µC arbeitet mit 1MHz.

dann reduzier mal die Basiswiderstände. Es könnte sein, das sie zu langsam schalten.
Die sind schon nur 1k. Verwendet werden ganz normale BC557.

Was spricht gegen einen BCD-Encoder pro Digit
So ziemlich alles. Es soll ja kein IC-Grab werden.

Anbei zwei Oszillogramme der Spannungen. Mit dem Gegentakttreiber wird die Schaltflanke zwar wesentlich steiler, aber das mitleuchten der anderen Balken bleibt.
7Seg-Anzeige.jpg
 
Hi Mathias,

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.
...
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.
Vergß die Gegentakttreiber. Das ist Blödsinn. Die Arbeit kannst du dir sparen.

Die sind schon nur 1k. Verwendet werden ganz normale BC557.
Nur ?? :p :p :p Schonmal den Basisstrom berechnet ?

IB = IC / B

Also Kollektorstrom durch Stromverstärkungsfaktor gleich Basisstrom.
1k ist viel zu wenig! Da könntest du mit 2V Betriebsspannung arbeiten (oder weniger).
Selbst 4,7k ist noch zu wenig (hab ich selber mal erlebt). Du kannst irgendwo bei 15-22k anfangen.

Schau mal hier ...
- Analyzer für I2C/TWI und 1-Wire/microLAN - Beitrag #11 Problem
- Analyzer für I2C/TWI und 1-Wire/microLAN - Beitrag #20 Lösung

Ich hatte etwa 3µs zum sperren gemessen. Das ist aber noch sehr weit von deinen 800µs weg. Entweder ist da bei dir ein Meßfehler, Ablesefehler oder Programmfehler drin oder du hast nen Bock im Schaltplan. So eine große Zeit kann man selbst mit einem total vollgepumpten Basisanschluß nicht erreichen. 10-15µs würd ich ja eventuell noch glauben. Schaltest du eventuell von GND zu hochohmig statt zu Vcc ? Der Atmel hat bereits Gegentakt-Treiber als Ausgang.

Wenn man es schneller haben möchte dann kann man auch noch ne 1N4148 oder besser ne Schottky zum Entladen der Basis parallel zum Basisvorwiderstand legen. ACHTUNG!! Richtung beachten sonst ist der Basisstrom viel zu hoch und der Transistor platzt und der Atmel-Pin kocht ;) Bei pnp die Kathode an der Basis und bei npn die Anode an der Basis.

Mach mal nen Schaltplan und pack ihn hier rein.

Gruß
Dino
 
Vergß die Gegentakttreiber. Das ist Blödsinn.
Klar, wollte auch nur mal sehen, wie es damit aussieht.

Schonmal den Basisstrom berechnet ?
Ja, aber einfach überschlagen mittels: IB=4,3V/1kΩ=4,3mA - Sehe da kein Problem. Die Geschichte mit der Stromverstärkung ist für einer derartige Rechnung nicht wirklich brauchbar. Zum einen kennt man den wirklichen Großsignalverstärkungsfakter des Transistors nicht genau und zum anderen hat man ja 6 verschiedene Basis/~Kollektorströme.

Schaltest du eventuell von GND zu hochohmig statt zu Vcc ?
Nein, es sei denn, der ATTiny hat diesbezüglich ein Eigenleben ;)

Entweder ist da bei dir ein Meßfehler, Ablesefehler
Nein. Mir ist aber aufgefallen, dass die Spannung an der Anode eigentlich wurscht is. Auch in Simulationen klingt diese Spannung relativ langsam ab. Der Vorwärtsstrom durch die LED wird aber "sofort" unterbrochen.

Mach mal nen Schaltplan und pack ihn hier rein.
Kann ich nachher mal machen, da gibt es aber nicht viel zu sehen, außer das, was man sowieso erwartet. Auf dem Gebiet der Schaltungstechnik liegt der Fehler aber bestimmt nicht. (Habe Elektrotechnik studiert, nur kam da die Programmierung zu kurz)

Edit: Auch mit lächerlich großen Basiswiderständen (100k) (bezüglich der gesättigten Basis) ändert sich am mitleuchten nichts, aber die Balken sind natürlich entsprechend dunkler.


Mathias
 
Hi Mathias,

Ja, aber einfach überschlagen mittels: IB=4,3V/1kΩ=4,3mA - Sehe da kein Problem. Die Geschichte mit der Stromverstärkung ist für einer derartige Rechnung nicht wirklich brauchbar. Zum einen kennt man den wirklichen Großsignalverstärkungsfakter des Transistors nicht genau und zum anderen hat man ja 6 verschiedene Basis/~Kollektorströme.
es ist klar das der Transistor dadurch nicht kaputt geht. Es ist ja in dem Sinne ne "normale Diode" die da zwischen Basis und Emitter steckt. Man könnte also wohl auch 10mA da durchpressen. Sinnvoll ist aber lediglich 1mA und weniger da alles darüber nur in die Sättigung treibt. Bei nem BD135 oder nem 2N3055 kann man mal in den Bereich von 5mA oder sogar 50mA beim 2N3055 kommen. Aber der BC557 ist ein Kleinsignaltransistor. Der kann sowieso nur um die 150-200mA schalten. Selbst bei einem grottenschlechten Verstärkungsfaktor von 100 würdest du dann maximal 2mA benötigen um ihn voll durchzusteuern. Es ist klar das der Verstärkungsfaktor eher im linearen Betrieb verwendet wird. Aber wenn man den Strom der da rauskommt mit 5 multipliziert dann sollte das allemal reichen. Einfach mal mehr dem Gefühl vertrauen. Der Transistor ist ja keine LowCurrent-LED die leuchten soll ;)

Edit: Auch mit lächerlich großen Basiswiderständen (100k) (bezüglich der gesättigten Basis) ändert sich am mitleuchten nichts, aber die Balken sind natürlich entsprechend dunkler.
Dann würde ich mal sagen das dein Timing-Verhalten im Programm falsch ist. Du solltest dann mal die Schaltzeiten für die Stellen überdenken so wie oldmax es schon geschrieben hat. Die Segmente während der Aus-Phase ändern. Also eine kleine Dunkelphase einbauen.

Gruß
Dino
 
Bei den 546/556 o.ä. schalte ich meißt mit (rechnerisch) 0.5mA. Reicht für Led's allemal, natürlich nicht für Lichterketten. Aber für Kleinkram.
 
Ich habe es jetzt auch noch mal mit Verzögerungszeiten im Programm versucht. Aber entweder sind sie so klein, dass sich am Mitleuchten immer noch nichts ändert. Oder es werden die Tastendrücke nicht mehr erkannt, wenn die Verzögerungszeiten zu lang sind.

@Michael:
500µA mögen für eine LED reichen. Aber bei maximal 7 pro Segment wird das etwas knapp.
 
Hallo,

Ich habe es jetzt auch noch mal mit Verzögerungszeiten im Programm versucht. Aber entweder sind sie so klein, dass sich am Mitleuchten immer noch nichts ändert. Oder es werden die Tastendrücke nicht mehr erkannt, wenn die Verzögerungszeiten zu lang sind.
Sieh dir mal die Reihenfolge deiner Abarbeitung an. Dann wird da irgendwas schief laufen ...

- Stelle abschalten
- Segmente für nächste Stelle laden/aktivieren
- nächste Stelle anschalten
- Darstellungszeit
- Stelle abschalten
- Segmente für nächste Stelle laden/aktivieren
- nächste Stelle anschalten
- Darstellungszeit
- Stelle abschalten
- ...

so sollte es ablaufen.

@Michael:
500µA mögen für eine LED reichen. Aber bei maximal 7 pro Segment wird das etwas knapp.
die 500µA reichen für einen Transistor normalerweise aus. Du sollst da ja keine LED drüber zum leuchten bringen sondern einen Transistor ansteuern. Für nen BC547/557 reicht das aus.

Gruß
Dino
 
attachment.php
Hi
Ich glaube fast, du adressierst deine Anzeige mit einer Integer und nicht mit einem Bit. Daher hab ich dir mal zwei Skizzen angehängt, die vielleicht mehr aussagen als tausend Worte. Denn so ohne einen Schaltplan ist es etwas schwierig.
Gruß oldmax
 

Anhänge

  • Skizze_Schaltung.PNG
    Skizze_Schaltung.PNG
    4,4 KB · Aufrufe: 28
  • Programm_Schritte.PNG
    Programm_Schritte.PNG
    15,3 KB · Aufrufe: 23
Hallo Leute.

Sorry, kann mich leider erst jetzt wieder melden.

die 500µA reichen für einen Transistor normalerweise aus. Du sollst da ja keine LED drüber zum leuchten bringen sondern einen Transistor ansteuern.
Logisch, ich bezog mich mit der Aussage natürlich auf den Basistrom des Transistors.

Denn so ohne einen Schaltplan ist es etwas schwierig.
An dem Schaltplan ist wie gesagt nicht besonderes, weshalb ich auch darauf verzichtet habe, ihn hier hochzuladen. Er spricht diesem hier http://embedded-lab.com/blog/wp-content/uploads/2011/03/Lab11_Circuit_SevenSegmentMultiplexing.jpg, nur dass ich eben einen ATTIny2313 verwende.

Ich glaube fast, du adressierst deine Anzeige mit einer Integer und nicht mit einem Bit.
Bin mir jetzt nicht ganz sicher, wie das gemeint ist :confused:

Hier mal mein bisheriger Code:
Code:
#include <avr/io.h>
#define F_CPU 1e6
#include <util/delay.h>
#include <avr/interrupt.h>

//Anschlussbelegung der 7Seg. Anzeige am Port B
#define SEGa 	PORTB, PORTB7	
#define SEGb 	PORTB, PORTB6	
#define SEGc 	PORTB, PORTB5
#define SEGd 	PORTB, PORTB4
#define SEGe 	PORTB, PORTB3
#define SEGf 	PORTB, PORTB2
#define SEGg 	PORTB, PORTB1	

#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 LOW
}

//gemeinsame Anode, clearbit schaltet Segment 
void SiebenSegAnz(uint8_t a)	
{
	switch(a)
	{	
		case 9:
		{	
			clearbit(SEGa);
			clearbit(SEGb);
			clearbit(SEGc);
			clearbit(SEGd);
			setbit	(SEGe);
			clearbit(SEGf);
			clearbit(SEGg);
		}break;
		case 8:		
		{	
			clearbit(SEGa);
			clearbit(SEGb);
			clearbit(SEGc);
			clearbit(SEGd);
			clearbit(SEGe);
			clearbit(SEGf);
			clearbit(SEGg);	
		}break;	
		case 7:
		{	
			clearbit(SEGa);
			clearbit(SEGb);
			clearbit(SEGc);
			setbit	(SEGd);
			setbit	(SEGe);
			setbit	(SEGf);
			setbit	(SEGg);
		}break;
		case 6:
		{	
			clearbit(SEGa);
			setbit	(SEGb);
			clearbit(SEGc);
			clearbit(SEGd);
			clearbit(SEGe);
			clearbit(SEGf);
			clearbit(SEGg);	
		}break;
		case 5:
		{	
			clearbit(SEGa);
			setbit	(SEGb);
			clearbit(SEGc);
			clearbit(SEGd);
			setbit	(SEGe);
			clearbit(SEGf);
			clearbit(SEGg);	
		}break;
		case 4:
		{	
			setbit	(SEGa);
			clearbit(SEGb);
			clearbit(SEGc);
			setbit	(SEGd);
			setbit	(SEGe);
			clearbit(SEGf);
			clearbit(SEGg);	
		}break;
		case 3:
		{	
			clearbit(SEGa);
			clearbit(SEGb);
			clearbit(SEGc);
			clearbit(SEGd);
			setbit	(SEGe);
			setbit	(SEGf);
			clearbit(SEGg);	
		}break;
		case 2:
		{	
			clearbit(SEGa);
			clearbit(SEGb);
			setbit	(SEGc);
			clearbit(SEGd);
			clearbit(SEGe);
			setbit	(SEGf);
			clearbit(SEGg);	
		}break;
		case 1:
		{	
			setbit	(SEGa);
			clearbit(SEGb);
			clearbit(SEGc);
			setbit	(SEGd);
			setbit	(SEGe);
			setbit	(SEGf);
			setbit	(SEGg);
		}break;
		case 0:
		{	
			clearbit(SEGa);
			clearbit(SEGb);
			clearbit(SEGc);
			clearbit(SEGd);
			clearbit(SEGe);
			clearbit(SEGf);
			setbit	(SEGg);
		}break;
		default:
		{	
			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 = 30;  // 1MHz Systemtakt, Interrupt-Periodendauer = 1ms
	TIMSK |= (1<<OCIE0A);
	TCCR0B = (1<<CS01);  //Prescaler 8
	sei();

	for(;;)
	{
	      //Schneller Zählerdurchlauf für Testzwecke
	      for(i=0;i<10000;i++)
              {
                   Print(i);
                   _delay_ms(100);
                   if( debounce( PIND, PD6 ) ) i=0;  //Zähler zurücksetzen
              }
	}
}

ISR(TIMER0_COMPA_vect)
{
static uint8_t z=0;
static unsigned short shift_register;

        if (z == 5)
        {
            SiebenSegAnz(digit[z]);
            _delay_us (20);
            shift_register = 0x01;
            PORTD = ~shift_register;
            PORTB=0xFF;
            z = 0;
        } else
        {
            SiebenSegAnz(digit[z]);
            _delay_us (20);
            shift_register = shift_register << 1;
            PORTD = ~shift_register;
            PORTB=0xFF;
            z++;
        }
}

Mathias
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)