Forum: Mikrocontroller und Digitale Elektronik PIC16F1939 I/P - Blinkende LED


von Michael Buschmann (Gast)


Lesenswert?

Hallo,
ich bin zimlich neu auf dem Gebiet der Microcontroller(Komme von C++ und 
C#) und habe mich etwas in das Thema eingelesen (Insbesondere 
Assembler).
Bisher hat auch alles ganz gut funktioniert und ich hatte alles ganz gut 
verstanden.
Jetzt verstehe ich follgendes aber nicht.
In der PIC Documentation steht das der PIC standartmäßig 500KHz hätte.
Das heißt er müsste doch pro Sekunde 500000 Befehle ausführen können 
oder ?
(Oder 500000 / 4 ?)
Warum Blinkt die LED dann aber ca. 1 mal pro Sekunden(Etwas weniger)?
Ich meine ich rufe doch die Delay Funktion immer nur ca. 20 mal 
hintereinander aus befor ich den LED Zustand wechsel.
Und einmal Delay zählt gerade mal von 255 bis 0.
Das wären ja dann insgesammt 20 * 255 = 5100 Takte "Pause".
Und wenn ich dann die 500000 / 5100 rechne müsste die LED doch ca. 98 
mal die Sekunden aufleuchten und dunkel werden.
Kann mir das jemand erklären ?

Und eine kleine Nebenfrage, ich habe mal gelesen das man die Bank mit 
dem STATUS Register wechseln kann/muss aber bei meiner PIC Documentation 
steht man soll das BSR Register benutzen.
Und mein PIC hat ja auch in jeder Bank ein STATUS Register.
Also warum und was sollte ich benutzten?

Hier der Quellcode:

;----------------------------------------------------------------------- 
---
;- Includes
;----------------------------------------------------------------------- 
---

#include "p16F1939.inc"

;----------------------------------------------------------------------- 
---
;- Config
;----------------------------------------------------------------------- 
---

__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & 
_CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF

__CONFIG _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_ON & _STVREN_ON & 
_BORV_LO & _LVP_OFF

;----------------------------------------------------------------------- 
---
;- Constants
;----------------------------------------------------------------------- 
---

DELAY_COUNTER_ADDRESS   EQU 0x21 ; Used by "Delay" function

;----------------------------------------------------------------------- 
---
;- Entry point
;----------------------------------------------------------------------- 
---

; Skip all the functions
goto MAIN_LABEL

;----------------------------------------------------------------------- 
---
;- Functions
;----------------------------------------------------------------------- 
---

Delay

    MOVLW 0xFF
    MOVWF DELAY_COUNTER_ADDRESS

    DELAY_LOOP_LABEL
    DECFSZ DELAY_COUNTER_ADDRESS
    GOTO DELAY_LOOP_LABEL

RETURN

;----------------------------------------------------------------------- 
---
;- Main
;----------------------------------------------------------------------- 
---

MAIN_LABEL

; Switch to bank 1
MOVLW 0x01
MOVWF BSR

; Set TRISA
MOVLW 0x00
MOVWF TRISA

; Switch to bank 0
MOVLW 0x00
MOVWF BSR

; Clear PORTA
MOVLW 0x00
MOVWF PORTA

MAIN_LOOP_LABEL

; Clear PORTA
MOVLW 0x00
MOVWF PORTA

CALL Delay
CALL Delay
...
Hier rufe ich eigentlich im originalen Quellcode die Funktion 20 mal auf

; Set PORTA
MOVLW 0xFF
MOVWF PORTA

CALL Delay
CALL Delay
...
Hier rufe ich eigentlich im originalen Quellcode die Funktion 20 mal auf

GOTO MAIN_LOOP_LABEL

;----------------------------------------------------------------------- 
---
;- End
;----------------------------------------------------------------------- 
---

END

von Max H. (hartl192)


Lesenswert?

Michael Buschmann schrieb:
> In der PIC Documentation steht das der PIC standartmäßig 500KHz hätte.
> Das heißt er müsste doch pro Sekunde 500000 Befehle ausführen können
> oder ?
> (Oder 500000 / 4 ?)
500k / 4

