Frage zu meinem Blinker

Gast #1656024
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
Gast #1656043
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)
#1656046
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.
Gast #1656047
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 ;-)
Gast #1656051
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
Gast #1656055
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?
#1656058
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 :-)
#1656064
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)
Gast #1656071
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.
Gast #1656072
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?
Gast #1656082
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. ;-)
#1656091
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)
Gast #1656093
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
#1656100
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 
:-)
Gast #1656105
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
#1656117
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 :-)
Gast #1656141
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
#1656150
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?
Gast #1656155
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
#1656162
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
Gast #1656175
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
Gast #1656189
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.
#1656193
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren