Zeitschleife 10sek für 16MHz Quarz in Assembler

#3894125
Lesenswert?

Ich hoffe, dass ihr mir helfen könnt, ich versuche ein Zeitschleife zu 
programmieren, aber kann dies leider nicht so richtig schreiben. Da so 
wie ich es bisher mir angesehen habe muss ich eine mehrfach 
verschachtelte Zeitschleife schreiben, komm aber mit dem richtigen 
aufbaue der Verschachtelung nicht klar. Ich hoffe, dass mir jemand hier 
im Forum dabei helfen kann.
Vielen Dank im Vorraus.
(Firma: Vescomp) #3894347
Lesenswert?

Sven Radola schrieb:
> aufbaue der Verschachtelung nicht klar. Ich hoffe, dass mir jemand hier
> im Forum dabei helfen kann.
> Vielen Dank im Vorraus.

 Probiere es mal hiermit:
1
main:
2
           ldi    r16, 10                   ;* 10 Sec
3
           rcall  WaitSec
4

5
           ldi    r16, 150                  ;* 150 mSec
6
           rcall  Waitms
7

8
eth_loop:  rjmp   eth_loop
9

10
;******************* Sec Routine  *****************
11
;** Gewunschte Zeit (in Sec.) beim Aufruf in r16 **
12
;**************************************************
13
WaitSec:   mov    r15, r16                 ;* r16 wird auch in Waitms benutzt, umladen
14
WtSec0:    ldi    r19, 0x04                ;* Waitms wird 4 Mal aufgerufen
15
WtSec1:    ldi    r16, 0xFA                ;* Mit jeweils 250 mSec
16
           rcall  Waitms
17
           dec    r19
18
           brne   WtSec1
19
           dec    r15
20
           brne   WtSec0
21
           ret
22
                                                                                      
23
;******************* mSec Routine  *****************
24
;** Gewunschte Zeit (in mSec.) beim Aufruf in r16 **
25
;***************************************************
26
Waitms:    ldi    r17, 0x14
27
Wtms0:     ldi    r18, 0xC6              ;* Dieser Wert wird bei anderen Freq. geandert
28
Wtms1:     dec    r18
29
           nop                           ;* Und mit NOP kannst du die Zeit fein verandern
30
           brne   Wtms1
31
           dec    r17
32
           brne   Wtms0
33
           dec    r16
34
           brne   Waitms
35
           ret

 Für 16MHz eingestellt.
 Es werden Register r15-r19 benutzt.

 Natürlich kannst du die Routine Waitms unabhängig von der
 Routine WaitSec benutzen.
 Beim Eintritt wird nicht auf Null geprüft, also ist r16 == 0
 gleichbedeutend mit 256 mSec bzw. 256 Sec.
#3894539
Lesenswert?

Ich habe so wie es aussieht leider vergessen, dass ich mit einen PIC18 
Microcontroller arbeite. Ich gehe doch richtig in der Annahme, dass der 
Code für AVR ist, oder kann ich den so auch für den PIC übernehmen?
Wahrscheinlich rollen manche von euch bei solchen Fragen mit den Augen, 
aber so ist es leider wenn mann sowas gerade Anföng.
Ich Bedanke mich schonmal im Vorfeld für eure Gedult.
(Firma: Vescomp) #3894552
Lesenswert?

Sven Radola schrieb:
> Ich habe so wie es aussieht leider vergessen, dass ich mit einen PIC18
> Microcontroller arbeite. Ich gehe doch richtig in der Annahme, dass der
> Code für AVR ist, oder kann ich den so auch für den PIC übernehmen?

 Natürlich nicht, aber:
1
;******************* mSec Routine  *****************
2
;** Gewunschte Zeit (in mSec.) beim Aufruf in r16 **
3
;***************************************************
4
;*** Das ist die äußere Schleife (Einstellen der Zeit: grob)
5
Waitms:    ldi    r17, 0x14
6

7
;*** Das ist die innere Schlefe  (Einstellen der Zeit: mittel)
8
Wtms0:     ldi    r18, 0xC6              ;* Dieser Wert wird bei anderen Freq. geandert
9

10
Wtms1:
11
;*** Und hier kannst du NOP Befehle reinschreiben oder rausnehmen
12
           nop                           ;* Und mit NOP kannst du die Zeit fein verandern
13

