Forum: Mikrocontroller und Digitale Elektronik Zeitschleife 10sek für 16MHz Quarz in Assembler


von Sven R. (xinax)


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.

von spess53 (Gast)


Lesenswert?

Hi

Probiers mal hiermit:

http://electronics-lab.com/downloads/mcu/003/index.html

MfG Spess

von Detlef K. (adenin)


Lesenswert?

In Assembler?
Das ist einfach.

Ich geh schon mal die Glaskugel polieren. ;)

von Marc V. (Firma: Vescomp) (logarithmus)


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.

von Sven R. (xinax)


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.

von Max H. (hartl192)


Lesenswert?

Sven Radola schrieb:
> oder kann ich den so auch für den PIC übernehmen?
Nein.

Habe ich es richtig verstanden, dass du eine Warteschleife Programmieren 
willst? Wie genau müssen die 10s sein?

von Sven R. (xinax)


Lesenswert?

Sie muss nicht auf die ms genau sein, es sollte nach Möglichkeit nicht 
9, oder 11 Ssek. sein.

von Timer (Gast)


Lesenswert?

Wie wäre es mit Timer? Die wurden dafür erfunden.

von Marc V. (Firma: Vescomp) (logarithmus)


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 ?

von Max H. (hartl192)


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

von Sven R. (xinax)


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

von Max H. (hartl192)


Lesenswert?

Sven Radola schrieb:
> es funktioniert aber nicht so, wie ich es mir gedacht habe.
Was funktioniert nicht?

von Sven R. (xinax)


Lesenswert?

Es findet kein Wechsel statt, die LED's bleiben angeschaltet. Es wir der 
PortD also nicht geköscht.

von Max H. (hartl192)


Lesenswert?

Wenn Ich deinen Code auf meinen PIC18F45k22 flashe (mit meinen Configs) 
blinken die LEDs.

Stimmt vllt. mit den Configs was nicht?

BTW: Beim PIC18 würde ich zum Ausgeben das LATx register verwenden,

> movlw   high(main)
> movwf   PCLATH
Das ist auch nicht nötig, da der PIC18 mit einen GOTO 20bit adressiert.

von John (Gast)


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

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.