Forum: Mikrocontroller und Digitale Elektronik Frage zu meinem Blinker


von Andy11 (Gast)


Lesenswert?

die LEDs auf der STK500 leuchten andauernd, aber wieso versteh ich nicht
1
;**********************************Header**************************************
2
;Projektname:
3
;Name des Erstellers:
4
;Zuletzt aktualisiert:
5
;
6
;*****************************Initialisierungen********************************
7
.include "m16def.inc" ;Definitionsdatei des Mega16
8
9
;Stack init***********
10
  ldi r16, High(Ramend)
11
  out SPH, r16
12
13
  ldi r16, Low(Ramend)
14
  out SPL, r16
15
16
;*****************Deklarierete Funktionen und Subroutinen**********************
17
18
;*************************Variablendeklarationen*******************************
19
20
;*****************************Ein-Ausgänge*************************************
21
  ldi r16, 255
22
  out DDRB, r16 ;Portb als Ausgabeport
23
24
  ldi r16, 0
25
  out DDRA, r16 ;Porta als Eingabeport
26
  ldi r16, 255
27
  out PORTA, r16 ;Pullups für Eingagsport A aktivieren
28
29
;*****************************Hauptprogramm************************************
30
Hauptprogramm:
31
  ldi r16, 255
32
  out PORTB, r16
33
34
  call Zwischen
35
36
  ldi r16, 0
37
  out PORTB, r16
38
39
  call Zwischen
40
JMP Hauptprogramm 
41
42
;***********************Unterprogramme/Funktionen******************************
43
Zwischen:
44
  ldi r16, 255
45
46
Warte:
47
  dec r16
48
  cpi r16, 0
49
  brne Warte
50
  ldi r16, 255
51
52
53
Weiter2:
54
  dec r16
55
  cpi r16, 0
56
  brne Weiter2
57
ret

von Axel K. (axel)


Lesenswert?

ähm fehlt da nicht noch ein .ORG xxxx vor der Stackpointer 
initialisierung?

von Flo (Gast)


Lesenswert?

du schaust nicht genau hin ;-)

Die blinken etwa im Kilohertztakt ;-)

von Andy11 (Gast)


Lesenswert?

ja aber wieviele Warte Schleifen muss ich denn jetz noch hingeben
wie dumm ist das, gibt es da keine andere möglichkeit?

von dom (Gast)


Lesenswert?

wie wärs denn mit nem timer???

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:
> ja aber wieviele Warte Schleifen muss ich denn jetz noch hingeben

Mut du ausrechnen :-)

> wie dumm ist das, gibt es da keine andere möglichkeit?

Doch natürlich.
Aber lass dir Zeit. Das lernst du schon noch
(Der Weg führt über Timer)

von Hubert (Gast)


Lesenswert?

Mit welchem Takt betreibst du das STK500? Es kann sein, dass es für das 
Auge schlichtweg zu schnell schaltet. Im AVR-Studio kannst du den Takt 
des STK auf ein paar kHz absenken, dann könnte sich was andern.

Bei 3,7 MHz dauern 255 Takte etwa 0,06ms (1/3700000 * 255 = 6,9*10^-5 s) 
Durch die Sprünge und so weiter wird die Schaltzeit noch etwas länger, 
aber ich denke du bist einfach zu langsam das zu sehen ;-)

Ich hoffe ich habe mich nicht verrechnet (ich bin nich so doll in asm)

von Hubert (Gast)


Lesenswert?

Näh zu langsam!

von Karl H. (kbuchegg)


Lesenswert?

Hubert schrieb:
> Mit welchem Takt betreibst du das STK500? Es kann sein, dass es für das
> Auge schlichtweg zu schnell schaltet. Im AVR-Studio kannst du den Takt
> des STK auf ein paar kHz absenken, dann könnte sich was andern.

Nicht!
Das gibt Ärger beim ISP flashen.

