Atmega8 und Timer2 / RTC

Gerhard73

Neues Mitglied
10. Feb. 2014
3
0
1
Sprachen
  1. BascomAVR
Moin, Moin,
seit einigen Wochen beschäftige ich mich als Anfänger mit der Programmierung vom Atmega8.
Aktuell steht die Verwendung des Timer2 im RTC auf meiner Liste.
Das Programm ( Echtzeituhr) kommt aus dem Buch von Roland Walter (AVR - Microcontroller Lehrbuch).
Generell funktioniert es.
Nun will ich ein Signal aus dem asynchronen Betrieb für einen Zähler ausleiten und finde dazu
im AMTEL - Handbuch keinen Ansatz ( ist nicht einfach, da es in Englisch geschrieben ist).
Kann mir jemand dazu vielleicht einen Tip geben?
Vielen Dank vorab.

Da ich zum ersten Mal im Forum bin, bitte ich um Geduld wenn ich mich nicht umgehend orientieren kann!

Grüße
Gerhard
 
Hallo Gerhard,

erstmal willkommen in Forum.
Wenn du ein konkretes Problem hast, ist es natürlich einfacher für alle, wenn du möglichst viele Infos hier reinstellst - wie z.B. deinen Quelltext - nicht jeder hat/kennt das AVR-Lehrbuch und selbst wenn, da gibt es mehr als ein Beispielprog.
Nun will ich ein Signal aus dem asynchronen Betrieb für einen Zähler ausleiten
Ohne genau zu wissen, was du unter "ein Signal" verstehst, kann man die Frage schlecht beantworten. (Stunde, Minute, Sekunde ???)

Gruß
- gp177 -
 
Atmega8 und Timer2 im Asynchron - Modus

Moin, Moin,
Vielen Dank für diese ersten Antworten.
Wie begrüße ich euch den?:)

Unten findet ihr den Quelltext in Bascom.
Das Programm läuft.
Timer2 im asynchron Modus soll den Takt vorgeben

Ziel:
Der Takt aus dem asynchron Modus soll Basis für den Sekundentakt im normalen Timer2 sein
Im normalen Modus soll die aktuelle Tagesuhr im LCD abgebildet sein
Im normalen Modus soll eine Alarmzeitpunkt im LCD abgebildet sein.
Dieser Alarmzeitpunkt und aktuelle Tageszeit kann im Program vorgegeben werden

Benötige einen Schaltwert für eine Ansteuerung für ein Relais

Status:
Takt im asynchron Modus funktioniert.
LCD funktioniert auch
Takt im Standard Modus vom Timer 2 funktioniert auch

Einen Zähler für die Zeit habe ich auch, ist aber momentan nicht in der Software enthalten.

LCD zeigt in Zeile 2 bei verschiedenen Abfragen von Status Registern aus dem asynchron Modus
z.B. eine "3" oder "7" an.

Nach dem Eintrag im Forum kommt der Verdacht auf, dass das binäre Werte sind.welche umgewandelt werden müssen.

Das ist der aktuelle Stand.

Übrigens vielen Dank für die Antworten.
Mit der Zeit sollte ich auch in die korrekte Terminologie reinkommen.

Bin die nächsten zwei Stunden noch online.
Danach werde ich erst am Montag wieder im Forum nachsehen.
Vorab schönes Wochenende.

Grüße
Gerhard73





Quelltext:

'0701.BAS: Timer2, RTC-Beispiel: 1-Hz-LED-Blinker
'Hardware: 32768Hz-Quarz, RC-Oszillator aktiv
' PB0 an grüne LED, PB3/OC2 an rote LED
'----------------------------------------------------------
$regfile = "m8def.dat" 'ATmega8-Deklarationen
$crystal = 1000000 'Der AVR-Takt kommt vom RC-Oszillator
$baud = 19200
$hwstack = 100
$swstack = 100
$framesize = 100



Acsr.acd = 1 'Analogen Komparator ausschalten
Ddrb = &B00001001 'Pins PB0+PB3 sind Ausgang
Assr.as2 = 1 'Bit AS2=1: Asynchroner Timer2-Betrieb
Tccr2 = &B000010100 'Bits6+3=00: Nicht-PWM-Modus
'Bits5+4=01: Pin OC2 invertieren
'Bits2+1+0=100: Takt 32768Hz/64=512Hz
Waitms 1000 'Eine Sekunde warten bis Quarz schwingt

Dim S As Byte
Dim M As Byte 'DIM für sekunden ,minuten und stunden am LCD
Dim H As Byte
Dim Readtcnt2 As Byte 'DIM für Laufzeitvariable

S = 0 'Vorgabe für sekunden ,minuten und stunden für LCD
H = 21
M = 23


'----------------------------------------------------------

Do 'Hauptschleife
Portb.0 = Not Portb.0 'Grüne LED invertieren
Waitms 500 '500 Millisekunden warten

S = S + Ocf2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Initlcd
Cursor Off
Cls
Locate 1 , 1
Lcd H ; ":" ; M ; ":" ; S

Readtcnt2 = Ocf2 'Versuch einen Wert vom Asynchroner Timer2 auszulesen

Locate 2 , 1
Lcd Readtcnt2
Loop
'Ursprung [Listing zum AVR-Mikrocontroller-Lehrbuch von Roland Walter, www.rowalt.de]
 
Hallo Gerhard,

ich nehme mal an, du bist im Besitz des Lehrbuches, dann blätter doch einfach mal etwas weiter ...
Im Listing 0702.bas findest du fast genau, was du suchst.


On Timer2 OnTimer2 'Interrupt-Routine für Timer2-Overflow

ASSR.AS2=1 'Bit AS2=1: Asynchroner Timer2-Betrieb
TCCR2=&B00000100 'Bits2+1+0=100: Takt 32768Hz/64=512Hz
TIMSK.TOIE2=1 'Timer2-Overflow-Interrupt an
SREG.7=1 'Interrupts global einschalten

Dim Sekunden_zaehler as DWORD
dim Halbe_sekunde as Bit

'Hauptschleife

Do
' mache irgendwas

'Auswertung Sekunden_zaehler (Vergleich mit AlarmZeit_in_sek)

'Anzeige (Umrechnung Sekunden --> YYYY_Mo_Dy_HH:MM:SS)
' mache irgendwas

Loop


OnTimer2: 'Timer2-Overflow-Interrupt-Routine
PORTB.3=Not PORTB.3 'Rote LED invertieren
Toggle Halbe_Sekunde 'Takt (512 Hz) durch 2 teilen
if Halbe_Sekunde = 0 then Incr Sekunden_zaehler
Return


Der Timer2 läuft weiterhin asynchron, bei jedem Timerüberlauf wird ein Interrupt erzeugt, dieser stellt die Kopplung ("ausleiten") zu deinem eigentlichen Programm her.
-------------------------------------------------------------

So etwa könnte das aussehen.
Bei allem was mit Zeiten, Datum etc. zu tun hat, macht es Sinn, alles in Sekunden ab einem best. Startzeitpunkt umzurechnen, sieht zwar erstmal komplizierter aus,
hat aber den großen Vorteil, das du problemlos mit Zeitdifferenzen arbeiten kannst, Minuten-, Stunden-, Tages-, Monats-, Jahresüberlauf - alles kein Problem.
Du mußt natürlich zum "Stellen" der Uhr erstmal die aktuelle Zeit + Datum in Sekunden seit 1.1.1900 oder 1.1.1970 umrechnen. Du kannst natürlich auch andere Startwerte nehmen, wenn du keine großen Zeitdifferenzen benötigst, reichen evtl. auch Sekunden seit 00:00.
Für die Anzeige mußt du dann natürlich wieder zurückrechnen. Alarmzeiten sind auch kein Problem - einfach die Alarmzeit in Sekunden umrechnen, dann kannst du die aktuelle Zeit (Sekunden_zaehler) mit der Alarmzeit_in_sek vergleichen.
Auch ein Alarm in 3 Stunden, 5 Minuten und 12 Sekunden (es ist gerade 23:45:27) ist so kein Problem.

Viel Spaß

- gp177 -
 
S = S + Ocf2
...
Readtcnt2 = Ocf2 'Versuch einen Wert vom Asynchroner Timer2 auszulesen
Hallo Gerhard,
warum weist du hier das OCF2 Flag den Variablen zu?
Im Moment übernimmst du dabei übrigens nur die Konstante 7 (Bit Nr. von OCF2 im TIFR).
Wenn du wirklich das Bit verarbeiten willst, dann musst du das Register mit angeben:
Readtcnt2 = TIFR.OCF2
wobei ReadTcnt2 eigentlich darauf hinweist, dass du den Counter Wert haben willst und nicht das Flag.
 
