1

Freitag, 27. März 2009, 18:46

Frage zu kleinem LED-Programm - bitte mal draufschauen!

Hallo Leute,
bin nicht so bewandert im Programmieren, und Atmels sind ja schön und klein und alles, aber mein AVR Bascom simuliert das hier nicht. Da klappern nur die Register..... Frage mache ich was falsch fehlt was oder warum zuckt das hier nicht?
Es sollen drei Leds in versch. Rhytmus aufleuchten, die eine im Sek-Takt, die andere im Beacon-Rhythmus, die dritte im 1/2 sec. Takt.

Vielen Dank für jeden Hinweis!
Schöne Grüße, mrmiffy

Listing:

'------------------------------------------------------------------------------
'name : Bascom_LED_Steuerung.bas
'copyright : (c) 1995-2005, MCS Electronics
'purpose : Usage of simulator & bascom
'micro : ATTiny 15
'suited for demo : yes
'commercial addon needed : no
'------------------------------------------------------------------------------
$regfile = "attiny15.dat"
$framesize = 50
$swstack = 8
$hwstack = 32
$crystal = 1000000 '1MHz interne Timer Frequenz ist gesetzt

Config Portb.0 = Output
Config Portb.1 = Output
Config Portb.2 = Output


Do
Portb.0 = 1 'Pin wird auf High, also 5V geschaltet
Waitms 1000 'Dauer des Leuchtens von LED A = 1 sec
Portb.0 = 0 'Pin wird auf Low, also 0V geschaltet
Waitms 1000 'Dauer der Dunkel-Pause von LED A =1 sec.
Loop

Do
Waitms 300 'kurzer Zeit-Versatz, die LEds sollen unterschiedlich starten
Portb.1 = 1 'Pin wird auf High, also 5V geschaltet
Waitms 100
Portb.1 = 0 'Pin wird auf Low, also 0V geschaltet
Waitms 100

Portb.1 = 1 'Pin wird auf High, also 5V geschaltet
Waitms 100
Portb.1 = 0 'Pin wird auf Low, also 0V geschaltet
Waitms 100

Portb.1 = 1 'Pin wird auf High, also 5V geschaltet
Waitms 100
Portb.1 = 0 'Pin wird auf Low, also 0V geschaltet

Waitms 1000
Loop

Do 'Hier wird Led 3 gestartet, anderer Blinkrhythmus
Portb.2 = 1 'Pin wird auf High, also 5V geschaltet
Waitms 500 'Dauer des Leuchtens von LED A = 0,5sec
Portb.2 = 0 'Pin wird auf Low, also 0V geschaltet
Waitms 500 'Dauer der Dunkel-Pause von LED A = 0,5 sec.
Loop


End
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)

2

Freitag, 27. März 2009, 19:58

Du hast bereits in der ersten 'Do...loop' Schleife keine Abbruchbedingung, also kommt er aus dieser Schleife gar nicht mehr heraus. Hättest du eine Abbruchbedingung dann würde er statt dessen in der zweiten Schleife hängen bleiben da auch hier die Abbruchbedingung fehlt. Usw. usw...
Aber selbst wenn du die Abbruchbedingungen hättest bzw. alles in eine Schleife packen würdest käme nicht das gewünschte Ergebnis dabei heraus. Nach jedem 'Waitms' geht der AVR erstmal Kaffee trinken und macht dann mit dem nächsten Befehl weiter.
Also:
LED1 an
1Sek Kaffee
Led1 aus
1Sek Kaffee

300ms Espresso

100ms Kaffee
Led2 ein
100ms Kaffee
Led2 aus
100ms Kaffee
Led2 ein
100ms Kaffee
Led2 aus

100ms Kaffee
Led2 ein
100ms Kaffee
Led2 aus
.
.
.

Fällt dir etwas auf? Die LEDs können niemals gleichzeitig blinken da die Intervalle nacheinander abgefertigt werden.
Du könntest das mit einem Timerinterrupt erledigen der alle X ms ausgelöst wird.
Innerhalb der Interruptroutine inkrementierst du Zähler und abhängig von deren Wert löst du eine Aktion aus. Nach dieser Aktion aber das Rücksetzen der Zählerwerte nicht vergessen.

