PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Attiny12 und Timer0 ?



Ronny81
20.01.2010, 17:34
Tach zusammen,

ich habe ein Problem mit der Programmierung eines Timers auf einem
Attiny12.
Ich will über das PPM-Signal aus der Fernsteuerung einen Ausgang schalten.
Leider will der Timer nicht hochzählen. Ich habe den Mc minimal beschalten
und ohne Quarz laufen. Kann das ein Problem sein?



$regfile = "attiny12.dat" ' Controller = ATtiny12
$crystal = 1000000 ' Takt 1MHz
$noramclear ' RAM nicht initialisieren
$tiny ' Stack nicht initialisieren
'$hwstack = 32 ' Stackinitialisierung wird durch $TINY unterdrückt
$swstack = 0 ' Software 0
$framesize = 0 ' Framesize = 0

'################################################# ################################################## ##############################
'#
'# Hardware initialisieren
'#
'################################################# ################################################## ##############################

Config Timer0 = Timer , Prescale = 1024 'Timer0 geht gut

Config Portb.0 = Output
Config Pinb.4 = Input
Portb.0 = 1

'################################################# ################################################## ##############################
'#
'# Variablen
'#
'################################################# ################################################## ##############################

'Dim Rc As Iram Byte ' Variablen als IRAM definieren

'################################################# ################################################## ##############################
'#
'# Hauptprogramm
'#
'################################################# ################################################## ##############################

Do

'Geberweg des Senders Minimum = 65 / Maximum = 110 / Mitte = 87

If Pinb.4 = 0 Then
Bitwait Pinb.4 , Set 'Auf positive Flanke warten
Timer0 = 1 'Zaehler starten
Bitwait Pinb.4 , Reset 'Auf negative Flanke warten
Rc = Timer0
Else
End If

If Rc > 70 Then Portb.0 = 0

Loop



Gruß Ronny

Sauerbruch
20.01.2010, 20:01
Hi Ronny!


Ich habe den Mc minimal beschalten
und ohne Quarz laufen. Kann das ein Problem sein?

Möglicherweise ja. Im Auslieferungszustand sind die Fusebits beim Tiny12 so gesetzt, dass er seinen Takt über einen externen Quarz generiert. Wenn das das Problem wäre, dürfte sich das Ding aber auch nicht brennen lassen, weil natürlich auch dazu irgendeine Art von Takt zwingend nötig ist.

Bekommst Du denn das Programm in den Controller??

Viel schlimmer ist aber, dass der Tiny12 gar kein RAM, sondern nur ein EEPROM hat. Das lässt sich ca. 100.000 mal beschreiben, und dann war´s das. Und 100.000 Zyklen sind schnell zusammen - bei ener Signalfrequenz von 50Hz (üblich bei RC-Signalen) in unter 1 Stunde...
Ich würde mir an Deiner Stelle für diese Anwendung unbedingt einen Controller holen, der zumindestens ein paar lausige Bytes RAM-Speicher hat.



Zu dem Code ist mir folgendes aufgefallen: Bei einer Taktfrequenz von 1MHz und einem Prescaler von 1024 zählt der Timer ziemlich genau alle 1ms eins weiter. Handelsübliche RC-Signale spielen sich in der Größenordnung von 0,8 bis 2,2 ms ab - da wird der Timer nicht weit über "2" hinauskommen.

Nochwas kleines (nicht ganz so wichtig): Das "Else" muss an seiner Stelle nicht unbedingt sein - Du kannst einfach schreiben

If Bedingung then
Befehl 1
Befehl 2
...
End if

ABER (und das ist wichtig): Hinter jedes "if" muss ein "end if" oder ein "else" kommen!

Die Zeile



If Rc > 70 Then Portb.0 = 0


kann so nichts werden!

Entweder

If Rc > 70 then Portb.0 = 0 ELSE Portb.0 = 1

Oder

If Rc > 70 then
Portb.0 = 0
End if

Diese Variante hätte aber den Nachteil, dass Dein Portb.0 nie mehr wieder auf 1 gesetzt wird :-)

Ich hoffe, das sind erstmal in paar Ansätze zum Nachdenken :-)

MagicWSmoke
20.01.2010, 20:28
Meister Sauerbruch,

ich hab' selten in einem Forum eine Post wie Deine gesehen, die inhaltlich so voller Unsinn ist. Wie soll da jemand, der sich noch nicht so auskennt daraus lernen ?


Im Auslieferungszustand sind die Fusebits beim Tiny12 so gesetzt, dass er seinen Takt über einen externen Quarz generiert.

Datenblatt Tiny12:

...for which combination of CKSEL3..0 to use. Default value is “0010”, internal RC oscillator with long start-up time.



Viel schlimmer ist aber, dass der Tiny12 gar kein RAM, sondern nur ein EEPROM hat. Das lässt sich ca. 100.000 mal beschreiben, und dann war´s das. Und 100.000 Zyklen sind schnell zusammen - bei ener Signalfrequenz von 50Hz (üblich bei RC-Signalen) in unter 1 Stunde...
Ich würde mir an Deiner Stelle für diese Anwendung unbedingt einen Controller holen, der zumindestens ein paar lausige Bytes RAM-Speicher hat.

Der TE verwendet im Code IRam, das ist ein Prozessorregister als Variable deklariert, da wird nicht das EEProm beschrieben.



...da wird der Timer nicht weit über "2" hinauskommen.
Die einzig korrekte Aussage. Gratuliere.



Die Zeile

If Rc > 70 Then Portb.0 = 0

kann so nichts werden!

Aber klar wird die was, die macht genau das Gleiche wie:

If Rc > 70 then
Portb.0 = 0
End if

In Bascom ist es zulässig eine If Anweisung ohne End If zu schreiben, allerdings kann nur eine Anweisung nach Then folgen und die Anweisung muss sich in einer Zeile mit If befinden.

@Ronny81,

der Tiny12 läuft mit 1.200.000Hz, da nirgends ein Wait verwendet wird, ist das nicht weiter problematisch daß Dein $crystal nicht stimmt, nur zum Berechnen des Timerwertes solltest Du mit der richtigen Taktfrequenz rechnen.

Sauerbruch
20.01.2010, 21:22
MagicWSmoke,