Auch wenn du im Prinzip recht hast ... wenn er das tut jagst du ihn in 
das nächste Problem rein.

von Flo (Gast)


Lesenswert?

Warten entweder über einen mindestens 24-bitigen Zähler oder über einen 
der eingebauten Timer.

Was für einen Prozessortakt verwendest du?

Bei angenommenen 1 MHz (der langsamste intern) dauert deine Warteroutine 
in etwa 256*3 + 256*3 Takte, als ungefähr 1500 us oder 1,5 ms.
Jetzt läuft dein Programm grad so:
Leds an
1,5 ms warten
Leds aus
1,5 ms warten

;;;;;;;

Du kannst dir z.B mit 3 Registern einen 24-bit-Delay bauen, der dann bis 
zu 16 sec verzögert (bei 1 MHz)


;im r16 ist der wert in 16tel Sekunden
;benötigt werden zusätzlich r0 und r1
delay:
  clr r0
  clr r1

delay_loop:
  dec r0
  brne delay_loop
  dec r1
  brne delay_loop
  dec r16
  brne delay_loop
 ret

;hier werden r16  256  256 Takte durchlaufen ;-)

von Flo (Gast)


Lesenswert?

Malpunkte zwischen den letzten Zahlen -.-

von spess53 (Gast)


Lesenswert?

Hi

>ja aber wieviele Warte Schleifen muss ich denn jetz noch hingeben
>wie dumm ist das, gibt es da keine andere möglichkeit?

Für längere Warteschleifen mußt du die verschachteln:
1
       clr r16
2
aaa:   clr r17
3
bbb:   dec r17
4
       brne bbb
5
       dec r16
6
       brne aaa

Für längere Delays muss man u.U. eine dritte Schleife benutzen. Suche 
mal im Netz nach 'avrdelayloop'. Damit kannst solche Delays generieren 
lassen. Etwas fortgeschrittene Programmierer nehmen allerdings einen 
Timer.

MfG Spess

von Hubert (Gast)


Lesenswert?

Das Studio meckert doch wenn der Takt zu langsam ist - Aber so kann man 
sich eine Vorstellung von der Schnelligkeit des AVR machen. Oder ISP 
geschwindigkeit anpassen.

von Karl H. (kbuchegg)


Lesenswert?

Flo schrieb:
> Malpunkte zwischen den letzten Zahlen -.-

Nimm die Leerzeichen raus, dann interpretiert die Fornesoftware das 
nicht mehr als Fettdruck

  r16*256*256

(ICh weiß, das ist lästig. Ich finds auch doof)

von Andy11 (Gast)


Lesenswert?

naja ok timer hört sich schon mal gut an, jedoch habe ich gedacht, dass 
ein timer bis maximal 1 Register zählen kann und das wären ja dann wohl 
wieder die 255
ich möcht jetzt aber auch nicht den Hardwaretimer dazu verwenden, in 
Bascom muss ich das ja auch nicht

aber ich habe keine idee, wie ich so einen "timer realisieren könnte"
gibts da ein paar vorschläge?

von Karl H. (kbuchegg)


Lesenswert?

Hubert schrieb:
> Das Studio meckert doch wenn der Takt zu langsam ist - Aber so kann man
> sich eine Vorstellung von der Schnelligkeit des AVR machen. Oder ISP
> geschwindigkeit anpassen.

Der ISP Takt darf max, 1/4 der µC Frequenz sein. Wenn er Pech hat, kann 
er den µC danach über ISP überhaupt nicht mehr ansprechen, sondern muß 
über High-Voltage Programming gehen. Hatten wir vor kurzen hier im 
Forum. Ein Schlauberger hat die CPU Frequenz soweit runtergedreht, dass 
es keine ISP Einstellung mehr gab, mit der er ihn hätte ansprechen 
können :-)

von Hubert (Gast)


Lesenswert?

Also im AVR Tutorial hatte ich das damals (bevor ich auf C umgestiegen 
bin) verstanden. Und danach: Trial 'n' Error!

