Bascom BASCOM ; Erste Schritte zum Ausprobieren

Nein. Compare2 wäre schon richtig. Compare1 ist für Timer 1. Aber Compare2 hat sich Bascom eingespart, daher musst du den AVR Namen nehmen, also OC2 (=Output Compare, Timer 2). Also On OC2 [NameDerSprungmarke]
Ohne [] natürlich.
 
Damit habe ich jetzt erst einmal ein blinken erreicht, aber es ist viel zu schnell für einen Sekundentakt. Es sollte doch ein Sekundentakt sein, oder?


CodeBox BascomAVR
$regfile = "m8def.dat"                  'Controllerdefinitionsdatei einbinden
$crystal = 8000000                      'Systemtakt angeben (Baudrate)
$hwstack = 40                           'Stacks
$swstack = 16
$framesize = 32
$baud = 19200                           'Baudrate UART
'Dim Zeichen As Byte                     'UART-Empfang
Dim Count As Byte
Ddrb = &B_1111_1111
Portb = &B0000_0000
Ddrc = &B_11_1111
Portc = &B00_0000
Ddrd = &B_1111_1111
Portd = &B0000_0000
Rot Alias Portd.7
Gruen Alias Portc.3
Ocr2 = 249
Config Timer2 = Ctc , Prescale = 256 , Clear_timer = 1       ', Compare A = Disconnect
On Oc2 Isr_timer2
Enable Oc2
On Timer2 Isr_timer2
Enable Timer2
Enable Interrupts
Main:
   Reset Watchdog
   Goto Main
Isr_timer2:
   Ocr2 = 249
   Toggle Gruen
Return
 
Die Zeilen


CodeBox BascomAVR
On Timer2 Isr_timer2
Enable Timer2

beziehen sich nur auf den Timer Überlauf. OC2 ist das was wir brauchen.
Und in der ISR musst du den OCR2 nicht neu setzen, der bleibt bestehen (außer du deaktivierst und reaktivierst den Timer).
Die 3 Zeilen sind also unnötig.
Aber: Sekundenintervall ist das ja auch noch nicht, sondern 8ms. Jetzt musst du noch von 8ms auf 1s kommen. Wie sagte ich schon, hast du auch schon gemacht früher ;)
 
Okay, dachte ich mir schon fast. Aber“Dekan“ kann ich nicht nehmen, ist irgend ein Befehl von Bascom.
 
Nach langem rätseln, habe ich den Code aus #413 etwas zusammen gebastelt. Ich hoffe nur, dass es das ist, was ich erreichen sollte. Auf jeden Fall blinkt Grün im Sekundentakt. Eingabe ASCII (1) im Terminal lässt Rot für eine Minute leuchten.

CodeBox BascomAVR
$regfile = "m8def.dat"                  'Controllerdefinitionsdatei einbinden
$crystal = 8000000                      'Systemtakt angeben (Baudrate)
$hwstack = 40                           'Stacks
$swstack = 16
$framesize = 32
$baud = 19200                           'Baudrate UART
Dim Zeichen As Byte                     'UART-Empfang
Dim Count As Byte
Dim Countdown As Word
Ddrb = &B_1111_1111
Portb = &B0000_0000
Ddrc = &B_11_1111
Portc = &B00_0000
Ddrd = &B_1111_1111
Portd = &B0000_0000
Rot Alias Portd.7
Gruen Alias Portc.3
Ocr2 = 249
Config Timer2 = Ctc , Prescale = 256 , Clear_timer = 1
On Urxc Onuartrx
Enable Urxc
On Oc2 Isr_timer2
Enable Oc2
Enable Interrupts
Main:
   Config Powermode = Idle
   Goto Main
Onuartrx:
   Zeichen = Inkey()                    'dann Zeichen aus Puffer lesen
   If Zeichen = 0 Then                  'bei 0x00 PWM deaktivieren
      Rot = 0
   Elseif Zeichen = 255 Then            'bei 0xFF PWM aktivieren
      Rot = 1
   Else
      Countdown = Zeichen * 60
      Rot = 1
   End If
Return
Isr_timer2:
   Incr Count
   If Count = 125 Then
      Count = 0
      Toggle Gruen
      If Countdown = 0 Then
         Rot = 0
      Else
         Decr Countdown
      End If
   End If
Return
 
Sieht gut aus, auch weil schon UART drin ist (brauchen wir später).
Bei 255 wird Rot zwar nur so lange an bleiben wie der Wert in Countdown besagt, aber Details. Das war jetzt auch nicht gefordert :)

Als nächstes kommt Timer1 als Counter dran. Da muss ich mich aber erst selbst schlau lesen.
Vom Grundprinzip: Du hast einen IO Pin der automatisch den Wert in (hier Timer1) erhöht. Zur Not geht es auch von Hand.
Du hast deinen 1 Sekunden Intervall. also muss nur noch der Timer Wert genommen werden, das ist die Frequenz in Hz.
 
Also, kurze Info zur Funktion als Frequenzteiler:
Wichtig zu wissen ist, dass die maximale Frequenz, die gemessen werden kann, die Systemfrequenz / 2,5 ist. Alles darüber ist höchstens als Schätzwert anzusehen.
Du fährst ihn jetzt mit 8MHz, macht also rund 3,2MHz Maximum. Angeben würde ich eher 3.
Auch wichtig für die Beschaltung: Du darfst natürlich nur Signale anlegen die zwischen GND und VCC liegen. Für den praktischen Einsatz, und um den Chip abzusichern falls zB. mal 12V Signale anliegen: Die Eingänge sind hochohmig genug. Quick'n'dirty, eine Z-Diode gegen Masse und ein Widerstand (47k zB.) in Reihe reicht normalerweise aus. (NICHT FÜR NETZSPANNUNG!)

Also, nach aktuellem Plan könnten wir 0Hz..3MHz messen, in 1Hz Schritten. Theoretisch. Fakt ist aber dass der Timer bei 16 Bit überläuft, also 65.535KHz ist vorerst das Maximum. Die Genauigkeit kann man noch erhöhen, später.

Kommende Aufgaben:
* Timer1 aufsetzen (Config) und anschließen. Ein Quarz Oszillator oder Frequenzgenerator wäre ideal, aber es tut auch ein Taster zu GND.
Interrupt wird vorerst(!) nicht benötigt.
* Im 1 Sekunden Intervall den Wert von Timer 1 über UART ausgeben.
* Die Genauigkeit erhöhen, speziell für niedrigere Frequenzen

Code und Beschaltung muss ich noch suchen.
 
Ich habe noch eine Frage, um es zu verstehen und nicht einfach nur zu schreiben, weil (na ja gut so, es funktioniert).
Overflow (Reload) = Überlauf (neu laden)
Compare = vergleichen
Compare haben wir ja angewendet. Overflow bestimmt auch schon mal. Ich kann mir aber keinen Zusammenhang aufbauen.
Hier ist auch ein Überlauf, doch die Zahlen kommen beim Calculator nicht raus.

CodeBox BascomAVR
If Tifr.tov1 = 1 Then             'wenn Timer übergelaufen ist
         Tifr.tov1 = 1                  'Überlaufflag zurücksetzen
         Incr Z
         If Z = 245 Then                'Überläufe zählen (245)
            Z = 0                       'Zähler zurücksetzen
            Toggle Gruen                'LED toggeln
         End If
 
Zuletzt bearbeitet:
Falsch gedacht. Bei Compare kommt der Calculator auf 245. Wann und wie wird dann der Overflow angewendet?
 
Also, der Timer ansich ist recht dumm. Er zählt einfach nur. Von 0 bis zum Maximalwert, oder anders herum.
Manche Timer kann man jetzt noch konfigurieren. Den Maximalwert ändern (Compare), verschiedene PWM Modis mit oder ohne dass automatisch der Ausgang gesetzt wird... Aber im Prinzip ist und bleibt es ein Zähler.

Overflow und Compare ist fast das Selbe.
Mit Compare gibst du dem Timer einen Maximalwert vor. Sprich, wenn Wert x erreicht ist wird automatisch wieder auf 0 gesetzt. Du bekommst dann halt den Compare Interrupt. Gezählt wird 0..x
Bei Overflow bekommst du naturgemäß einen Interrupt. Das Maximum hängt von der Bittiefe ab, 8 Bit = 255, 16 Bit = 65535. Um jetzt die Frequenz zu erhöhen muss man schnellstmöglich den Timerwert, der ja jetzt 0 ist, um Wert x erhöhen. Gezählt wird x..(Max)

Du nutzt die internen 8 MHz und den /8 Teiler, macht 1MHz Systemtakt.
Dann nutzt du den /8 Vorteiler für den Timer, macht 125KHz.
Das durch 256 geteilt (8 Bit).
Ergibt ~488 Überläufe pro Sekunde (Hz).
Das durch 2 geteilt (wegen phasenkorrekt) 244. (245 weil du erst erhöhst, dann überprüfst)