14
;*** Hier wird die innere Schleife abgearbeitet
15
           dec    r18             ;* Wert dekrementieren
16
           brne   Wtms1           ;* Wenn > 0, nochmals zum Wtms1
17

18
;*** Hier wird die mittlere Schleife abgearbeitet
19
           dec    r17             ;* Wert dekrementieren
20
           brne   Wtms0           ;* Wenn > 0, nochmals zum Wtms0
21

22
;*** Hier wird der Wert in ms abgearbeitet
23
           dec    r16             ;* Wert fur ms dekrementieren
24
           brne   Waitms          ;* Wenn > 0, nochmals zum Waitms
25

26
           ret

 Wie wäre es wenn du jetzt selbst probierst ?
#3894558
Lesenswert?

1
  CBLOCK 0x00
2
  delay_cnt: 3
3
  ENDC
4
  
5
  ......
6
  
7
  movlw .250
8
  movwf delay_cnt+2
9
delay_2:  
10
  movlw .200
11
  movwf delay_cnt+1
12
delay_1:  
13
  movlw .199      ; 200µs
14
  movwf delay_cnt+0
15
  nop
16
  decfsz delay_cnt+0
17
  bra $-4
18
  
19
  decfsz delay_cnt+1
20
  bra delay_1
21
  
22
  decfsz delay_cnt+2
23
  bra delay_2

10.000250s  @ 16MHz
#3894612
Lesenswert?

Ich habe den Programmteil von Max H. als Unterprogramm einebunden, es 
funktioniert aber nicht so, wie ich es mir gedacht habe.
Ich will in meinem Programm meine LED's an PORTD 10 sek. an und aus 
schalten, ich werde hier meinen Quellode posten, hoffe ihr könnt mir 
sagen, wo mein Fehler liegt. Die Konfigzeile habe ich rausgenommen, für 
bessere Übersicht

------------------------------------------------------------------------ 
---
    list        p=18lf46k22     ; List definiert den Controller
    #include    <p18lf46k22.inc>; Headerdatei mit Registernamen
;---------------------------------
; VARIABLE DEFINITIONS
;---------------------------------
    CBLOCK  0x20        ; BLOCK abb 0x10(RAM)
    delay_cnt: 3
    ENDC
;---------------------------------
    ORG     0x000       ; Anfangsadresse 0x000
ResetVector movlw   high(main)
            movwf   PCLATH
            goto    main
;---------------------------------
; Hauptprogramm: main
;---------------------------------
main
    Banksel ANSELD
    clrf    ANSELD      ; Digital I/O
    clrf    TRISD       ; Ausgang
    clrf    PORTD       ; Ausgänge auf 0 setzen
;--------------------------------
LED
    movlw   0xff
    movwf   PORTD       ; Alle LED's an
    call    delay       ; delay Unterroutine aufrufen
    clrf    PORTD
    call    delay
    goto    LED

delay
    movlw .250
    movwf delay_cnt+2
delay_2:
    movlw .200
    movwf delay_cnt+1
delay_1:
    movlw .199      ; 200µs
    movwf delay_cnt+0
    nop
    decfsz delay_cnt+0
    bra $-4

    decfsz delay_cnt+1
    bra delay_1

    decfsz delay_cnt+2
    bra delay_2
    return
End
Gast #3894719
Lesenswert?

Hier gibt es einen Delay-Codegernerator für PICs
http://www.piclist.com/techref/piclist/codegen/delay.htm

Das ist der generierte Code für 10 Sekunden bei 16MHz:
1
; Delay = 10 seconds
2
; Clock frequency = 16 MHz
3

4
; Actual delay = 10 seconds = 40000000 cycles
5
; Error = 0 %
6

7
        cblock
8
        d1
9
        d2
10
        d3
11
        endc
12

13
Delay
14
                      ;39999993 cycles
15
        movlw  0x6C
16
        movwf  d1
17
        movlw  0x32
18
        movwf  d2
19
        movlw  0x58
20
        movwf  d3
21
Delay_0
22
        decfsz d1, f
23
        goto   $+2
24
        decfsz d2, f
25
        goto   $+2
26
        decfsz d3, f
27
        goto   Delay_0
28

29
                       ;3 cycles
30
        goto   $+1
31
        nop
32

33
                       ;4 cycles (including call)
34
        return

Gruß
John

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