Timer 2 Problem mit Atmega 644 (nach Tausch von Atmega8)

tenor

Mitglied
30. Sep. 2012
169
0
16
44
Sprachen
  1. BascomAVR
Bascom: Timer 2 Problem mit Atmega 644 (nach Tausch von Atmega8)

Hallo,
ich habe eine Aquarium Steuerung angefangen, die einzelnen Komponenten hatten soweit auch funktioniert.
Beim "zusammenfügen" mit Menü Struktur, ist mir dann der Speicher ausgegangen.... Dann habe ich alles neu aufgelötet,
diesmal mit dem Atmega 644 anstellte des Atmega 8.
Vorher hatte ich einen 8MHz Quarzoszillator, jetzt einen 16Mhz.

Der Timer für den Sekunden Takt und für das PWM Signal funktioniern jetzt nicht mehr. (zuerst aber das PWM :) )
Ich verwende Bascom Basic.

Der Code sieht im Moment ca. so aus:

Code:
$regfile = "m644def.dat"
$crystal = 16000000


Config Lcdpin = Pin , Db4 = Porta.2 , Db5 = Porta.3 , Db6 = Porta.4 , Db7 = Porta.5 , E = Porta.1 , Rs = Porta.0
Config Lcd = 16 * 2                                         'configure lcd screen

Config Porta = Output                                       'LCD Display
'Config Portc = Output
'Config Pinc.3 = Output
Config Pind.7 = Output                                      'PWM
Config Pina.6 = Input
Config Pina.7 = Input
'Config Pinc.5 = Input
'Config Pinc.4 = Input
Ddrc = &B00001000
Initlcd                                                     'init display again
Cursor On
Cls
'Const Timervorgabe = 34286
Const Timervorgabe = 3036
'Konfiguration Timer 2 für Hardware-PWM an OC2 (B.3)
Config Timer2 = Pwm , Prescale = 128                        ', Compare = Set
'Config Timer2 = Pwm , Prescale = 128 , Compare = Clear
Config Timer1 = Timer , Prescale = 256                      'Timer1 für den Sekundentakt
Enable Timer2
Timer2 = 0
Start Timer2
On Timer1 Timer_irq
Enable Timer1
Main:
Cls
Do
Ocr2a = 157
loop 
Timer_irq:
   Timer1 = Timervorgabe
   Isekunde = Isekunde + 1
   If Isekunde => 60 Then
      Isekunde = 0
      Isminute = Isminute + 1
   End If
   If Isminute => 60 Then
      Isminute = 0
      Istunde = Istunde + 1
   End If
   If Istunde => 24 Then
      Istunde = 0
   End If
   If Istunde = Pwm_startstd And Isminute => Pwm_startmin Then       'Trigger nur erhöhen wenn Startzeit erreicht ist
      If Dauer => Prescale2 And Pwm_trigger < 255 Then      'Trigger nur erhöhen wenn prescale erreicht ist (Teiler damit auf eine Stunde gedimmt wird)
         Pwm_trigger = Pwm_trigger + 1
         Dauer = 0
      End If
   End If
   If Istunde = Pwm_startstd2 And Isminute <= Pwm_startmin Then       'Trigger nur erhöhen wenn Startzeit erreicht ist
      If Dauer => Prescale2 Then                            'Trigger nur erhöhen wenn prescale erreicht ist (Teiler damit auf eine Stunde gedimmt wird)
         Pwm_trigger = Pwm_trigger + 1
         Dauer = 0
      End If
   End If
   Dauer = Dauer + 1
Return

Hat da jemand eine Idee?
Ich messe immer nur volle 11 V an Pind.7 (OC2).
Durch das einstellen des Registers OCR2 von 0-255 möchte ich die Spannung von 1-11V erreichen.

Besten Dank vorab!
 
Hallo tenor,

Willkommen im AVR-Praxis-Forum.

Ich kenne mich leider mit Bascom nicht so aus, aber vielleicht hilft dir folgendes weiter:

Der Timer/Counter2 des ATmega644 hat zwei PWM-Pins, OC2A (PD7) und OC2B (PD6). In der Configurationszeile für PWM des Timer2 wählst du nicht explizit OC2A aus. Ich weiß nicht was Bascom macht, wenn man hier nichts angibt.

Ich hoffe du misst nicht direkt am Pin des Mikrocontrollers 11V, die höchste zulässige Spannung ist VCC+0,5V!

Dirk :ciao:
 
Hallo tenor,

wie schon erwähnt, wird es am fehlenden Parameter bei der Konfiguration liegen.


Du musst explizit CompareA und/oder CompareB PWM wählen.
Folgendes ist nur ein Beispiel.

Code:
Config Timer2 = Pwm , [B]Compare A Pwm[/B] = Clear Up , [B]Compare B Pwm[/B] = Clear Up , Prescale = 8

Dirk :ciao:
 
Besten Dank!
Daran hat´s gelegen :)

Jetzt muss ich nur noch den Sekundentakt hinbekommen, dann bin ich da wo ich schon vor einem Monat mit dem Atmega 8 war :)

Timer 1 ist ja ein 16 Bit Timer, folgendes sollte doch jede Sekunde den Interrupt auslösen
Code:
Config Timer1 = Timer , Prescale = 256 
Const Timervorgabe = 3036
On Timer1 Timer_irq
Enable Timer1


Timer_irq:
   Timer1 = Timervorgabe
   Isekunde = Isekunde + 1
Return

Leider passt das so noch nicht. Hast du da auch noch eine Idee?
 
Hallo!

Habe ich etwas übersehen, oder hast du einfach nur vergessen global alle Interrupts mit:
Code:
Enable Interrupts
erst mal einzuschalten. :wink:

Ohne die Angabe, werden keine Interrupts ausgeführt.


Grüße,
Cassio
 
Wie Cassio schon geschrieben hat, müssen Interrupts aktiviert werden.

Der Nachladewert stimmt jedenfalls.

Dirk :ciao:

timer1.png
 
Danke, die hatte ich jedoch schon aktiviert.
Unter meiner Variablendeklaration hatte ich das gemacht, der Übersichtlikeits halber hab ich die hier weggelassen.

Hab die Sekundenausgabe auf das LCD gebracht, der Interrupt löst aus, allerdings wird die Sekundenvariable nur ca. alle 8 Sekunden hoch gezählt..

Hab daraufhin den Fehler gefunden.
Bei den Fusebits, war der Haken "devide clock internally by 8" gesetzt.

Besten Dank an alle! :)
 
Der 644 kann doch den Timer1 auch im CTC fahren (über das ICR1 oder OCR1A) also statt dem Reload dann CTC mit 62500), oder irre ich mich da?
Das mit der CKDIV8-Fuse haste ja inzwischen selbst rausbekommen...
(Und ich such hier verzweifelt nach den Variablendeklarationen...)
 
Der 644 kann doch den Timer1 auch im CTC fahren (über das ICR1 oder OCR1A) also statt dem Reload dann CTC mit 62500), oder irre ich mich da?
Keine Ahnung.. Was wäre der Vorteil für mich an der Stelle?

Das einzige bonbon was ich mir die Programmieren noch erleichtern würde, wäre die interne Uhr zu benutzen.
Für die Start und die Stop Zeit rechne ich im Moment noch mit den Variablen für die Stunde und Minuten.
Zumindest für den Atmega8 habe ich es nicht hinbekommen.

Aber so geht es ja auch :)
Code:
If Istunde >= Pwm_startstd And Pwm_startstd < Pwm_stopstd And Isminute >= Pwm_startmin Then Evg = 1       'EVG einschalten wenn das Dimmen beginnen soll
If Istunde >= Pwm_stopstd And Pwm_stopstd > Pwm_startstd And Isminute >= Pwm_stopmin Then Evg = 0       'EVG ausschalten
 
Hallo,

Das einzige bonbon was ich mir die Programmieren noch erleichtern würde, wäre die interne Uhr zu benutzen.
Für die Start und die Stop Zeit rechne ich im Moment noch mit den Variablen für die Stunde und Minuten.
Zumindest für den Atmega8 habe ich es nicht hinbekommen.

Aber so geht es ja auch :)
Code:
If Istunde >= Pwm_startstd And Pwm_startstd < Pwm_stopstd And Isminute >= Pwm_startmin Then Evg = 1       'EVG einschalten wenn das Dimmen beginnen soll
If Istunde >= Pwm_stopstd And Pwm_stopstd > Pwm_startstd And Isminute >= Pwm_stopmin Then Evg = 0       'EVG ausschalten
ein alt bekanntes Mißverständnis des Datenblattes :p
Der Atmel (weder Tiny noch Mega) hat keine eingebaute Echtzeituhr. Es existiert lediglich ein zweiter Oszillator (Pins TOSC1/TOSC2) an dem ein 32kHz Uhrenquarz für eine asynchrone Taktung angeschlossen werden kann. Damit betreibt man dann einen Timer und der erzeugt einen Basistakt für eine Software-Echtzeituhr. Nur damit erst gar keine Mißverständnisse aufkommen ;)

