8051 Ride7 Delay-Funktion

Gast #3814715
Lesenswert?

Ich brauch für ein simples Programm eine ganz einfache Delay-Routine, 
die nicht besonders genau sein soll, sondern einfach ca. X ms 
Verzögerung im Programm hervorrufen soll.
Unten ein kurzes Test-Programm welches einfach im Sekundentakt die LEDs 
an P2 blinken lassen soll.
Leider passiert gar nichts.
Werden die beiden Schleifen einfach wegoptimiert und wenn ja, was kann 
ich dagegen tun?

Ah und der Controller läuft übrigens mit 1Mhz (12Mhz Quarz, Takt wird 
intern aber noch durch 12 geteilt).
1
#include <at89c5131.h>
2
#include <intrins.h>
3

4
void delay_ms(int k)
5
{
6
    int i=1000;  
7

8
    while(--k)
9
    {
10
        while(--i)
11
        {
12
            _nop_();
13
        }
14
        
15
    }
16
}
17

18
int main(void)
19
{ 
20
    while(1)
21
    {
22
        delay_ms(1000);
23
    
24
        P2 = 0xFF;
25
    
26
        delay_ms(1000);
27
    
28
        P2 = 0;
29
    }
30

31
    return 0;
32
}
Gast #3814744
Lesenswert?

1.) volatile ist zwingend notwendig, da ansonsten der Compiler das 
tatsächlich "wegoptimiert" ... (war mal ein Fehler bei meinen 
Auszubildenden)

2.) würdest du mit einem Oszilloskop an den Port 2 gehen würdest du wohl 
höchstwahrscheinlich was sehen. Welche Frequenz hast du dort ?
Gast #3814786
Lesenswert?

Oszilloskop hab ich keins zur Verfügung.
Hier mal das Listing. Also für mich sieht das nicht wirklich nach großer 
Optimierung aus. Die Funktion wird quasi eins zu eins übersetzt.
1
            ; FUNCTION _delay_ms (BEGIN)
2
              ; Register R6R7 is assigned to parameter k
3
              ; R2R3 is assigned to i
4
                                           ; SOURCE LINE # 6 
5
0000 7A03           MOV    R2,#003H
6
0002 7BE8           MOV    R3,#0E8H
7
0004         ?WHILE2:
8
                                           ; SOURCE LINE # 8 
9
0004 EF             MOV    A,R7
10
0005 1F             DEC    R7
11
0006 7001           JNZ    ?LAB3
12
0008 1E             DEC    R6
13
0009         ?LAB3:
14
0009 EE             MOV    A,R6
15
000A 4F             ORL    A,R7
16
000B 600C           JZ     ?NXT2
17
000D         ?WHILE3:
18
                                           ; SOURCE LINE # 10 
19
000D EB             MOV    A,R3
20
000E 1B             DEC    R3
21
000F 7001           JNZ    ?LAB4
22
0011 1A             DEC    R2
23
0012         ?LAB4:
24
0012 EA             MOV    A,R2
25
0013 4B             ORL    A,R3
26
0014 60EE           JZ     ?WHILE2
27
                                           ; SOURCE LINE # 12 
28
0016 00             NOP    
29
0017 80F4           SJMP   ?WHILE3
30
0019         ?NXT2:
31
                                           ; SOURCE LINE # 16 
32
0019 22             RET    
33

34
            ; FUNCTION _delay_ms (END)
Gast #3814806
Lesenswert?

Habs jetzt mal mit For-Schleifen probiert, den Wert von i ein wenig 
variiert und siehe da: es klappt (einigermaßen genau)
1
#include <at89c5131.h>
2
#include <intrins.h>
3

4
sfr at P2 A;
5

6
volatile int i;
7

8
void delay_ms(int k)
9
{
10
    for(k; k>0; k--)
11
    {
12
        for (i = 50; i>0; i--)
13
        {
14
            _nop_();
15
        }
16
        
17
    }
18
}
19

20
int main(void)
21
{ 
22
    A = 0x12;
23

24
    while(1)
25
    {
26
        delay_ms(1000);
27
    
28
        A = 0xFF;
29
    
30
        delay_ms(1000);
31
    
32
        A = 0;
33
    }
34

35
    return 0;
36
}
#3815362
Lesenswert?

jjflash schrieb:
> So ist die beim Eintritt immer 1000 (nehm ich zumindest mal an ... )

Soweit richtig. Aber nach dem ersten Durchlauf durch die innere Schleife 
wird sie nicht wieder mit 1000 initialisiert sondern mit 0, entsprechend 
65000. Deine Sekunde Verzögerung wird also in erster Näherung eine 
Minute sein. Probiere es noch einmal und hab einfach viiiiiieeeeeeel 
Geduld.

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