So, mal ein paar grundlegende Gedanken:

erstens: Willkommen im Forum hier auch meinerseits.
zweitens: Programmcode in lesbarer Form posten (ich hab keine Lust, im Handy irgendwelche ZIPs runterzuladen...) - hast Du ja gemacht. Hier nur der Hinweis, die Code-Tags zu nutzen. Am einfacchsten vor dem reinkopieren des Codes oben auf den #-Button klicken. Alternativ kannst Du natürlich auch den Code markieren, und dann klicken, oder die Tags zu Fuß eintippen. Resultat sieht dann so aus:
Code:
 '0701.BAS:  Timer2, RTC-Beispiel: 1-Hz-LED-Blinker
'Hardware:  32768Hz-Quarz, RC-Oszillator aktiv
'           PB0 an grüne LED, PB3/OC2 an rote LED
'----------------------------------------------------------
$regfile = "m8def.dat"                                      'ATmega8-Deklarationen
$crystal = 1000000                                          'Der AVR-Takt kommt vom RC-Oszillator
$baud = 19200
$hwstack = 100
$swstack = 100
$framesize = 100



Acsr.acd = 1                                                'Analogen Komparator ausschalten
Ddrb = &B00001001                                           'Pins PB0+PB3 sind Ausgang
Assr.as2 = 1                                                'Bit AS2=1: Asynchroner Timer2-Betrieb
Tccr2 = &B000010100                                         'Bits6+3=00:    Nicht-PWM-Modus
                                                            'Bits5+4=01:    Pin OC2 invertieren
                                                            'Bits2+1+0=100: Takt 32768Hz/64=512Hz
Waitms 1000                                                 'Eine Sekunde warten bis Quarz schwingt

Dim S As Byte
Dim M As Byte                                                  'DIM für sekunden ,minuten und stunden am LCD
Dim H As Byte
Dim Readtcnt2 As Byte                                       'DIM für Laufzeitvariable

S = 0                                                               'Vorgabe für sekunden ,minuten und stunden für LCD
H = 21
M = 23


'----------------------------------------------------------

Do                                                                'Hauptschleife
  Portb.0 = Not Portb.0                                     'Grüne LED invertieren
  Waitms 500                                                  '500 Millisekunden warten

  S = S + Ocf2
               Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
               Config Lcd = 16 * 2
               Initlcd
               Cursor Off
               Cls
               Locate 1 , 1
               Lcd H ; ":" ; M ; ":" ; S

               Readtcnt2 = Ocf2                             'Versuch einen Wert vom Asynchroner Timer2 auszulesen

               Locate 2 , 1
               Lcd Readtcnt2
Loop
'Ursprung [Listing zum AVR-Mikrocontroller-Lehrbuch von Roland Walter, [url]www.rowalt.de[/url]]
drittens: verfolgt der Buchautor mit seinem Lehrbuch sicher irgendwelche didaktischen Ziele, wenn er Probleme erstmal so und nicht anders angeht. Er will den Leser ja nicht gleich mit der geballten Ladung erschlagen. Insofern sollten wir uns da nicht unbedingt gleich mit IRQs und so einmischen... es sei denn, wir werden dazu aufgefordert.
viertens: bei der Zuweisung von TCCR2 ist 'ne Ziffer zuviel drin, oder
fünftens: wenn Du irgendwelche Interrupt-flags pollst, mußt Du die manuell löschen. Wenn der entsprechende Interrupt als solcher verwendet wird, wird das Flag (bis auf wenige Ausnahmen) automatisch beim ISR-Aufruf (genauer beim Sprung in die IVT) aufgehoben - das mit dem Bit und dem I/O-Register wurde ja bereits angesprochen...
sechstens: noch'n genereller Hinweis -> statt wild loszuprogrammieren sollte man erstmal das Konzept sauber formulieren (und auch hier posten).
Dann kann eventuell bereits das Konzept diskutieren, bevor es an das implementieren geht.

@gp177: wenn der Sekundenzähler 512Hz halbiert, zählt er immer noch mit 256Hz hoch, läuft also (als byte) lediglich im Sekundentakt über (=Carry beim inkrement).
 
Moin, Moin, gp177 und for_ro
Vielen Dank für all die Unterstützung.
Und nun der Reihe nach.....bzw doch zuerst zu for_ro:


S = S + Ocf2
..
..
Readtcnt2 = Ocf2