Beispiel: Eine LED soll im Sekundentakt blinken, eine zweite im 3-Sekundentakt.
Der Timerinterrupt wird jede Sekunde angesprungen.

LED_irq:
toggle portb.0 'bei jedem Interrupt - also jede Sekunde - wird die LED umgeschaltet
inkr Zaehler
if Zaehler = 3 then
toggle portb.1 'bei Zählerstand 3 - also nach 3Sek - wird LED2 umgeschaltet
Zaehler = 0 'Schleife neu starten wenn Endwert erreicht war
end if
Return
Schöne Grüsse
Toenne

3

Freitag, 27. März 2009, 20:48

Hallo Toenne,

vielen Dank für die schnelle Antwort!
Ja siehste, so schlau bin ich nicht im Metier Programmieren.
Ich hätte gedacht, er arbeitet das einfach nacheinander ab und zwar so lange bis er keinen Vcc mehr hat. Dass er ne Abbruchbedingung braucht um weiter zu gehen war mir nicht klar. Schade dass einem der Compiler das nicht meldet, das wär ja der geeignete Ort für Fehlermeldungen...

Ich baue Deinen Vorschlag mal ein und schaue was passiert. Evtl. frag ich dann noch mal nach.

Danke und schöne Grüße!

MrMiffy
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)

4

Freitag, 27. März 2009, 23:50

Das hast du falsch verstanden, er braucht keine Abbruchbedingung um weiterzumachen sondern eine Abbruchbedingung um die erste Do...Loop Schleife zu verlassen, die zweite wird er sonst nämlich nie ausführen. Ist keine SPS die das automatisch macht ;). Wenn du dann aber die letzte Do...Loop Schleife auch irgendwann abbrichst dann bleibt er tatsächlich einfach stehen, eine übergeordnete Schleife brauchst du also auf jeden Fall wenn er permanent laufen soll.
Und wenn irgendwo 'Waitms' steht dann wartet er auch und arbeitet nicht etwa derweil die anderen Zeilen ab, deswegen funktioniert deine serielle Abarbeitung nicht wenn du eigentlich die LEDs parallel ansteuern willst.
Die Timerinterrupts sind nicht grundsätzlich notwendig, du könntest das auch komplett über einen Zähler erledigen.

Do
Inkr Zaehler
if Zaehler = 10 then portb.0 = 1
if Zaehler = 20 then portb.0 = 0
if Zaehler = 30 then portb.0 = 1
if Zaehler = 40 then portb.0 = 0

if Zahler = 5 then portb.1 = 1
if Zahler = 10 then portb.1 = 0
if Zahler = 15 then portb.1 = 1
if Zahler = 20 then portb.1 = 0
if Zahler = 25 then portb.1 = 1
if Zahler = 30 then portb.1 = 0
if Zahler = 35 then portb.1 = 1
if Zahler = 40 then portb.1 = 0

if Zaehler = 40 then Zaehler = 0
Loop

Zwei Probleme gibt es dabei nur:
1. Der AVR ist so schnell dass du mehrere Schleifen schachteln müsstest damit überhaupt optisch wahrnehmbare Blinkfrequenzen entstehen würden oder aber mit astronomischen Zählerwerten arbeiten.
2. Die genauen Werte müsstest du experimentell ermitteln um Blinkintervalle einer bestimmten Grösse zu erhalten, die Zeit ist ja davon abhängig wie lange er für so einen Durchlauf braucht.
Beim Timer ist das einfacher, der lässt sich genau berechnen und Ausgänge oder auch Variablen mit weniger Zeilen toggeln.

Den obigen Code kannst du jetzt aber nicht einfach in Bascom kopieren und laufen lassen, du musst den Timer erst konfigurieren und ihm seine Einsprungmarke mitteilen. Dazu am besten mal bei den Beispielprogrammen das Timerbeispiel anschauen.
Schöne Grüsse
Toenne

5

Samstag, 28. März 2009, 13:01

Hallo Toenne, danke für die Hinweise!

Das mit Zähler oder Timer hab ich jetzt verstanden. Frage: Kann ich denn mit einem Timer auch ungleichmäßige Rhythmen programmieren? Für das Beacon ist z.B. 3x kurz Blinken, ca 100-200ms, dann Pause 1sec. notwendig. Da schau ich nicht durch...
Und gleichzeitig sollen eben unabhängig davon die anderen Blinker-LEDs blinken.