> Das wären ja dann insgesammt 20 * 255 = 5100 Takte "Pause".
Ein durchlauf der Delay schleife dauert ein bisschen länger als 1 Takt. 
Schon alleine das GOTO brauch 2

> Und eine kleine Nebenfrage, ich habe mal gelesen das man die Bank mit
> dem STATUS Register wechseln kann/muss aber bei meiner PIC Documentation
> steht man soll das BSR Register benutzen.
> Und mein PIC hat ja auch in jeder Bank ein STATUS Register.
> Also warum und was sollte ich benutzten?
Das mit dem Status waren die alten PIC16, bei den neueren macht man das 
übers BSR. Welche bits würdest du beim PIC16F1939 im Status überhaupt 
setzten um Bank zu switchen?

> MOVLW 0x01
> MOVWF BSR
Dafür kannst du auch ben mowlb Befehl oder das Banksel Makro verwenden.

: Bearbeitet durch User
von Michael Buschmann (Gast)


Lesenswert?

Max H. schrieb:
>> Und eine kleine Nebenfrage, ich habe mal gelesen das man die Bank mit
>> dem STATUS Register wechseln kann/muss aber bei meiner PIC Documentation
>> steht man soll das BSR Register benutzen.
>> Und mein PIC hat ja auch in jeder Bank ein STATUS Register.
>> Also warum und was sollte ich benutzten?
> Das mit dem Status waren die alten PIC16, bei den neueren macht man das
> übers BSR. Welche bits würdest du beim PIC16F1939 im Status überhaupt
> setzten um Nank zu switchen?

Ja ok das eine hat sich dann erledigt.
Aber nich nicht die Hauptfrage.

Max H. schrieb:
>> Das wären ja dann insgesammt 20 * 255 = 5100 Takte "Pause".
> Ein durchlauf der Delay schleife dauert ein bisschen länger als 1 Takt.
> Schon alleine das GOTO brauch 2

Das ist mir kla, das meine Berechnungen nicht so genuau sind, aber ich 
glaube kaum das die die Berechnungen von 98 mal die Sekunde auf 1 mal 
die Sekunde runterbringen würden..
Also wie kann das sein ?

von Michael Buschmann (Gast)


Lesenswert?

Ich meine ein Delay müsste ca. 25000 Takte verbraten, was aber doch auf 
keinen Fall sein kann...

von Max H. (hartl192)


Lesenswert?

Michael Buschmann schrieb:
> Das ist mir kla, das meine Berechnungen nicht so genuau sind,
Alleine durch das Weglassen der GOTOs hast du schon um den Faktor 3 
verfehlt.
> Also wie kann das sein ?
Ich hab mit den Code jetzt nicht so genau angesehen, mit der Korrektur, 
dass der PIC bei 500kHz "nur" 125kIPS macht, ein Schleifendurchlauf 3 
Taktzyklen benötigt und du das Delay 40 mal Pro Periode (20 mal während 
der High- und 20 mal während der Lowtime) aufrufst, kommen wir der 
Realität schon näher.
Dann kommt auch noch dazu, dass du mit dem Sprung zum delay Lable und 
wider zurück und dem Beschreiben des DELAY_COUNTER_ADDRESS Registers 240 
Taktzyklen verlierst.

: Bearbeitet durch User
von chris (Gast)


Lesenswert?

Ein delaydauert 1025 Takte

von chris (Gast)


Lesenswert?

Sorry 770

von chris (Gast)


Lesenswert?

Und der Grund ist wahrscheinlich, dass der failsafe clock läuft, also ca 
125khz +-50%
Read the fucking datasheet.

von Thomas E. (picalic)


Lesenswert?

chris schrieb:
> 125khz +-50%
> Read the fucking datasheet.

Nein, nach dem Reset läuft der PIC tatsächlich mit 500 kHz, und damit 
kommt die halbe Sekunde pro 20x Delay-Aufruf schon hin:

50kHz -> 8 µs pro Takt ->  *4 = 32 µs Befehlszyklus.
770 * 32µs = ca. 25 ms, 25 * 20 = 500 ms -> Blinkfrequenz = 1/s

