Forum: Mikrocontroller und Digitale Elektronik Konzept für Funkuhr und Soft-PWM


von Sven S. (schwerminator)


Lesenswert?

Moin Moin,
Ich habe eine fertige Schaltung, in der die Helligkeit mit einem LDR 
ermittelt und von einem AVR ATMega16 über ein ADC-Pin ausgewertet wird. 
Abhängig von diesem Wert soll nun die Helligkeit von vier 
7-Segment-Anzeigen eingestellt werden, die parallel an vier Ports 
hängen. Klar ist, das ganze muss mit Soft-PWM geregelt werden. Ich 
programmiere in GCC.
Nun wollte ich mal eure Meinungen über die Vorgehensweise einholen. Wie 
realisiere ich das ganze am besten? Entscheidend ist, dass alle Kanäle, 
die an sind (leuchtendes Segment), gleich hell sind und somit den 
gleichen PWM-Output haben. Das sollte das ganze relativ stark 
vereinfachen.
Da ich noch nicht so viel Erfahrung in der Programmierung von 
Ein-Chip-Computern habe, bräuchte ich ein grobes Konzept.

Zu der Hardware:
Controller: ATMega16 mit 4MHz extern getaktet
LDR hängt an ADC0
DCF77-Empfänger hängt an INT0
Vier 7-Segment-Anzeigen hängen an den vier Ports

Wie ihr sicherlich schon bemerkt habe, soll das Ganze eine Funkuhr 
werden. Wie gesagt brauche ich ein Konzept, welche Aufgabe wann und wie 
erledigt wird. Welche Prozesse interruptgesteuert sind (DCF77 natürlich 
über externen Interrupt) und welche timergesteuert? In welcher 
Reihenfolge werden die Aufgaben abgearbeitet?

Ich hoffe ihr versteht meine Probleme. Ich weiß halt nicht so recht, wo 
ich anfangen soll, die Einzelaufgaben funktionieren alle (DCF77, LDR, 
7-Segment-Ausgabe [ohne Dimmung]), aber wie zusammenbringen? Nun hoffe 
ich euf eure Hilfe. Danke.

mfG, Sven

von Falk B. (falk)


Lesenswert?

@Sven S. (schwerminator)

>hängen. Klar ist, das ganze muss mit Soft-PWM geregelt werden. Ich
>programmiere in GCC.

Soft-PWM

Wobei du hier sicher keine 8 Bit Auflösung brauchst. 4 Bit reichen 
locker IMO.

>Nun wollte ich mal eure Meinungen über die Vorgehensweise einholen. Wie
>realisiere ich das ganze am besten? Entscheidend ist, dass alle Kanäle,
Deine Ansteurung erfolgt sicher über eine LED-Matrix. Dort musst du 
beim Multiplexen eben den Multiplexzyklus nicht fest, sondern variabel 
machen. Sprich, wenn du 4 Ziffern mit 100Hz Wiederholfreqeunz multiplext 
(=400Hz = 2,5ms), musst du eben je nach PWM Wert die Ziffer nach 
N*2,5ms/16 wieder auschalten. (N=0..15, 4 bit PWM)

>DCF77-Empfänger hängt an INT0

Ist unnötig und bisweilen fehleranfällig.

>Vier 7-Segment-Anzeigen hängen an den vier Ports

Ohne Multiplexen? Sollte man nicht machen.

AVR-Tutorial: 7-Segment-Anzeige

>erledigt wird. Welche Prozesse interruptgesteuert sind (DCF77 natürlich
über externen Interrupt)

Ganz unnatürlich. Besser ist die Abtastung im Timerinterrupt, z.B. mit 
100 Hz.

> und welche timergesteuert?

Das Multiplexen der Anzeige. Und die Abtastung des DCF77 Signals. Such 
mal im Forum.

MFG
Falk

von Sven S. (schwerminator)


Lesenswert?

Moin Falk,
die 7-Segmenter werden tatsächlich NICHT gemultiplext. Die Pins sind 
verfügbar, also keine Problematik! Wie schon gesagt: Die Schaltung ist 
auch bereits aufgebaut, also lässt sich an der Hardware nichts mehr 
ändern. Multiplexen fällt also flach.
Nun zum DCF77-Dekodieren: Da habe ich hier im Forum und auch im Netz nur 
Codebesispiele gefunden, die den Hardwareinterrupt benutzen. Ich habe 
bis jetzt beispielsweise den Code von Ulrich Radig verwendet. Wenn du 
mir einen Link zu einem Code mit Timersteuerung geben könntest, würde 
ich einfach den INT0-Pin als normalen I/O-Pin verwenden.