Mit der Timerprogrammierung scheint mir das auch am komfortabelsten zu sein. ich denke ja einfach wie du siehst...

Ich wurschtel mal heute weiter rum und wenn ich scheitere melde ich mich wieder!

Danke für die Hilfe!

Gruß MrMIffy
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)

6

Samstag, 28. März 2009, 14:19

Im Prinzip geht es am einfachsten wie oben beschrieben. Zunächst ermittelst du eine geeignete Timerbasis, z.B. 100ms. Dann das längste Zeitintervall welches deinen Zählerendwert definiert. Und dann zählst du in der Timerroutine einfach hoch.

Timer_irq:
inkr Zaehler

if Zaehler = 1 then portb.0 = 1 'LED an
if Zaehler = 2 then portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
if Zaehler = 3 then portb.0 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
if Zaehler = 4 then portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
if Zaehler = 5 then portb.0 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
if Zaehler = 6 then portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus

'Die LED hat nun 3x geblinkt, jetzt passiert erstmal nix mehr bis der Zaehlerendwert erreicht ist

if Zaehler = 10 then Zaehler = 0 'Obiges Spiel geht nach 10x100ms = 1Sek von vorne los

Return


Lässt sich sicher eleganter lösen, so ist es aber erstmal einigermassen verständlich hoffe ich. Du musst nur aufpassen dass die IRQ-Routine nicht zu lang wird da sonst schon der nächste Interrupt ansteht bevor der erste überhaupt komplett abgearbeitet wurde. Bei z.B. 100ms passt aber schon ein bisschen was rein ;).
Weitere LEDs könntest du entweder in obiger Schleife gleich mitverarzten oder über einen weiteren Timerinterrupt, der Mega8 hat ja zwei.
Schöne Grüsse
Toenne

7

Montag, 30. März 2009, 18:06

Hallo Toenne,

ich hab jetzt mal versuchsweise Deinen Vorschlag in Form gebracht, aber noch Fragen dazu:

$regfile = "m8def.dat" ' Prozessortyp ATmega32
$crystal = 1000000 ' Taktrate
$hwstack = 32
$swstack = 10
$framesize = 40
$baud = 4800

Config Timer0 = Timer , Prescale = 256
On Timer0 T0_isr

'Timer-Freigabe
Enable Timer0

'Freigabe der Interrupt-Routinen
Enable Interrupts


Config Portb.0 = Output
'Config Portb.2 = Output für die Erweiterung gedacht....
'Led2 Alias Portb.2
'Config Portb.3 = Output
'Led3 Alias Portb.3

Dim Zaehler As Integer

T0_isr:
If Zaehler = 1 Then Portb.0 = 1 'LED an
If Zaehler = 2 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler = 3 Then Portb.0 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler = 4 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler = 5 Then Portb.0 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler = 6 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus

'Die LED hat nun 3x geblinkt, jetzt passiert erstmal nix mehr bis der Zaehlerendwert erreicht ist

If Zaehler = 10 Then Zaehler = 0 'Obiges Spiel geht nach 10x100ms = 1Sek von vorne los

Return


Also: stimmt meine Deklaration von Zaehler als integer? Oder soll das ein WORD sein?
Dann das Timerproblem: Ich gehe von 1 MHz aus, aber kann ich denn durch andere Def. den Systemtakt in weiten Grenzen bestimmen ( $crystal = 1000)?
Das würde einiges vereinfachen. Wenn nicht, folgendes Prob:
Ich will ja eigentlich den Tiny15 benutzen, da 8pin und schön klein. Der hat einen Systemtakt von 1,6 MHz und nur zwei Timer mit 8 bit. D.h. da kann ich max. mit 256 prescalen. Wie komm ich denn da auf meine 0,1 sec? Muss ich da nicht noch einen Zähler vorab laufen lassen oder wie löst man das?

Dann: Mit dem obigen Code geht zwar alles durch den Syntax-Check/Compiler, aber im Simulator wird einfach nichts angezeigt. Ich vermute das liegt am hohen Takt, oder was ist da falsch?
Danke für weiter Tips!

Grüße, MrMiffy
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)

8

Montag, 30. März 2009, 18:18

Zitat

Muss ich da nicht noch einen Zähler vorab laufen lassen oder wie löst man das?