von Hubert (Gast)


Lesenswert?

Aber das STK wird doch über die Serielle Schnittstelle angesprochen. Hat 
nix mit ISP zu tun. Und wenns nichtmehr geht den TAkt wieder hochdrehen 
ohne ISP bis ISP wieder geht.

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:
> naja ok timer hört sich schon mal gut an, jedoch habe ich gedacht, dass
> ein timer bis maximal 1 Register zählen kann und das wären ja dann wohl
> wieder die 255

Der Sekundenzeiger deiner Uhr kann auch nur bis 59 zählen, und trotzdem 
kannst du damit Minuten, Stunden, ja sogar Tage stoppen. Wie machst du 
das?

> aber ich habe keine idee, wie ich so einen "timer realisieren könnte"
> gibts da ein paar vorschläge?

Ganz ehrlich:
Auch wenn ich ein großer Verfechter von Timern bin: Du solltest 
verstehen, warum deine kurze Schleife viel zu schnell abgearbeitet wird, 
was du dagegen tun kannst und vor allen Dingen, wie du ausrechnen 
kannst, wie lange ein bestimmtes Code Stück braucht.
Genau das ist nämlich einer der Vorteile von Assembler: Du hast 
Kontrolle über jeden einzelnen Taktzyklus (na ja ... fast)

von Karl H. (kbuchegg)


Lesenswert?

Hubert schrieb:
> Aber das STK wird doch über die Serielle Schnittstelle angesprochen.

Ach?
Wusste gar nicht das das STK den Chip über die serielle Schnittstelle 
programmiert  :-)

von Hubert (Gast)


Lesenswert?

>>Ach?
>>Wusste gar nicht das das STK den Chip über die serielle Schnittstelle
>>programmiert  :-)

Witzig, das hier Moderatoren so nen Mist schreiben. Ich habe nicht 
gesagt das der Chip über die Sreielle Schnittstelle programmiert wird. 
Das STK500 wird über den Comport angesprochen, ob da ein AVR im Sockel 
steckt oder nicht.

von Andy11 (Gast)


Lesenswert?

1
Ganz ehrlich:
2
Auch wenn ich ein großer Verfechter von Timern bin: Du solltest
3
verstehen, warum deine kurze Schleife viel zu schnell abgearbeitet wird,
4
was du dagegen tun kannst und vor allen Dingen, wie du ausrechnen
5
kannst, wie lange ein bestimmtes Code Stück braucht.
6
Genau das ist nämlich einer der Vorteile von Assembler: Du hast
7
Kontrolle über jeden einzelnen Taktzyklus (na ja ... fast)

ich habe wirklich schon viele aufgaben außerhalb assembler gemeistert, 
ich weiß aber echt nich wie ich das mach, mir fehlt einfach der 
Denkansatz
geht jetz der TImer über den alle hier sprechen ganz anders vom coding 
her, oder besteht da ein ähnlichkeit?

von Flo (Gast)


Lesenswert?

ein Timer ist ein nebenläufiger Zähler, der über einen Prescaler 
(Vorteiler) mit einem geringeren Takt versotgt werden kann als der 
Prozessor läuft. Bei bestimmten Ereignissen wie einem Zählwertüberlauf 
(Overflow) oder einem erfolgreichen Vergleich mit einem anderen Wert 
(Compare-Match) kann ein Interrupt ausgelöst werden, also eine 
Programmunterbrechung.
In dieser Unterbrechung kannst du dann z.B. peridische Dinge tun, wie 
eine Zeitvariable hochzählen und ähnliches. Danach wird das 
Hauptprogramm fortgesetzt.

Einfach mal im Tutorial unter Timer schauen, oder im Datenblatt ein 
bisschen Schmökern. ;-)

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:

> ich habe wirklich schon viele aufgaben außerhalb assembler gemeistert,
> ich weiß aber echt nich wie ich das mach, mir fehlt einfach der
> Denkansatz