Mein Problem ist also immernoch das Einlesen der Helligkeit, das 
Aktualisieren der Uhrzeit jede Sekunde & Ausgabe, sowie jene Ausgabe in 
entsprechender Helligkeit zu realisieren. Ich habe da einfach kein 
Konzept...

Ich habe da einen groben Ansatz:
1. Display zeigt umlaufendes Segment, bis DCF77-Sync stattgefunden hat
2. Timer ruft jede Sekunde eine Funktion auf
2.1. Eine Funktion, die den LDR auswertet, wird aufgerufen
2.2. Es wird eine Ausgabe an die LEDs gemacht (in entsprechender PWM)
2.3. Das wird so lange gemacht, bis wieder die Sekundenfunktion 
aufgerufen wird

Ist die Denke so vom Ansatz richtig?

von Falk B. (falk)


Lesenswert?

@ Sven S. (schwerminator)

>auch bereits aufgebaut, also lässt sich an der Hardware nichts mehr
>ändern. Multiplexen fällt also flach.

Naja, dann eben nur Soft-PWM Hier kannst du einen Port als einen 
Kanal ansehen, macht die Sache einfacher.

>mir einen Link zu einem Code mit Timersteuerung geben könntest, würde
>ich einfach den INT0-Pin als normalen I/O-Pin verwenden.

Beitrag "DCF77-Uhr mit ATTINY12"

Es gibt hier ne schöne Suchfunktion . . .
Sogar ZWEI!

>Mein Problem ist also immernoch das Einlesen der Helligkeit, das
>Aktualisieren der Uhrzeit jede Sekunde & Ausgabe, sowie jene Ausgabe in
>entsprechender Helligkeit zu realisieren. Ich habe da einfach kein
>Konzept...

Der Trick heisst Timer-Interrupt
Dort musst du periodich jedes Problem bearbeiten. Allerdings so, dass du 
dort nie stehen bleist oder wartest.

>1. Display zeigt umlaufendes Segment, bis DCF77-Sync stattgefunden hat
>2. Timer ruft jede Sekunde eine Funktion auf

Zu langsam. Alle 10ms. Oder weniger, für die PWM.

>2.1. Eine Funktion, die den LDR auswertet, wird aufgerufen
>2.2. Es wird eine Ausgabe an die LEDs gemacht (in entsprechender PWM)
>2.3. Das wird so lange gemacht, bis wieder die Sekundenfunktion
>aufgerufen wird

Falsch. Du musst die Aufgaben verschachteln, sozusagen in zeitlich 
kleine Stücke zerlegen. Dann laufen sie quasi parallel ab.

>Ist die Denke so vom Ansatz richtig?

Nein.

Eher so.

In jedem 10ms Timerinterrupt machst du

LDR auswerten (Phototransistor geht auch)
Ergebnis in PWM umrechnen
neue PWM Stufe aktivieren
DCF77 Signal abtasten
Abgetastetes Bit auswerten und speichern
Wenn alle Bits da sind, DCF77 Telegramm auswerten

lass erstmal die PWM weg, mach nur die Anzeige + DCF77 Dekodierung 
"parallel". Wenn du das verstnaden hast, mach die PWM mit rein.

MFG
Falk

von Sven S. (schwerminator)


Lesenswert?

Hi Falk,
die Anzeige der Uhrzeit funktioniert bereits einwandfrei. Ich benutzte 
bereits die Bibliothek von Ulrich Radig, die - wie gesagt - den 
Hardwareinterrupt benutzt. So sieht meine main() aus:
1
int main(){
2
  MCUInit();
3
  
4
  sei();            //Globale Interrupts einschalten
5
  
6
  Start_Clock();        //Starten der DCF77-Uhr
7
  
8
  waitTillSync();
9
  
10
  while(1) setTime(hh, mm);
11
  
12
  return 0;
13
}
Das funktioniert, weil hh und mm globale Variablen sind und stetig 
aktualisiert werden. Es geht mir lediglich noch um die Implementierung 
der Helligkeitssteuerung. Das wird bei dem bestehenden Code schwierig, 
oder?

von Falk B. (falk)


Lesenswert?

@ Sven S. (schwerminator)

>aktualisiert werden. Es geht mir lediglich noch um die Implementierung
>der Helligkeitssteuerung. Das wird bei dem bestehenden Code schwierig,
>oder?

Alles relativ. Schau dir Soft-PWM an.

MFG
Falk

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.