Genau, auf die Art kannst du einen eigenen Prescaler definieren:

T0_isr:
inkr Teiler
if Teiler = 10 then
...hier dann deine IF-THEN Abfragen
Teiler = 0
end if
return

Deine Routinen würden in den Beispiel nur in jedem 10. Durchlauf abgearbeitet.

Zitat

Mit dem obigen Code geht zwar alles durch den Syntax-Check/Compiler, aber im Simulator wird einfach nichts angezeigt.

Der Simulator zeigt bei mir prinzipiell nichts an...habe mich aber auch noch nicht weiter damit beschäftigt wie man den richtig verwendet. :dumm:

Aber ganz nebenbei: Du enabelst deinen Timer und die Interrupts zwar, startest den Timer aber nicht.
So funktioniert es wahrscheinlich besser:

Config Timer0 = Timer , Prescale = 256
On Timer0 T0_isr
Enable Timer0
Start Timer0
Schöne Grüsse
Toenne

9

Montag, 30. März 2009, 22:41

Hi Toelle,

ich hab meinen Code mal mit deinen Änderungen gefüttert, und jetzt sieht er so aus:

$regfile = "m8def.dat" ' Prozessortyp ATmega8
$crystal = 800000 ' Taktrate
$hwstack = 32
$swstack = 10
$framesize = 40
$baud = 4800

Config Timer0 = Timer , Prescale = 256
On Timer0 T0_isr

'Timer-Freigabe
Enable Timer0

'Freigabe der Interrupt-Routinen
Enable Interrupts
Start Timer0


Dim Teiler As Integer
Dim Zaehler As Integer

Config Portb.0 = Output
'Config Portb.2 = Output für die Erweiterung gedacht....
'Led2 Alias Portb.2
'Config Portb.3 = Output
'Led3 Alias Portb.3

do 'diese Hauptschleife muss ja wohl sein, oder?
loop
end


T0_isr:
'inkr Teiler
If Teiler = 31250 Then 'dann müsste es mit 0,1 sec tickern
'..hier Dann Die If -then Abfragen

'inkr Zaehler - Unterschleife für das LED-Spielchen Beacon an - aus
If Zaehler = 1 Then Portb.0 = 1 'LED an
If Zaehler = 2 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler = 3 Then Portb.0 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler = 4 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler = 5 Then Portb.0 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler = 6 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus

'Die LED hat nun 3x geblinkt, jetzt passiert erstmal nix mehr bis der Zaehlerendwert erreicht ist
Teiler = 0
If Zaehler = 10 Then Zaehler = 0 'Obiges Spiel geht nach 10x100ms = 1Sek von vorne los

end if
return


Da tickern jetzt die Register aber ich durchschaue natürlich mangels Simulator nicht, was sich da wirklich an den Outputs tut. Ich hab mir schon den Oshon Soft AVR Simulator geladen, AVR Simulator IDE - Evaluation Copy v1.32 - da tickern auch div. Register, aber auf den LEDs tut sich nichts. Das bedeutet wohl, ich muss einmal reinbrennen und auf dem Eva-Board gucken was da zuckt?
Gibt es andere, zuverlässige Sim-Soft, mit der man vorab was sehen kann?

Und, bitte noch mal einen Blick auf meine Zeilen da oben - schon mal wieder Dank dafür!

MrMiffy
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)

10

Montag, 30. März 2009, 23:55

Was sollen Zeilen wie...

'Led2 Alias Portb.2
'Config Portb.3 = Output
'Led3 Alias Portb.3

...oder...

'inkr Teiler

...bezwecken? Das Hochkomma davor sorgt dafür dass dies nicht als Programmcode sondern als Kommentar angesehen wird, das wird also gar nicht kompiliert ;).

Ferner hat dein Timer keinen Preset, ist das Absicht dass er immer von 0 bis 65535 laufen soll?
Und die 800kHz Taktfrequenz sind auch kein Schreibfehler? In den Fuses gibt es keine derartige Einstellung, keine Ahnung wie sich das auswirkt.
OK, einfach mal fix nachgerechnet:
800000Hz / 256 = 3125 Einsprünge in die Timerroutine pro Sekunde. 31250 Schleifen geteilt durch die 3125 Einsprünge ergeben 10 Aktionen pro Sekunde...also genau das was du willst. Theoretisch zumindest, ich glaube nicht dass er die 0.8MHz schluckt.
Lieber 4MHz und noch eine 5er Schleife drüberstülpen, dann kannst du die Fuses korrekt einstellen.