Es ist ganz einfach.
Überschlagsmässig kannst du davon ausgehen, dass jeder Befehl im AVR 
einen Taktzyklus braucht. Branch Befehle brauchen 2 Takte, wenn die 
Bedinung zutrifft
1
Zwischen:
2
  ldi r16, 255
3
4
Warte:
5
  dec r16                1 Takt
6
  cpi r16, 0             1 Takt
7
  brne Warte             2 Takt

Das heist: Ein Durchlauf durch die Schleife dauert 4 Takte. Durch r16 
machst du 255 Durchläufe durch die Schleife. Macht 255 mal 4 = 1020 
Takte.

Agenommen dein µC läuft mit 1Mhz. WIe lange dauert das dann?
Nun 1Mhz heist, dein µC hat in 1 Sekunde 1 Million Takte zur Verfügung. 
Du brauchst nur 1020. Diese 1020 Takte dauern daher

             1 Mio            1 Sekunde
             1020              x
           -----------------------------
                   1020 * 1
              x = ---------- = 0.00102 Sekunden
                   1000000

Solange dauert es daher, bis dein µC die Schleife 255 mal abgearbeitet 
hat. (Bei einer Taktfrequenz von 1Mhz)

von Andy11 (Gast)


Lesenswert?

1
em geringeren Takt versotgt werden kann als der
2
Prozessor läuft. Bei bestimmten Ereignissen wie einem Zählwertüberlauf
3
(Overflow) oder einem erfolgreichen Vergleich mit einem anderen Wert
4
(Compare-Match) kann ein Interrupt ausgelöst werden, also eine
5
Programmunterbrechung.

in Bascom sag ich aber auch nur

Do

Led an
wait 1

Ledaus
wait1

loop

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:

> in Bascom sag ich aber auch nur

Du musst dich jetzt entscheiden:
Soll dir BASCOM in Zukunft weiterhin alles abnehmen oder willst du 
selber für deine Verfehlungen verantwortlich sein und endlich mal deinem 
µC auf die Beinchen schauen, was der so treibt :-)

Man kann beides tun. So wie man Auto fahren kann, ohne sich um die 
Details des Motors kümmern zu müssen. Aber Autoschrauber wird man nur 
dann, wenn man einen Lötkolben am richtigen Ende anfassen kann und einen 
eine defekte Batterie nicht sofort die Schweißperlen auf die Stirn 
treibt weil man nicht weiß wo man die suchen muss ... und was zum Teufel 
macht die Batterie in meinem Auto und wie sieht die eigentlich aus.

Oder glaubst du, dass BASCOM was anderes macht um 1 Sekunde zu warten 
:-)

von Andy11 (Gast)


Lesenswert?

1
Andy11 schrieb:
2
3
> ich habe wirklich schon viele aufgaben außerhalb assembler gemeistert,
4
> ich weiß aber echt nich wie ich das mach, mir fehlt einfach der
5
> Denkansatz
6
7
Es ist ganz einfach.
8
Überschlagsmässig kannst du davon ausgehen, dass jeder Befehl im AVR
9
einen Taktzyklus braucht. Branch Befehle brauchen 2 Takte, wenn die
10
Bedinung zutrifft
11
12
Das heißt
13
14
Zwischen:
15
  ldi r16, 255
16
17
Warte:
18
  dec r16                1 Takt
19
  cpi r16, 0             1 Takt
20
  brne Warte             2 Takt
21
22
23
Das heist: Ein Durchlauf durch die Schleife dauert 4 Takte. Durch r16
24
machst du 255 Durchläufe durch die Schleife. Macht 255 mal 4 = 1020
25
Takte.
26
27
Agenommen dein µC läuft mit 1Mhz. WIe lange dauert das dann?
28
Nun 1Mhz heist, dein µC hat in 1 Sekunde 1 Million Takte zur Verfügung.
29
Du brauchst nur 1020. Diese 1020 Takte dauern daher
30
31
             1 Mio            1 Sekunde