In der Überlauf Routine hast du selber noch einen weiteren Zähler generiert (die Zählervariable) wo du quasi in Software genau das machst was der Timer in Hardware macht. Der Hardware Timer füttert dein Software Timer bei Überlauf. Du hast hier also quasi eine Kette aus 2 Timern. Timer1 (Hardware) benachrichtigt dich bei Überlauf, und der Software Timer führt Code aus wenn der Vergleich (Compare) mit einer Vorgabe (245) erfüllt ist und setzt sich auf 0 zurück.
 
Hier ist auch ein Überlauf, doch die Zahlen kommen beim Calculator nicht raus.
Sowohl Dirks Calculator für Windows als auch meiner für Android berücksichtigen nur Timer, die im single Slope laufen (also inkrementieren, überlaufen und (eben von 0) weiterinkrementieren). Ein 8Bit-Timer macht so also 28 Schritte pro Überlauf, ein 16Bit-Timer 216. Meint Tool bietet außerdem noch 9 und 10 Bit.

Der hier verwendete Modus ist aber ein phasenkorrekter dual Slope, der Timer pendelt zwischen null und maximum hin und her. Strenggenommen läuft er also gar nicht über, das Überlaufsereignis tritt jedesmal ein, wenn die null erreicht wird. Also fast(!!) halb so oft (fast doppelt so viele Schritte). Warum nur fast? Weil der tatsächliche Überlauf-Schritt fehlt (bei 8Bit der Schritt von 255 zu 0, der 256ste Schritt), und das eben zweimal.
Bei 8Bit sind es jetzt also (28*2)-2 Schritte. Oder 28+1-2 Schritte. Ein 16Bit-Timer entsprechend 216+1-2 Schritte.

(Eigentlich müßten @Dirk und @me irgendwann mal die dualSlopes miteinpflegen... aber ich hasse Java-Programmierung, speziell unter Android selbst).

P.S.: Eigentlich war ich der Meinung, die Berechnung hier irgendwo mehrfach gründlich durchgekaut zu haben...

P.P.S. @Dirk : hochgestellter Text kollidiert mit der Zeile drüber - das hatten wir meiner Erinnerung nach schonmal/hattest Du schonmal korrigiert - jetzt isses wieder da... (*nochmalAufDeineToDoListeSchieb*)
 
Du nutzt die internen 8 MHz und den /8 Teiler, macht 1MHz Systemtakt.
Dann nutzt du den /8 Vorteiler für den Timer, macht 125KHz.
Das durch 256 geteilt (8 Bit).
In #528 Systemtakt = 8 MHz
Vorteiler ist doch der Prescale(r) 256 und nicht 8
Wer oder was ist der Teiler /8 und macht 1MHz daraus ?
LotadaC meint, dass wir die Timerberechnung schon mehrmals durchgekaut haben. Eigentlich kann ich schon ein bisschen rechnen, nur was mit wem geteilt werden muss bringt mich durcheinander. Ja, jetzt sind auch noch Compare und Overflow im Spiel.
 
8MHz hat der Controller intern, der /8 Teiler kann per Fuse dazu geschaltet werden, hat mit dem Code nichts zu tun. Wenn aktiv ist der effektive Systemtakt also 1MHz.
Der /8 ist der Prescaler vom Timer. Hattest du meine ich mal verwendet, zuletzt /64.
Gut möglich dass du die Fuse jetzt gelöscht hast. Dann kommst du mit Prescaler /64 (=/8/8) aber auf's Selbe hinaus.

256 ist der Wert bei dem der Timer überläuft, ist also der Takt des Überlaufens, nicht des Timers selbst. Also die Quelle des Overflow Interrupts.
 
Ich habe heute mal den Code in #528 in einem 12 Stunden Test laufen lassen. Dieser ging auf die Sekunde genau.
Ich habe momentan einen externen 8MHz Quarz. Ich habe nur ein Problem, wenn ich die RxD und TxD vom Board trenne, resetet der µC oder das Board.
Woran kann das liegen?
 
Ist mir jetzt noch nie passiert. Läuft er denn danach normal weiter?
 
Nein, es ist so, als hätte man die Resettaste gedrückt.
Aufgabe #531 bin ich noch nicht ganz fertig.
 

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