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
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.
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 ?
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.
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
@ 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
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.
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!?
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.
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.