32
             1020              x
33
           -----------------------------
34
                   1020 * 1
35
              x = ---------- = 0.00102 Sekunden
36
                   1000000
37
38
Solange dauert es daher, bis dein µC die Schleife 255 mal abgearbeitet
39
hat.

ist mir schon klar, es ging mir nur darum es auch vernünftig 
anzuschreiben in assembler

von spess53 (Gast)


Lesenswert?

Hi

>in Bascom sag ich aber auch nur
>Do
>Led an
>wait 1
>
>Ledaus
>wait1
>loop

BASCOM ist wie 'Hotel Mama'.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:

> ist mir schon klar, es ging mir nur darum es auch vernünftig
> anzuschreiben in assembler

Wo liegt jetzt das Problem?
Du willst vielleicht eine Verzögerung von insgesamt 0.2 Sekunden.

0.00102 Sekunden hast du schon. Wenn du daher diese Konstruktion

  0.2 / 0.00102 = 196

mal ausführst, hast du die 0.2 Sekunden

1
Zwischen:
2
3
  ldi r17, 196
4
5
Warte1:
6
  ldi r16, 255
7
8
Warte:
9
  dec r16 
10
  cpi r16, 0
11
  brne Warte
12
13
  dec r17
14
  cpi r17, 0
15
  brne Warte1

OK. stimmt nicht ganz genau, weil natürlich die Bearbeitung von r17 auch 
seine Zeit braucht.

Du brauchst noch längere Zeiten?
Nun du hast noch r18, r19, r20 ..... und du kannst noch genügend viele 
Schleifen immer weiter drumherum bauen.

Wenn man 60 mal 1 Sekunde wartet, hat man in Summe auch 1 Minute 
gewartet :-) Will man 1 Stunde warten, dann wartet man eben 60 Minuten, 
wobei jede einzelne der Warteminuten dadurch entsteht, dass man 60 mal 1 
Sekunde wartet.
Eigentlich ganz einfach und stellt dich im realen Leben vor keinerlei 
Probleme.
BASCOM macht letzten Endes auch nichts anderes. Nur rechnet sich BASCOM 
eben still und heimlich aus, wie oft welche Teile wiederholt werden 
müssen, damit 1 Sekunde Wartezeit entsteht. Jetzt weißt du wie's gemacht 
wird. Vorher hast du dich nicht darum gekümmert :-)

von Andy11 (Gast)


Lesenswert?

1
 
2
3
Zwischen:
4
  ldi r16, 255
5
  ldi r17, 255
6
7
Warte:
8
  dec r16
9
  cpi r16, 0
10
  brne Warte
11
12
  dec r17
13
  cpi r17, 0
14
  brne Warte
15
ret

aber hier habe ich auch 2* (255*4) Taktzyklen und das müsste dann 
2040/1Mio = 2ms lang sein und trotzdem ist der Unterschied deutlich zu 
erkennen

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:

> aber hier habe ich auch 2* (255*4) Taktzyklen und das müsste dann
> 2040/1Mio = 2ms

Moment.
Bis jetzt war alles mehr oder weniger hypothetisch, weil du bisher deine 
Taktrequenz nicht bekant gegeben hast.

Und ausserdem wird der innerste Teil nicht  2*255 mal abgearbeitet, 
sondern 255*255 mal:
Das letzte Codestück zählt r16 von 255 bis 0 runter. Und das r17=255 mal

> lang sein und trotzdem ist der Unterschied deutlich zu
> erkennen

Welcher Unterschied?

von Andy11 (Gast)


Lesenswert?

>Und ausserdem wird der innerste Teil nicht  2*255 mal abgearbeitet,
>sondern 255*255 mal

was wieso jetz=?

ok das hier

//
        dec r16
  cpi r16, 0
  brne Warte

