3 LCD-Counter mit einem ATmega8

Ist ja nun etwas unbefriedigend, ein ZF-Offset durch Eingriff in das Programm festzulegen. Allein aus Neugier habe ich an einem Testboard Schaltung und Programm so erweitert, dass eine Zwischen-frequenz im Dialog eingegeben werden kann. Dazu gibt es auch einen Board-Entwurf, der geprüft, aber nicht realisiert wurde.

3.1 Schaltung

Die Entwicklung widmete sich zuerst dem Entwurf des zum LCD passenden Boards, da für die Bauteileanordnung und Leiterbahnführung enge Grenzen gesetzt waren. Das Board hat wie im Abschnitt 1 die gleiche Größe wie das 16x2 LCD (z.B. LCD 162C LED, reichelt.de) mit der zugehörigen Steckerleiste.

Feste Betriebsparameter werden wie in Abschnitt 1 mit Jumpern gesetzt. Der Einstelldialog für die Zwischenfrequenz ist mit Tastern zu bewerkstelligen. Üblicherweise macht man das genau einmal. Hierfür lötet man sich eine Befehlsmimik zusammen und steckt sie mit etwas Flachkabel auf das Counter-Board auf den Key-Port (Punktmarkierung beachten).

ATmega8-counter circuit

Abb. 3.1: ATmega8-Counter, Schaltung

Die Schaltung entspricht im Wesentlichen der mit dem ATtiny (Abb. 1.1). Neu hinzugekommen sind der Jumper- und der Key-Port. Da auf der Platine kein Platz mehr war, ist der NPN zur Anzeige-umschaltung LSB/USB entfallen. Nur noch der Jumper-Pin J4 ist übrig geblieben. Für eine Fernsteuerung muss dann extern ein Transistorschalter vorgesehen werden.

Die Jumper:

Jumper Gesteckt Funktion
J1 - Normalbetrieb, Frequenzanzeige
  x Einstellen der Zwischenfrequenz
J2 - Frequenzanzeige ohne Offset-Korrektur
  x Frequenzanzeige mit Offset-Korrektur um die ZF
J3 - Subtrahiere die ZF von der Eingangsfrequenz
  x Addiere die ZF zur Eingangsfrequenz
J4 - "LSB" wird angezeigt
  x "USB" wird angezeigt
J5   Unbenutzt, keine Funktion

3.2 Einstellen der Zwischenfrequenz

Die Zwischenfrequenz wird nach Stecken des Jumpers J1 eingestellt. Auf einem Steckbrett oder einer Lochrasterplatine werden mindestens drei Taster zusammen mit den Dioden verdrahtet (Abb. 5). Die Taster "Num up" und "Num down" haben die gleiche Funktion, eine Ziffer von 0 bis 9 zu variieren. Mit "Num up" geht es mit jedem Tastendruck aufwärts, mit "Num down" entsprechend abwärts. Man kann beide verwenden, es reicht aber auch einer von beiden. Mit den Tastern "Cursor right" und "Cursor left" lässt sich die jeweilige Ziffer von links nach rechts und umgekehrt auswählen. Die Anzeige ist identisch mit der Frequenzanzeige, es kann also auf 100 Hz genau eingestellt werden.

99.999,9 kHz

Dies ist die Vorbesetzung bei einem frisch gebrannten ATmega8. Damit werden die zur Anpassung verfügbaren Ziffern vorgegeben. Für eine ZF von z.B. 9 MHz wird 09.000,0 eingestellt. Wird bei der Jumpereinstellung (J2, J3) subtrahiert und ist die ZF größer als die Eingangsfrequenz, damit die Differenz negativ, wird dies statt der Frequenz angezeigt.

Mit einem langen Druck (ca. 1 sec.) auf den Cursor right-Taster wird die Einstellung im EEPROM des ATmega8 gespeichert, erkennbar an der Rückmeldung in Displayzeile 1. Nach Entfernen von Jumper 1 wird die Frequenz entsprechend der Jumper J2 und J3 angezeigt, nachdem der Zähler aus und wieder eingeschaltet wurde.

Die Dioden an den Tastern haben folgende Funktion: Wenn irgendein Taster gedrückt wurde, ziehen die Dioden den Port D.2 (INT0) nach Low. Dadurch erfolgt ein Interrupt, bei dem geprüft wird, welcher Taster gerade gedrückt wurde.

Bis auf die zusätzliche Überwachung des INT0-Interrupts entspricht die Software der aus Abschnitt 1. Die Frequenzanzeige ist nun aus der Timer0-Interruptroutine (Zähl-Gate) in die Do...Loop verlagert.

Die Unterlagen sind im Download als "lcdcounter_200.zip" abgelegt.

Nachtrag vom 26.02.2014

Bei der Programmierung eines vergleichbaren Zählers für UKW/VHF mit einem Prescaler zeigte sich, dass das Gate-Timing (Timer0) nicht korrekt ist. In "lcdcounter_200" läuft der Timer0 nach Auslesen des Timer1-Counters beim nächsten Eintritt in die Interrupt-Serviceroutine gleich wieder los. Die im Vergleich zu den Timer0-Interrupts fußlahme LCD-Anzeige kann daher mehr als eine gemessene Frequenz angeboten bekommen. Ergebnis ist ein sporadisches Flattern der Anzeige.

In der korrigierten Version lcdcounter_201 (im Download) sind folgende Korrekturen (blau) vorgenommen:

Korrektur 1 in der Timer0_isr:

   Timer0 = Presettimer0                          'Reset Timer0 start counts
   If bytTimer0_runs = 0 Then
      Enable Timer1
      Start TIMER1
      bytTimer0_runs = 1
   ElseIf bytTimer0_runs < bytTimer0_MaxRuns Then
      Incr bytTimer0_runs
   Else
      Stop Timer1
      Stop Timer0                                 'Stop until display finished
      wrdCountLo = Timer1                         'get low word (overlay lngCount)
      lngCountSave = lngCount                     'Save frequency
      Shift lngCountSave , Right , 3              'Divide by 8 (2^3)=frequency
      Timer1 = 0                                  'reset timer1
      bytTimer0_runs = 0
      lngCount = 0                                'reset counter
      bitShow = 1
   End If

Mit abgelaufener Gatezeit wird der Timer0 gestoppt. Es wird also nicht mehr gezählt, bis die LCD-Anzeige erledigt ist.

Korrektur 2 in der Do...Loop des Hauptprogramms (ganz unten):

         lngTmp0 = lngIFOffset / 10               'Offset in kHz
         strDis = Str(lngTmp0)                    'IF offset (kHz)
         strDis = Format(strDis , "    0")
         LCD strFreq ; " " ; "Offset " ; strDis
         bitShow = 0
         Timer0 = Presettimer0                    'Reset Timer0 start counts
         Start Timer0                             'Restart Timer0 for next counting
      End If

   End If

Loop

Nach Abarbeiten der LCD-Anzeige wird der Timer0 mit der PresetTimer0-Voreinstellung wieder gestartet. So bekommt die Anzeige immer genau ein Zählergebnis serviert.