was die fusebits betrifft, habe ich mich seit eh und je auf den engbedded-fusebit-calculator verlassen (http://www.engbedded.com/fusecalc/). Komisch kam mir das mit dem externen Quarz auch vor - aber es steht dort definitiv so unter "default settings". Inzwischen habe aber auch ich die Seite 25 im Datenblatt entdeckt...

Auch wenn ich jetzt weiß was ein Iram Byte ist (*freu...) bleibt mir weiterhin unklar, weshalb Bascom (1.11.8.8. als Vollversion) bei mir jedes mal meckert, wenn ich ein "if" ohne "else" oder "end if" verwende. Und zwar in JEDER Art und Weise.

Aber solche Rätsel können ja durchaus das Salz in der Suppe sein... ich werde dranbleiben!

In diesem Sinne vielen Dank für Deine Zeilen!!

MagicWSmoke
20.01.2010, 21:33
Sauerbruch,


bleibt mir weiterhin unklar, weshalb Bascom (1.11.8.8. als Vollversion) bei mir jedes mal meckert,


Also mit 1.11.8.8 kann ich nicht testen, meine älteste Version ist 1.11.9.3
Damit und aufwärts bis 1.11.9.8 compiliert folgendes Beispiel ohne Probleme.

$regfile = "m8def.dat"
$crystal = 8000000

Dim A As Byte

A = 50

If A > 40 Then Portb.0 = 0


End


... ich werde dranbleiben!

Dann mal viel Erfolg :cheesy:


Nachtrag:
Hab' noch 'ne 1.11.8.2 gefunden, damit geht das mit If ohne End If genauso.

for_ro
20.01.2010, 22:59
Meister Sauerbruch,
ich hab' selten in einem Forum eine Post wie Deine gesehen, die inhaltlich so voller Unsinn ist.

@MagicWSmoke,
wir sind hier in einem freundlichen Forum, wo die Art deiner Kritik absolut deplatziert ist. Hier geht es - noch - nicht so zu wie im Mikrocontroller Forum oder teilweise auch im Bascom Forum.
Du kannst ja ruhig darauf hinweisen, dass Sauerbruch da etwas falsch verstanden hat. Aber der Ton macht immer noch die Musik und der ist einfach unpassend.


In Bascom ist es zulässig eine If Anweisung ohne End If zu schreiben, allerdings kann nur eine Anweisung nach Then folgen und die Anweisung muss sich in einer Zeile mit If befinden.
Wie du sicherlich weisst, können dort schon mehrere Anweisungen stehen.
Z.B. so

If A > 40 Then Portb.0 = 0 : Portb.1 = 0: PortB.2 = 0
wobei hier nur die erste Anweisung von der Bedingung abhängig ist.
If A > 40 Then : Portb.0 = 0 : Portb.1 = 0: PortB.2 = 0 : End If
mit dieser kleinen Änderung sind alle Anweisungen innerhalb des If-Blocks.

@Sauerbruch,
super, wie ruhig du darauf reagiert hast. So kommt man wieder zum eigentlichen Thema zurück.

MagicWSmoke
20.01.2010, 23:59
for_ro,


wir sind hier in einem freundlichen Forum, wo die Art deiner Kritik absolut deplatziert ist.
Das war noch nicht unfreundlich, unfreundlich hört sich anders an.

Denkst Du nicht, daß es eine eigenartige Einstellung ist, falsche Aussagen eines Mitgliedes zu tolerieren, die Richtigstellung dazu aber zu kritisieren, auch wenn Dir die Form letzterer nicht gefällt ?

Meine Kritik wäre sicher anders ausgefallen, hätte Sauerbruch nicht den Eindruck erweckt, er wüsste was er da schreibt. Bei ~400 Posts setze ich zumindest voraus daß nicht gezielt Fehlinformationen verbreitet werden.
Also würde Deine Priorität im Zweifelsfall auf freundlicher, aber falscher Antwort liegen ? Sollte das wirklich der Fall sein, dann möchte ich natürlich nicht weiter beim gemütlichen Beisammensein stören.


Wie du sicherlich weisst, können dort schon mehrere Anweisungen stehen.
Z.B. so
Ja, ist aber gefährlich, wenn Du das so einem Neuling zeigen würdest, könntest Du davon ausgehen, daß es falsch interpretiert wird. Wüsste ich es nicht besser, würde ich auch annehmen, daß alles was danach kommt, Teil der Bedingung ist.


If A > 40 Then Portb.0 = 0 : Portb.1 = 0: PortB.2 = 0

wobei hier nur die erste Anweisung von der Bedingung abhängig ist.
Das bringt nur Probleme mit der Lesbarkeit, würde ich auf alle Fälle vermeiden. If mit Anweisung in einer Zeile würde ich nur verwenden, wenn die Bedingung sicher funktioniert und ich den Code kürzen möchte.

MagicWSmoke
21.01.2010, 00:12
Sauerbruch,

wie bereits geschrieben, hat mich die Bestimmtheit Deiner falschen Aussagen dazu animiert meine Post so zu verfassen, wie ich's tat.

Auch ich hab' natürlich schon Schmarrn geschrieben, bemüh' mich aber es dann nicht als sicher gegeben darzustellen, wenn ich's nicht auch sicher weis.
Meine Post war als Kritik gegen Deine Aussagen gedacht, das war natürlich keine Kritik an Deiner Person, ich denke Du hast es auch nicht so aufgefasst.

Ich freue mich, wenn es Dir einen Nutzen gebracht hat. Du scheinst mir ein Netter zu sein, da hätt' ich gern ein klein wenig die Schärfe raus genommen.

Ludwig

Ronny81
21.01.2010, 12:17
Hallo,

danke erstmal für eure Tips.
Leider bekomme ich für den Timer0 immer noch keinen Wert zurück.
Bitwait und so fuktioniert. Es muss am Timer liegen, denn der hat immer
den Wert 0, egal welchen Prescale benutze.

Muss ich vielleicht noch einen Pin der MCs auf GND oder VCC legen?

Ich habe mom nur RST mit 10kOhm auf VCC gelegt und Betriebsspannung
angelegt.



$regfile = "attiny12.dat" ' Controller = ATtiny12
$crystal = 1200000 ' Takt 1,2MHz
$noramclear ' RAM nicht initialisieren
$tiny ' Stack nicht initialisieren
'$hwstack = 32 ' Stackinitialisierung wird durch $TINY unterdrückt
$swstack = 0 ' Software 0
$framesize = 0 ' Framesize = 0

'################################################# ################################################## ##############################
'#
'# Hardware initialisieren
'#
'################################################# ################################################## ##############################

Config Timer0 = Timer , Prescale = 64 'Timer0 geht gut

Config Portb.0 = Output
Config Pinb.4 = Input
Portb.0 = 1

'################################################# ################################################## ##############################
'#
'# Variablen
'#
'################################################# ################################################## ##############################

Dim Rc As Iram Byte ' Variablen als IRAM definieren

'################################################# ################################################## ##############################
'#
'# Hauptprogramm
'#
'################################################# ################################################## ##############################

Do


'Geberweg des Senders Minimum = 65 / Maximum = 110 / Mitte = 87

If Pinb.4 = 0 Then
Bitwait Pinb.4 , Set 'Auf positive Flanke warten
Timer0 = 1 'Zaehler starten
Bitwait Pinb.4 , Reset 'Auf negative Flanke warten
Rc = Timer0
Else
End If

If Rc > 1 Then Portb.0 = 0

Loop

MagicWSmoke
21.01.2010, 12:26
Welche Bascom Version hast Du ?

Bei den älteren Versionen musste man den Timer noch mit

Start Timer0
starten, die neueren Versionen machen das automatisch beim Config.


Ich habe mom nur RST mit 10kOhm auf VCC gelegt und Betriebsspannung angelegt.

Das reicht, evtl. noch den obligatorischen 100nF Kondensator von VCC nach GND direkt am µC. Lass doch erstmal 'ne Led blinken, damit Du siehst, ob sonst alles passt.

Sauerbruch
21.01.2010, 12:30
Es muss am Timer liegen, denn der hat immer
den Wert 0

Bist Du Dir da sicher bzw. woran machst Du das fest?

Ronny81
21.01.2010, 12:39
Ich habe die Version 1.11.9.5

Ich habe den gleichen Satz ja schon auf einem Attiny24 laufen und da gehts
top. Darum verstehe ich das auch nicht.
Ja und den 100nF hab ich drin.
Das mit der LED hab ich schon versucht, das geht. Also laufen tut er.

Und woran ich festmachen, dass der Timer 0 zurückgibt, wenn ich


If Rc = 0 Then Portb.0 = 0

schreibe, dann geht Portb.0 auf low.
Also kommt aus den Timer nicht mal 1 oder 2 raus :-(

MagicWSmoke
21.01.2010, 12:51
If Rc = 0 Then Portb.0 = 0 schreibe, dann geht Portb.0 auf low. Also kommt aus den Timer nicht mal 1 oder 2 raus

Wenn der PinB.4 beim Start 1 ist, dann ist Rc beim ersten Durchlauf noch 0 (so schnell ist der Timer nicht), damit wird PortB.0 auf 0 gesetzt und das war's dann, denn auf 1 geht er laut Deinem Code nicht mehr.

Probier mal folgendes:


$regfile = "attiny12.dat" ' Controller = ATtiny12
$crystal = 1200000 ' Takt 1MHz
$noramclear ' RAM nicht initialisieren
$tiny ' Stack nicht initialisieren
'$hwstack = 32 ' Stackinitialisierung wird durch $TINY unterdrückt
$swstack = 0 ' Software 0
$framesize = 0 ' Framesize = 0

'################################################# ################################################## ##############################
'#
'# Hardware initialisieren
'#
'################################################# ################################################## ##############################

Config Timer0 = Timer , Prescale = 64 ' 1,5mS x (1200000Hz / 64) = Schwellwert 28

Config Portb.0 = Output
Config Pinb.4 = Input
Portb.0 = 1

'################################################# ################################################## ##############################
'#
'# Variablen
'#
'################################################# ################################################## ##############################

Dim Rc As Iram Byte ' Variablen als IRAM definieren

'################################################# ################################################## ##############################
'#
'# Hauptprogramm
'#
'################################################# ################################################## ##############################

Do

'Geberweg des Senders Minimum = 65 / Maximum = 110 / Mitte = 87

If Pinb.4 = 0 Then
Bitwait Pinb.4 , Set 'Auf positive Flanke warten
Timer0 = 1 'Zaehler starten
Bitwait Pinb.4 , Reset 'Auf negative Flanke warten
Rc = Timer0
End If

If Rc > 20 Then
Portb.0 = 0
Else
Portb.0 = 1
End If

Loop

Ronny81
21.01.2010, 13:00
Leider ändert das nichts :-(
Ich muss immer noch Rc = 0 setzen, damit die LED angeht



If Rc = 0 Then
Portb.0 = 0
Else
Portb.0 = 1
End If


Ich verstehe das nicht mehr. In meinem Attiny24 läufts super

MagicWSmoke
21.01.2010, 14:07
Mit 1.11.9.5 compiliert, im AVR Studio getestet und im Maschinencode schrittweise durchgegangen, der Code arbeitet einwandfrei.

Prüf, ob die Portpins wie gewünscht arbeiten:

Do
If Pinb.4 = 0 Then
Portb.0 = 0
Else
Portb.0 = 1
End If
Loop

und teste den Timer:

Do
If Timer0 > 128 Then
Portb.0 = 0
Else
Portb.0 = 1
End If
Loop

Mit Prescaler 64 muss eine angeschlossene Led dunkler leuchten. Für ein erkennbares Blinken den Prescaler auf 1024 erhöhen, dann sollte ein Blinken mit 4,5Hz zu erkennen sein.

Ausgang der Fernsteuerung korrekt mit Pin 3 des Tiny12 verbunden und positiver Impuls vorhanden ? Evtl. anderen Eingangspin nehmen.