Gruß
Dino
 
interne Uhr? Was meinst Du damit?
Du kannst Timer2 mit einem externen 32kHz-Quarz betreiben, aber um die Zählerei mußt Du Dich auch dort selbst kümmern. Oder Du hängst eine externe echte RTC über irgendeine Schnittstelle an den Controller (SPI/TWI), ggf dann auch synchronisiert mittels Zeitzeichenempfänger.

Reload vs CTC: wenn der Timer es kann (und das Programm es erlaubt), finde ich CTC besser. Dadurch läuft der "reload" komplett selbständig im Hintergrund, spart pro Interruptaufruf 2 Instruktionen.
 
schade :(
ich habe das aus der Hilfe --> Time
Action

Returns a time-value (String or 3 Byte for Second, Minute and Hour) depending of the Type of the Target





Syntax

bSecMinHour = Time(lSecOfDay)

bSecMinHour = Time(lSysSec)

bSecMinHour = Time(strTime)



strTime = Time(lSecOfDay)

strTime = Time(lSysSec)

strTime = Time(bSecMinHour)



In der Tat Plane ich ein DHCF Empfangsmodul zu verwenden, hab es hier schon liegen aber noch nichts mit gemacht.
Dachte eigentlich dieses Modul "füllt" mir die Time Variablen.

bzgl. CTC-
Das muß ich mir erstmal anschauen, das sagt mir im moment gar nichts.
 
In der Tat Plane ich ein DCF Empfangsmodul zu verwenden, hab es hier schon liegen aber noch nichts mit gemacht.
Dachte eigentlich dieses Modul "füllt" mir die Time Variablen.
tja ... beim Mikrocontroller gibt es kein "Plug and Play". (Windows versaut ?) Du mußt dich um alles selber kümmern. Frei nach dem Spruch eines Projektmitarbeiters : "Wenn du willst das was funktioniert, dann mach es selbst!" :p :rolleyes:

Der DCF-Empfänger liefert dir lediglich Pulse von 0,1s oder 0,2s Länge (0/1-Bits) die in binärer Weise Minuten, Stunden, Wochentag, Tag, Monat, Jahr kodieren. Nicht mehr und nicht weniger. Die Pulse mußt du noch selber ausmessen um zu wissen ob jetzt 0 (0,1s) oder 1 (0,2s) gesendet wurde. Außerdem mußt du selber die Bits hintereinandersetzen, die Checksumme berechnen und Fehler in der Übertragung erkennen.

Dafür gibt es auch fertige Bibliotheken die man einbinden kann. Wenn es aber nicht zum Rest deines Programms oder deiner gewünschten Problemlösung paßt, dann mußt du es wieder komplett selber machen.

Gruß
Dino
 
Ne, plug and play ist nicht, keine Frage.
Dachte nur das ich mit dem DCF diese Bascom Timer Funktion benutzen kann.
So dass ich dann nur noch die Variablen für die Zeit auslesen kann.

Das das nicht soo simpel ist mit dem DCF ist mir schon klar, hat ja einen Grund warum dieser noch in der Schublade steckt ;)
 
Dachte nur das ich mit dem DCF diese Bascom Timer Funktion benutzen kann.
So dass ich dann nur noch die Variablen für die Zeit auslesen kann.
Es gibt für DCF ne Bascom-Lib die dir die Impulse vermißt, Fehler erkennt und die empfangene Zeit in Variablen lagert. Die mußt du dann wirklich nur noch auslesen. Wenn du das so meinst, dann geht das. Bascom kann das von sich aus aber nicht und Assembler (das unter Bascom) erst recht nicht. Es hat sich einfach mal einer hingesetzt und eine Bibliothek in Assembler geschrieben die dann in Bascom eingebunden wird und Variablen mit den Zeitinformationen bereitstellt.

Es gibt solch eine Bibliothek die mit Bascom mitgeliefert wird und es gibt eine, die glaube ich bei mikrocontroller.net entstanden ist.

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)