Ach ja, wie kommst du darauf dass der Tiny15 nur einen Prescaler von 256 hat, steht das im Datenblatt? Der Prescaler hat nämlich mit der Bitbreite des Zählers nichts zu tun, die definiert nur wie weit der Timer zählen kann: 8Bit -> 0..255, 16Bit -> 0..65535. Meines Wissens nach kann der auch beim Tiny15 mit 1024 beaufschlagt werden so dass du mit Prescaler = 1024 und Timerpreset 158 direkt deine gewünschten 10Hz = 10 Einsprünge pro Sekunde erhälst.
Also...

Zitat

Config Timer0 = Timer , Prescale = 1024
On Timer0 T0_isr
Timer = 158
.
.
.
T0_isr:
Timer = 158
.
.
.
Return

Einfach mal ausprobieren, da du ja die entsprechende LIB einbinden musst könnte ich mir vorstellen dass Bascoam ggf. meckert falls dieser Prescaler nicht unterstützt wird.

Was die Simulation angeht: Ich habe das eben nochmal mit meiner eigenen Timerroutine die gerade Ärger macht getestet, funktioniert anscheinend schon. Allerdings in Zeitlupe, bis da der Timer einmal runtergezählt hat kannst du getrost 'ne Runde schlafen gehen. Kann so kaum Sinn der Übung sein, irgendwas läuft das schief.
Ich übe aber ohnehin lieber gleich auf einem Steckbrett.
Schöne Grüsse
Toenne

11

Dienstag, 31. März 2009, 15:13

Hallo Toenne,

Zitat

Original von toenne[/i] Was sollen Zeilen wie... 'Led2 Alias Portb.2 'Config Portb.3 = Output 'Led3 Alias Portb.3 ...oder... 'inkr Teiler ...bezwecken? Das Hochkomma davor sorgt dafür dass dies nicht als Programmcode sondern als Kommentar angesehen wird, das wird also gar nicht kompiliert ;).


Ja, das erste ist als Erinnerung gedacht, dass da noch die Erweiterung um die Schleifen für die anderen zwei LEDs ansteht. Und der 'inkr Teiler wurde angemeckert vom Bascom, das habe ich für einen Kommentar von Dir gehalten. Noch mal nachgesehen: inkr hattest Du irgendwo vorgeschlagen, ich bin jetzt erst drauf gestoßen dass es incr heißen muss, damit hier was hochzählt. Inkr wurde natürlich angemeckert, wg. unbekanntes Statement?!? - da hab ich das erst mal weggedingst.


Zitat

Theoretisch zumindest, ich glaube nicht dass er die 0.8MHz schluckt.
Lieber 4MHz und noch eine 5er Schleife drüberstülpen, dann kannst du die Fuses korrekt einstellen.

Ich hab im Datenblatt des Tiny15 gesehen, dass der Systemtakt 0,8-1,6 MHz haben kann/darf - von daher dachte ich das könnte man probieren!? Oder meinst Du das wär riskant, an die untere Grenze zu gehen?


Prescaler:
Du hast wieder recht: Oben im Kopf des Datenblattes steht dass der Tiny15 nur 8bit Timer hat, aber Seiten weiter im Text ist der Prescaler auch bis 1024 erläutert und zugelassen. Und der Prescaler ist ja pre, also vor dem Timer geschaltet, daher muss das ja wohl so gehen.


!

Zitat

Config Timer0 = Timer , Prescale = 1024 On Timer0 T0_isr Timer = 158 . T0_isr: Timer = 158 . Return

Dieses meinst Du jetzt für 0,8 oder für 4 MHz Systemclock? Nein, für 1MHz? da wären es 10/sec,richtig?


Das Steckbrett habe ich auch schon aufgebaut, werde heute abend oder morgen mal brennen und testen...

Danke für diese weiterbringenden Vorschläge Toenne!
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »mrmiffy« (31. März 2009, 15:20)


12

Dienstag, 31. März 2009, 18:29