//
kommt zwar beim 2ten Teil auch immer wieder vor aber das sind trotzdem 
nicht 255²

>Welcher Unterschied?
das Blinken

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:

> kommt zwar beim 2ten Teil

welchen 2ten Teil. Die Schleifen sind jetzt ineinander geschachtelt!

Du hast den Code hier
1
Zwischen:
2
  ldi r16, 255
3
  ldi r17, 255
4
5
Warte:
6
  dec r16
7
  cpi r16, 0
8
  brne Warte
9
10
  dec r17
11
  cpi r17, 0
12
  brne Warte
13
ret

Ich markiere dir mal die Schleifen und rücke etwas ein
1
Zwischen:
2
  ldi r16, 255
3
  ldi r17, 255
4
5
Warte:              ; <---+<--+
6
    dec r16         ;     |   |
7
    cpi r16, 0      ;     |   |
8
    brne Warte      ; ----+   |
9
                              |
10
  dec r17           ;         |
11
  cpi r17, 0        ;         |
12
  brne Warte        ; --------+


wenn r17 um 1 runtergezählt wurde und noch nicht bei 0 angelangt ist, 
beginnt r16 erneut von 255 bis wieder 0 runterzuzählen. Daraufhin wird 
r17 wieder um 1 erniedrigt und r16 macht wieder seinen 255-er Drchlauf 
usw. usw. In Summe wird alse r16 insgesammt 255 mal (durch r17) von 255 
auf 0 runtergezählt.  256*256

von Andy11 (Gast)


Lesenswert?

> beginnt r16 erneut von 255 bis wieder 0 runterzuzählen

aber wieso?? der Registerinhalt ist doch schon 0, würde der jetzt weiter 
runterzählen ist die Zahl dann negativ
ich sag ja dem register nicht, dass sein wert wieder 255 ist, oder macht 
er das automatisch wenn er 0 ist, dass er dann sozusagen bei 
über/unterlauf wieder auf der anderen seite beginnt zu zählen--> sprich:
wenn der zähler nicht weiter kann, geht er in den AUsgangszustand

von AVRuser (Gast)


Lesenswert?

Hallo,

Zur Frage: wenn ich ein Register, das Null ist, dekrementiere, gibt es 
einen Unterlauf, und der Wert im Register ist danach 255.

Und noch so am Rande: bei dem Code

>Warte:
>  dec r16
>>  cpi r16, 0
>  brne Warte
>
>  dec r17
>>  cpi r17, 0
>  brne Warte
>ret

kann man sich die Zeile "cpi ... , 0" sparen, da das "dec" das Zero-Flag 
bei Null setzt und daher direkt der Branch ("brne") folgen kann.

von Karl H. (kbuchegg)


Lesenswert?

Andy11 schrieb:
>> beginnt r16 erneut von 255 bis wieder 0 runterzuzählen
>
> aber wieso?? der Registerinhalt ist doch schon 0, würde der jetzt weiter
> runterzählen ist die Zahl dann negativ

der kann nicht negativ werden. Auf dieser Ebene gibt es so erst mal kein 
Vorzeichen. Nach 0 kommt wieder 255.

> ich sag ja dem register nicht, dass sein wert wieder 255 ist

nein.
aber wenn r16 0 ist und du machst einen dec drauf, dann ist r16 danach 
255

Genauso umgekehrt 255 + 1 -> 0

so schlecht war das mit der Uhr da weiter oben gar nicht :-) Nach 59 
kommt 0. Das geht immer so rundum.

von spess53 (Gast)


Lesenswert?

Hi

>aber wieso?? der Registerinhalt ist doch schon 0, würde der jetzt weiter
>runterzählen ist die Zahl dann negativ.

Nein. du fängst wieder mit $FF an.

MfG Spess

von Andy11 (Gast)


Lesenswert?

Riesiges Dankeschön an alle hier, hier kriegt man ja schneller antworten 
als im Bascom forum :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.