Das waren die erste Versuche Register und Flags auszulesen.
Habe dabei die Variable nicht geändert. Werde die Listigs zukünftig sorgfälltiger posten.

Dim Readtcnt2 As String * 10
Wert = Tifr
Readtcnt2 = Bin(wert)

Das Ergebnis auf der LCD war dann bei einem Versuch "11000000"

Ich war begeistert, dass dann das Register so abgebildet wurde.
Dein Hinweis mit dem Bit ist gut und verstanden.
Ich taste mich eben so Stück für Stück vor.
Danke for_ro

Nun zu Dir, gp177...
Der Hinweis auf Listing 0702 war/ist richtig...
Dein Listing mit.....'mache irgendwas...usw. führte zu einem AHA - Erlebnis...

Ein technisches Buch in so kompremierter Form zu lesen und umzusetzten dauert seine Zeit.
Habe mitterweile auch festgestellt, dass das Buch Kapitel für Kapitel öfters gelesen werden muß.
Der Bezug und das Verständis kommt meines Erachtens jedoch nur bei eigenen Projekten.
Habe schon einige kleine Erfolge erzielt und brauche dazu eine unabhängige Uhr.
Ziel ist ein automatische Bewässerung von Blumentöpfen.
Mit 220V will ich das nicht durchführen. Der Betreib mit 12V dagegen ist nicht riskant.
Meine Progrogammierarbeit von gestern steht unten.
Weitere Erfolge und die Programmierung der Uhr folgen.
Momentan kann der gewünschte Zeitraum noch mit -Sekunden- abgedeckt werden.
Übrigens...Dim Sekunden_zaehler as DWORD....läuft bei mir nicht.

Hier das aktuelle Listing:


Code:
'0702.BAS:  Timer2, RTC-Beispiel: LED-Blinker mit Aufwecken
'Hardware:  32768Hz-Quarz, RC-Oszillator aktiv
'           PB0 an rote LED     (Simuliert den Motor)
'           PB3/OC2 an grüne LED  (RTC-Takt)
'----------------------------------------------------------
$regfile = "m8def.dat"                                      'ATmega8-Deklarationen
$crystal = 2000000                                          'Der AVR-Takt kommt vom RC-Oszillator

Dim Sekunden_zaehler As Long
Dim Halbe_sekunde As Bit

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Initlcd
Cursor Off

On Timer2 Ontimer2                                          'Interrupt-Routine für Timer2-Overflow


Acsr.acd = 1                                                'Analogen Komparator ausschalten
Ddrb = &B00001011                                       'Pins PB0+PB1+PB3 sind Ausgang
Assr.as2 = 1                                                'Bit AS2=1: Asynchroner Timer2-Betrieb
Tccr2 = &B00000100                                      'Bits2+1+0=100: Takt 32768Hz/64=512Hz
Timsk.toie2 = 1                                             'Timer2-Overflow-Interrupt an
Waitms 1000                                                 'Eine Sekunde warten bis Quarz schwingt

Sreg.7 = 1                                                  'Interrupts global einschalten
'----------------------------------------------------------

Do                                                          'Hauptschleife


    Waitms 100




               Cls                                           'Sekunden anzeigen
               Locate 1 , 1
               Lcd Sekunden_zaehler

             
               If Sekunden_zaehler = 20 Then      'Schaltpunkt der Pumpe     
               Gosub Pumpe_ein
               End If



Loop
'----------------------------------------------------------
Ontimer2:                                                            'Timer2-Overflow-Interrupt-Routine
  Portb.3 = Not Portb.3                                          'Rote LED invertieren
  Toggle Halbe_sekunde
  If Halbe_sekunde = 0 Then Incr Sekunden_zaehler
Return

'----------------------------------------------------------

Pumpe_ein:                                                'Pumpe ein- und ausschalten
   Portb.0 = 1
   Wait 3
   Portb.0 = 0
   Return


So, werde jetzt ein Relais und Transistor einlöten.

Hatte schon gestern antworten wollen aber nach einer unbekannten Zeit war ich automatisch ausgelogt.

Grüße bis demnächst,
Gerhard73
 
Hi,

Hatte schon gestern antworten wollen aber nach einer unbekannten Zeit war ich automatisch ausgelogt.

neben dem Login den Haken bei "Eingeloggt bleiben" setzen. Dann bleibst du so lange drin wie das Cookie im Browser existiert. Wenn der Browser die Cookies löscht bist du wieder draußen.

Gruß
Dino
 

Ü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)