Oops, das mit dem 'inkr' war tatsächlich ein dummer Schreibfehler, muss natürlich tatsächlich 'incr' geschrieben werden :dumm: .

Zitat

Ich hab im Datenblatt des Tiny15 gesehen, dass der Systemtakt 0,8-1,6 MHz haben kann/darf - von daher dachte ich das könnte man probieren!?

OK, wenn dem so ist dass passt es ja, dann werden auch die Fuses entsprechende Frequenzen darstellen (ich gestehe nicht erst das Datenblatt gesaugt und gelesen zu haben...). Dass du die Fuses einstellen musst und es nicht genügt nur im Code $crystal-irgendwas zu schreiben weisst du ja? In Bascom geht das zum Glück wunderbar komfortabel.

Zitat

Nein, für 1MHz? da wären es 10/sec,richtig?

Jupp, 1MHz.
Schöne Grüsse
Toenne

13

Dienstag, 31. März 2009, 20:32

Hallo Toenne,

so, jetzt hab ich mal meine letzte Version hier hin kopiert, ich hoffe das findet deinen Segen und funktioniert auch.
Jetzt kommt's aber: da gibt es Gemecker vom Bascom, als ich den Chip auf Tiny15 umstelle, er will die Dim Teiler / Zaehler als integer nicht! Kann das wahr sein? Was soll denn so was?


Code:
$regfile = "attiny15.dat" ' Prozessortyp ATtiny15
$crystal = 1000000 ' Taktrate
$hwstack = 32
$swstack = 10
$framesize = 40
$baud = 9600

Config Timer0 = Timer , Prescale = 1024

On Timer0 T0_isr

'Timer-Freigabe
Enable Timer0

'Freigabe der Interrupt-Routinen
Enable Interrupts

Start Timer0
Timer0 = 158

Dim Teiler As Integer 'Hier meckert Bascom - mit Tiny nicht möglich...
Dim Zaehler As Integer 'Hier auch - komische Sache!
Dim Zaehler2 As Integer
Dim Zaehler3 As Integer

Config Portb.0 = Output
Config Portb.1 = Output
Config Portb.2 = Output


Do
Loop
End

T0_isr:

Timer0 = 158
Incr Zaehler
If Zaehler = 1 Then Portb.0 = 1 'LED an
If Zaehler = 2 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler = 3 Then Portb.0 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler = 4 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler = 5 Then Portb.0 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler = 6 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
'Die LED hat nun 3x geblinkt, jetzt passiert erstmal nix mehr bis der Zaehlerendwert erreicht ist
If Zaehler = 10 Then Zaehler = 0 'Obiges Spiel geht nach 10x100ms = 1Sek von vorne los

If Zaehler2 = 1 Then Portb.1 = 1 'zweite LED an
If Zaehler2 = 2 Then Portb.1 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler2 = 3 Then Portb.1 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler2 = 4 Then Zaehler2 = 0

If Zaehler3 = 1 Then Portb.2 = 1 'dritte LED an
If Zaehler3 = 2 Then Portb.2 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler3 = 3 Then Portb.2 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler3 = 4 Then Zaehler3 = 0

Return

Danke wiederum für Deine Hinweise!

Schöne Grüße, MrMiffy
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)

14

Dienstag, 31. März 2009, 22:03

Zitat

Dim Teiler As Integer 'Hier meckert Bascom - mit Tiny nicht möglich...
Dim Zaehler As Integer 'Hier auch - komische Sache!

Keine Ahnung warum, aber 'Teiler' verwendest du im Code doch ohnehin nicht mehr, da brauchst du ihn auch nicht zu deklarieren...
Für Zaehler kannst du ja mal WORD probieren, der Zweck heiligt die Mittel.

Zitat

Dim Zaehler2 As Integer
Dim Zaehler3 As Integer

Diese beide Variablen werden weder voreingestellt (z.B. zu Beginn mit 'Zaehler2 = 0') noch im weiteren Code verändert. Die haben einen Zufallswert und der bleibt dann auch.
Es wäre also sicher nicht verkehrt noch ein...

Zitat

incr Zaehler2
incr Zaehler3

einzufügen, sonst passiert da gar nichts.
Allerdings lässt sich das viel einfacher lösen. Statt...

Zitat

