Fehler in Timerdefinitionen bei ATtiny25?

ATMega-Controller in BASIC programmieren

Postby thomas scherer » Mon Aug 23, 2010 12:00 am

Gerade wollte ich mit dem Timer0 eines ATtiny25 ein PWM-Signal erzeugen, statt Impulse damit zu generieren, wie es sonst meine Art ist.
Dabei habe ich in Bits und Bytes beißen müssen, denn der übliche "config"-Befehl
Config Timer0 = Timer etc.

tut zur zwar vollsten Zufriedenheit und auch die PWM-Variante

Config Timer0 = Pwm , Compare A Pwm = Clear Up , Prescale = 64

funktioniert klasse - leider aber nur auf einem anderen Controller wie z.B. dem ATtiny24.
Ich hätte aber gerne so einen winzige 8-Beiner und habe auch die 25er, 45er und 85er da - nur wollen sie alle nicht mitspielen.
Sehe ich das richtig, dass ich mich daher unbequemen muss und die kompletten Config-Bits einzeln und von Hand setzen?
"Das Internet" munkelt sowas in der Art...
Oder hat schon jemand mal einen 25er mit PWM auf Timer0 erfolgreich laufen lassen ohne Bits zu quälen?
thomas scherer
 
Posts: 1128
Joined: Thu Jan 02, 2014 10:38 am

Postby thomas scherer » Tue Aug 24, 2010 12:00 am

Okay, abgehakt.
Hier ist die Handarbeitslösung, jedes Bit einzeln gestreichelt.
Funktioniert mit ATtiny25, ATtiny45 und ATtiny85.

'*** Configuring Timer0 as 8 bit PWM ***
'* clear Timer registers
Tccr0a = 0
Tccr0b = 0
'* compare output mode A (= non inverting)
Tccr0a.com0a0 = 0
Tccr0a.com0a1 = 1
'* compare output mode B (= inverting)
Tccr0a.com0b0 = 1
Tccr0a.com0b1 = 1
'* phase correct PWM (top = hexFF)
Tccr0a.wgm00 = 1
Tccr0a.wgm01 = 0
Tccr0b.wgm02 = 0
'* set PWM values
Ocr0a = Duty_cycle
Ocr0b = Duty_cycle
'* select timer prescaler and start timer
Select Case T0presc
Case 1 : Tccr0b = Tccr0b Or &B001
Case 8 : Tccr0b = Tccr0b Or &B010
Case 64 : Tccr0b = Tccr0b Or &B011
Case 256 : Tccr0b = Tccr0b Or &B100
Case 1024 : Tccr0b = Tccr0b Or &B101
Case Else : Nop 'stops timer
End Select


Danke Thomas!
(bei irgendjemand muss ich mich ja bedanken)
thomas scherer
 
Posts: 1128
Joined: Thu Jan 02, 2014 10:38 am

Postby albert » Tue Aug 24, 2010 12:00 am

Hallo!

Zur Info, hier findet man diverse BASCOM-FEHLER und
gegebenenfalls auch Lösungen.
http://bascom-forum.de/index.php/board,9.0.html

mfg

albert
albert
 
Posts: 106
Joined: Fri Jan 03, 2014 1:47 pm

Postby thomas scherer » Sat Aug 28, 2010 12:00 am

Stimmt, Fehler findet man da. Diesen Fehler aber nicht. Und auch keine passende Lösung
Ich habs aber dank Deiner Anregung auch dort mal gepostet.
thomas scherer
 
Posts: 1128
Joined: Thu Jan 02, 2014 10:38 am

Postby thomas scherer » Tue Aug 31, 2010 12:00 am

So, es gab auch eine Antwort dort im Forum,
die mir half, meinen Fuß von der Leitung zu nehmen.
Ich weiß auch nicht, warum ich nicht gleich drauf gekommen bin,
aber der Einspruch war berechtigt
Es stimmt nämlöich, dass man nicht generell von einem Fehler bei der Kombi: ATtiny25 & Config TIMER0 = Pwm reden kann.
Es stimmt, dass die Bits in den beiden Registern TCCR0A und TCCR0B für phase correct PWM korrekt gesetzt werden.
Es stimmt auch, dass man Dinge wie einen Fast PWM mode via Register-Bits einschalten muss.

Und jetzt kommt der Haken: Es ist nämlich so, dass die beiden BASCOM-Befehle Stop TIMER0 und Start TIMER0 beide die unangenehme Eigenschaft haben, vorher gesetzte Bits im Register TCCR0B zu löschen.

Nach
Config Timer0 = Pwm , Compare A Pwm = Disconnect , Compare B Pwm = Clear Down , Prescale = 64

enthält TCCR0B ja das Bitmuster 00001011.

Kommt jetzt
Stop TIMER0

dann ist TCCR0B = 00000000, wird also komplett gelöscht.

Beim Befehl
Start TIMER0

ist es dann so, dass nur die drei niederwertigsten Bits mit der Prescaler-Info restauriert werden,
Das heißt, auch wenn man die Bits in TCCR0B.7 bis TCCR0B.3 vorher restauriert, steht nach dem
Befehl in TCCR0B nur das Muster 00000011 statt 00001011 drin.

Statt einem Fast PWM mode mit OCR0A = TOP wird daraus dann ein normaler Fast PWM mode
mit xhFF = Top.

Sodele, geklärt die Sache. Ich weiß nicht, ob das jetzt ein echter Bug oder nur ein Viertel-Bug ist.
Doch wenn das verhalten von Start und Stop TIMERX schon geändert wer den sollte, dann könnte
MCS auch gleich Nägel mit Köpfen machen und die anderen Timer-Modi implementieren,
also für Config TIMERX neben COUNTER | TIMER | PWM auch gleich noch die fehlenden Attribute
FAST PWM | PWM OCRA | FAST PWM OCRA und die Sache wäre perfekt.

Mein neuer Umgehungs-Code (Ersetzung für Start und Stop TIMERX) sieht daher so aus:
$regfile = "attiny25.dat"                      'chip

$noramclear 'saves memory

'*** stack spaces ***
$hwstack = 32 'hardware stack
$swstack = 10 'software stack
$framesize = 40 'frame space

'*** port settings ***
Config Portb = Input

'*** effective clock settings ***
Config Clockdiv = 4

'*** constants ***
Const Period = 80
Const Pulse = 20

'*** variables ***
Dim Start_timer As Byte
Dim Stop_timer As Byte

'*** configure TIMER0 in Fast PWM mode with OCR0A as TOP ***
Config Timer0 = Pwm , Compare A Pwm = Disconnect , Compare B Pwm = Clear Down , Prescale = 64
Tccr0a.wgm01 = 1 'set fast mode
Tccr0b.wgm02 = 1 'set OCR0A = TOP
Start_timer = Tccr0b 'stores value to start timer
Stop_timer = Tccr0b And &B11111000 'stores value to stop timer
Tccr0b = Stop_timer 'stops TIMER0

'* preset of OCR0A and OCR0B
Ocr0a = Period
Ocr0b = Pulse

'*** interrupt start ***
Enable Timer0
Enable Interrupts

Tccr0b = Start_timer 'starts TIMER0

'*** main loop ***
Do
nop
Loop
thomas scherer
 
Posts: 1128
Joined: Thu Jan 02, 2014 10:38 am

Postby thomas scherer » Tue Aug 31, 2010 12:00 am

Und noch ein kleines Käferchen, das irgendwo zwischen echten bug und Unbequemlichkeit liegt:
Der Befehl
Config Timer0 = Pwm , Compare A Pwm = Disconnect , Compare B Pwm = Clear Down , Prescale = 64

setzt trotz dem Parameter "Compare A Pwm = Disconnect"
den Pin, der zu OC0A (hier PORTB.0) gehört, auf Ausgang.
Das DDRB-Register enthält anschließend das Muster 00000011, d.h. dass beide Compare-Pins OC0A und OC0B als Ausgang konfiguriert werden. Was unnötig bzw. störend ist.
Will man im Fast-PWM-Mode, wo OC0A ja nicht verwendet wird, weil im Register OCR0A ja der Endwert (TOP) des Timers steht, diesen Pin aber als Eingang nutzen, muss man ihn nach der Timer-Konfiguration nochmal explizit auf Eingang setzen.
Beispiel:
Config PORTB.0 = Input
thomas scherer
 
Posts: 1128
Joined: Thu Jan 02, 2014 10:38 am

Postby thomas scherer » Tue Mar 12, 2013 12:00 am

Übrigens gibt es bei Verwendung von Timer1 als PWM-Quelle mit einem ATtiny25/45/85 ernsthafte Probleme, da in der Bascom-Definitionsdatei der Controller eines nicht bedacht wurde:
Die Variable "PWM1B" z.B. ist mehrfach definiert, einerseits als Äquivalent zu OCR1B und andererseits als Bit im Register GTCCR.
Das hat Zur Folge, dass das Setzen des PWM-Modus nicht funktioniert, da GTCCR.PWM1B nicht etwa das Bit 6 sondern das Bit 1 setzt.
Abhilfe ist das numerische Setzen des Bits, also GTCCR.6 = 1.
Mit der normalen Bascom-Konfiguration wie config Timer1 PWM etc. funktioniert die Sache natürlich mal gleich gar nicht.

Das hat mich viel Nerven gekosten und erst Galahat aus dem Bascom-Forum hat mich drauf gebracht.
thomas scherer
 
Posts: 1128
Joined: Thu Jan 02, 2014 10:38 am


Return to BASCOM-AVR-Kurs

Who is online

Users browsing this forum: No registered users and 1 guest