von GroberKlotz (Gast)


Angehängte Dateien:

Lesenswert?

@ Michael Buschmann

...hatte gerade etwas Zeit - so läuft es etwa.
Wie schon gesagt, ein Arbeitstakt dauert bei den PIC 1/(fosc/4) s
Hab Dir mal das etwas ergänzte Projekt angehängt.

mfG GroberKlotz

von chris (Gast)


Lesenswert?

Thomas Elger schrieb:
> chris schrieb:
> 125khz +-50%
> Read the fucking datasheet.
>
> Nein, nach dem Reset läuft der PIC tatsächlich mit 500 kHz, und damit
> kommt die halbe Sekunde pro 20x Delay-Aufruf schon hin:
> 50kHz -> 8 µs pro Takt ->  *4 = 32 µs Befehlszyklus.
> 770 * 32µs = ca. 25 ms, 25 * 20 = 500 ms -> Blinkfrequenz = 1/s

500khz CLK = 8 uS  instructions timing, nicht 32.
Failsafe plus 4x pll, weil dieser nicht so schnell lock't sind 125khz, 
32uS je Instruktion clock.

von Thomas E. (picalic)


Lesenswert?

chris schrieb:
> 500khz CLK = 8 uS  instructions timing, nicht 32.

Uuuups - stimmt natürlich! Hab wohl den Takt versehentlich 2x durch 4 
geteilt, 1x intuitiv (weil's beim PIC immer so ist) und dann nochmal, 
weil man ja beim PIC den Takt immer durch 4 teilen muss, um auf die 
Instruction-Cycles zu kommen (naja, war halt schon spät), und weil 
schließlich auch noch ca. 1/s Blinkfrequenz am Ende 'rauskam, war ich 
natürlich fest von der Richtigkeit des Unsinns überzeugt...

Ok, seltsam finde ich dann, warum es so langsam läuft. Mit 
"_FOSC_INTOSC" im Config-Register und dem Reset-Wert im OSCCON (der ja 
im o.a. Programm nicht verändert wird) komme ich immer nur auf 500 kHz 
Takt!?

von chris (Gast)


Lesenswert?

Weil er den pll 4x eingeschaltet hat, und dieser sich nicht innerhalb 
2ms lock't. Deshalb startet dann der failsafe OSC, 32kh , zusammen mit 
dem 4x pll sind es dann 125khz.

von Thomas E. (picalic)


Lesenswert?

Sorry, aber ich kapiere es trotzdem nicht, weil:
1. im Config-Word "FCMEM_OFF" eingestellt ist, also der Failsafe-Clock 
Monitor gar nicht aktiviert ist.
2. Der Failsafe Clock nur den externen Clock überwacht, aber mit 
"FOSC_INTOSC" sowieso der interne Clock ausgewählt ist.
3. Selbst im Falle eines "Failsafe" nicht automatisch der "LFINTOSC" als 
Clock ausgewählt würde, sondern der interne Oszillatorblock mit der 
Frequenzwahl entsprechend im OSCCON-Register.
Siehe Datenblatt, unter 5.5.2 FAIL-SAFE OPERATION:
"The  internal  clock  source  chosen  by  the  FSCM  is
determined  by  the  IRCF<3:0>  bits  of  the  OSCCON
register." Da das OSCCON-Register Reset-Status hat, ist das hier der 500 
kHz Takt.
4. Die PLL ist zwar lt. Config-Word "enabled", aber wird bei Verwendung 
des internen Oszillators nach einem Reset nicht verwendet (IRCF-Bits = 
0111 für 500kHz)
5. Ich finde auch nirgends im Datenblatt irgend einen Hinweis, daß der 
PIC den 32kHz Oszillator verwendet, wenn die PLL nicht locked, noch sehe 
ich eine Möglichkeit, diesen Oszillator überhaupt als Takteingang in die 
PLL zu verwenden. Die einzig möglichen Taktquellen für die PLL sind der 
externe Clock und der interne 8 MHz Clock.

: Bearbeitet durch User
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.