If Zaehler2 = 1 Then Portb.1 = 1 'zweite LED an
If Zaehler2 = 2 Then Portb.1 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler2 = 3 Then Portb.1 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler2 = 4 Then Zaehler2 = 0

If Zaehler3 = 1 Then Portb.2 = 1 'dritte LED an
If Zaehler3 = 2 Then Portb.2 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler3 = 3 Then Portb.2 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler3 = 4 Then Zaehler3 = 0

...schreib einfach...

Zitat


toggle portb2
toggle portb3

...denn die beiden sollen ja offensichtlich einfach stur im 100ms-Rythmus den Status wechseln, das Konstrukt für portb.0 existiert ja nur weil du eine 3sek.Pause drinhaben willst.
Wenn du sicherstellen willst dass beide Leds immer gleichzeitig blinken dann könntest du auch schreiben...

Zitat


toggle portb2
portb3 = portb2

Allerdings wäre es dann einfacher beide LEDs in Reihe auf den gleichen Ausgang zu legen ;).
Übrigens würde das so wie von dir geschrieben ohnehin nicht richtig funktionieren:
Wenn der Zähler 3 ist dann wird der Ausgang geschaltet.
Wenn der Zähler 4 ist wird der Zähler auf Null zurückgesetzt, der Ausgang bleibt aber geschaltet.
Im nächsten Durchgang mit Zähler = 1 wird er nochmal geschaltet, das ganze sähe dann also so aus:
1 (Zähler = 1)
0 (Zähler = 2)
1 (Zähler = 3)
1 (Zähler = 4, danach rücksetzen auf Startwert)
1 (Zähler = 1)
0 (Zähler = 2)
1 (Zähler = 3)
1 (Zähler = 4, danach rücksetzen auf Startwert)
usw...
Oder war das die Blinkfolge wie du sie wolltest?
Schöne Grüsse
Toenne

15

Dienstag, 31. März 2009, 22:43

Hallo Toelle,

verflixt, auch Word wird nicht akzeptiert als Dim für Zaehler! Ich finde darüber aber auch im Datenblatt nichts. Kann doch eigentlich nicht sein, dass so was einfaches nicht mit Tinys zu machen sein sollte...

Hast eine Idee?

Schöne Grüße, MrMIffy
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)

16

Mittwoch, 1. April 2009, 00:46

Dann nimm halt BYTE, möglicherweise kann das Ding tatsächlich nur bis 255 zählen.
Schöne Grüsse
Toenne

17

Mittwoch, 1. April 2009, 15:54

Hallo Toenne,

jetzt wird's aber wirklich komisch: Bascom meckert auch bei Byte und sogar bei Bit - das kommt mir jetzt aber sehr seltsam vor.
Siehe Foto:
[IMG]http://img175.imageshack.us/my.php?image=bascomtiny15fehler2.jpg[/IMG]
Ich hoffe das wird angezeigt!?
Sonst: Fehler-FotoFehler_Foto

kann das sein,das was in dem regfile nicht stimmt?
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »mrmiffy« (1. April 2009, 17:44)


18

Mittwoch, 1. April 2009, 16:29

Hallo Toelle,
ich hab jetzt mal bei Google und im Forum von MCS (Bascom) geforscht und gefunden, dass der Tiny 15 kein Sram hat. Daher solle man die Werte für hwstack, swstack und framesize so klein wie möglich halten (ich hab jetzt 6,0,0 gewählt) und: in der Deklaration für die DIM as "IRam" angeben, also in der Form: Dim Zaehler as IRAM integer.
Damit wird jetzt diese Zeile nicht mehr angemeckert, (uff!) aber:

die beiden Toggles hab ich jetzt in die Hauptprogramm-Schleife gestellt
jetzt wird hier beides angemeckert sowie ein angeblich fehlender Loop in Zeile 0 (!)

Fehler_3

Hast Du dazu eine Idee?

Hier noch mal der kpl. Code:

$regfile = "attiny15.dat" ' Prozessortyp ATtiny15
$crystal = 1000000 ' Taktrate 1MHz
$hwstack = 6
$swstack = 0
$framesize = 0
$baud = 4800

Config Timer0 = Timer , Prescale = 1024 'Timer-Einstellungen
On Timer0 T0_isr 'Einsprung Definition
Enable Timer0 'Timer-Freigabe
Enable Interrupts 'Freigabe der Interrupt-Routinen
Start Timer0 'Timer starten
Timer0 = 158
'Deklarationen für Var, Outputs
Dim Zaehler As Iram Byte
Config Portb.0 = Output
Config Portb.1 = Output 'für die Erweiterung gedacht....
Config Portb.2 = Output

Do
Toggle Portb1
Toggle Portb2
Loop 'Hauptprogramm-Schleife
End


T0_isr: 'Interrupt-Service-Routine
Timer0 = 158
Incr Zaehler
If Zaehler = 1 Then Portb.0 = 1 'LED an
If Zaehler = 2 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler = 3 Then Portb.0 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler = 4 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
If Zaehler = 5 Then Portb.0 = 1 'nach einem weiteren Durchlauf = 100ms LED wieder an
If Zaehler = 6 Then Portb.0 = 0 'nach einem Durchlauf = 100ms LED wieder aus
'Die LED hat nun 3x geblinkt, jetzt passiert erstmal nix mehr bis der Zaehlerendwert erreicht ist
If Zaehler = 10 Then Zaehler = 0 'Obiges Spiel geht nach 10x100ms = 1Sek von vorne los
Return




Vielen Dank für die HIlfe!

Schöne Grüße, MrMiffy

PS: Außerdem wollte ich die beiden "regelmäßigen" Leds unterschiedlich schnell laufen lassen, also werde ich auch hierzu wieder zu Zaehler2/3 und dem längeren Weg usw. zurückgehen. Von daher war Deine Anmerkung natürlich richtig: könnte man beides einfach toggeln. Aber immer eins nach dem anderen....

Und PPS: Toll, dass Du hier so geduldig auf die Sprünge hilfst - man lernt mehr, wenn man nicht alles vorgestrickt bekommt. Aber dass es gleich soo kompliziert wird....
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)

19

Mittwoch, 1. April 2009, 17:57

Du hast den Punkt vergessen, portb1 ist für ihn eine Variable die noch nicht deklariert wurde. Sobald du portb.1 schreibst wirst du auch feststellen dass er es komplett gross schreibt.
Dass er loop anmeckert ist evtl. nur eine Folgeerscheinung da er schon vorher das Compilieren abbricht und deswegen gar nicht dort ankommt, keine Ahnung.
Korrigier erstmal die Ports und schau ob der Fehler bleibt.
Schöne Grüsse
Toenne

20

Mittwoch, 1. April 2009, 19:50

Hallo Toenne,

ok, das hab ich gemacht - danke für den Hinweis! Kleine Ursache große Wirkung - also mit Punkt geht das Ansprechen der beiden Ports jetzt auch.

Nur: Solange ich den Tiny15 nehme, meckert Bascom, dass die Toggle-Befehle nicht ausgeführt werden können weil angebl. der Befehlssatz des Tiny15 nicht macht (?) hä?
Kann denn das sein, das ist doch ein ziemlicher simple-Befehl? Ich dachte auch bisher, der Befehlssatz der Atmels wäre annähernd gleich?

Auf dieser Seite Atmel-Tinys wird übrigens behauptet, man können dem Tiny15 nur mit Assembler kommen...
Aber prinzipiell ginge ja auch der Tiny 13, das hab ich noch nicht probiert. Hat einen Timer weniger, dafür das SRam. ISt aber auch abgekündigt...

Fakt ist aber, wenn ich stattdessen einen attiny2313 dafür nehme, geht alles ohne Gemecker durch. Nur: Der hat 20 Beine, das sind 12 zuviel....

Ich will jetzt noch mal versuchen, das Ganze ohne Toggle nur mit den Zählern hinzu kriegen, weil eigentlich möchte ich bei dem 8-pin Design bleiben (soll für einen meiner Jungs in der Modellbaugruppe in einen Plastikflieger rein, da ist schon so wenig Platz....)

Ich danke weiterhin für Deine Geduld!
Rasant-E Geier Trimmy Thermaris Sagitta Smaragd Salto PB26 Lucky Gazelle Fiesta-SF Libelle Tercel Comet 93T Laser Möwe Grunau Baby III Gillette Eclipse Omega+ Fulmar ASW27E 4m Krause Fulmar II Riser 100 E Kult ASK 8 Flair Mini-Ellipse E+S..... ;)