Forum

Einloggen | Registrieren | RSS  

Strippenzieher(R)

E-Mail

D-14806,
06.04.2020,
19:25
 

PIC Assembler Anfängerfrage 20-04-06 (Elektronik)

Verehrte Gemeinde!
PIC 16F630 , 1MHz Takt , Übungsobjekt, ohne ernsten Hintergrund:
Aber funktionieren sollte es , macht es aber nicht:
Es soll alle 4,096 ms ein bit H sein, aber nur einen Programmdurchlauf lang. Da dachte ich mir, Timer0 (der genaugenommen ein 8bit Zähler ist) via Vorteiler 256:1 mitlaufen lassen und dessen bit3 auf steigende Flanke abfragen. Geht 7mal, dann unerklärliche Pause, wieder 7mal ... irgendwann mal längere Pause (scheint mir) , mein ostalgisches Oszi kann das nicht darstellen.
Hatte den vermeintlichen 4,096 ms -Takt noch weiter runtergeteilt um eine 7-Seg Anzeige (etwa) im Sekundentakt hochzählen zu lassen, dabei fiel auf, dass die "Uhr" zu langsam und unregelmäßig lief. Letzteres wieder gelöscht, das Übrige sieht dann so aus:
;Files Required: P16F630.INC
list p=16f630 ; list directive to define processor
#include <p16F630.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG _FOSC_INTRCIO & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _BOREN_OFF & _CP_OFF & _CPD_OFF
ORG 0x000 ;processor reset vector
;clear RAM
movlw 0x20 ;Anfang RAM
movwf FSR ;ins FileSelectRegister
clrf INDF ;lösche Inhalt indirekt adressiertes Register
incf FSR,1 ;erhöhe FileSelectRegister um 1
btfss FSR,7 ;wenn 80h, dann überspringe nächsten Befehl
goto $-3 ;springe 3 Zeilen zurück
;setting SpecialFunktionRegister
bcf STATUS,RP0 ;Umschaltung auf Bank 0
movlw b'00000111' ;Zahl in Akku
movwf CMCON ;Komparator Konfig off, lowest power
bsf STATUS,RP0 ;Umschaltung auf Bank 1
movlw b'01010111' ;Zahl in Akku
movwf OPTION_REG ;pull-up zulassen+timer+prescaler256
movlw b'00001111' ;Zahl in Akku
movwf TRISA ;PortA definieren
movlw b'00000000' ;Zahl in Akku
movwf TRISC ;PortC definieren
bcf STATUS,RP0 ;Umschaltung auf Bank 0
movlw b'111111' ;Zahl in Akku
movwf PORTA ;Akku zum PortA
movlw 0x52 ;Kalibrierwert in Akku
movwf OSCCAL ;korrigiere Oszillator
goto Haupt ;zum Hauptprogramm
; Hier geht's richtig los
Haupt ;Flankenauswertung timer0
comf 0x20,0 ;Reg.20 negiert in Akku
andwf TMR0,0 ;Akku alt & timer0 = Akku neu
movwf 0x21 ;Akku in Reg.21 = Flankenbits
movf TMR0,0 ;timer0 in Akku
movwf 0x20 ;Akku in Reg.20
movf 0x21,0
movwf PORTC

goto Haupt ;zum Hauptprogramm
END ;directive 'end of program'

Weiß jemand, weshalb die Flankenbits (im Register 21) nicht wie erhofft regelmäßig zur Verfügung stehen?
Denkfehler meinerseits oder völlig falscher Ansatz?
Besten Dank schonmal fürs Durchwurschteln:-|

xy(R)

E-Mail

06.04.2020,
20:41

@ Strippenzieher

PIC Assembler Anfängerfrage 20-04-06

Kannst du das bitte als Textfile anhängen, die Forensoftware zerpflückt leider die Formatierung.

Altgeselle(R)

E-Mail

06.04.2020,
20:42

@ Strippenzieher

PIC Assembler Anfängerfrage 20-04-06

» Verehrte Gemeinde!
» PIC 16F630 , 1MHz Takt , Übungsobjekt, ohne ernsten Hintergrund:
» Aber funktionieren sollte es , macht es aber nicht:
» Es soll alle 4,096 ms ein bit H sein, aber nur einen Programmdurchlauf
» lang. Da dachte ich mir, Timer0 (der genaugenommen ein 8bit Zähler ist) via
» Vorteiler 256:1 mitlaufen lassen und dessen bit3 auf steigende Flanke
» abfragen. Geht 7mal, dann unerklärliche Pause, wieder 7mal ... irgendwann
» mal längere Pause (scheint mir) , mein ostalgisches Oszi kann das nicht
» darstellen.
» Hatte den vermeintlichen 4,096 ms -Takt noch weiter runtergeteilt um eine
» 7-Seg Anzeige (etwa) im Sekundentakt hochzählen zu lassen, dabei fiel auf,
» dass die "Uhr" zu langsam und unregelmäßig lief. Letzteres wieder gelöscht,
» das Übrige sieht dann so aus:
» ;Files Required: P16F630.INC
» list p=16f630 ; list directive to define processor
» #include <p16F630.inc> ; processor specific variable definitions
» errorlevel -302 ; suppress message 302 from list file
» __CONFIG _FOSC_INTRCIO & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _BOREN_OFF &
» _CP_OFF & _CPD_OFF
» ORG 0x000 ;processor reset vector
» ;clear RAM
» movlw 0x20 ;Anfang RAM
» movwf FSR ;ins FileSelectRegister
» clrf INDF ;lösche Inhalt indirekt adressiertes Register
» incf FSR,1 ;erhöhe FileSelectRegister um 1
» btfss FSR,7 ;wenn 80h, dann überspringe nächsten Befehl
» goto $-3 ;springe 3 Zeilen zurück
» ;setting SpecialFunktionRegister
» bcf STATUS,RP0 ;Umschaltung auf Bank 0
» movlw b'00000111' ;Zahl in Akku
» movwf CMCON ;Komparator Konfig off, lowest power
» bsf STATUS,RP0 ;Umschaltung auf Bank 1
» movlw b'01010111' ;Zahl in Akku
» movwf OPTION_REG ;pull-up zulassen+timer+prescaler256
» movlw b'00001111' ;Zahl in Akku
» movwf TRISA ;PortA definieren
» movlw b'00000000' ;Zahl in Akku
» movwf TRISC ;PortC definieren
» bcf STATUS,RP0 ;Umschaltung auf Bank 0
» movlw b'111111' ;Zahl in Akku
» movwf PORTA ;Akku zum PortA
» movlw 0x52 ;Kalibrierwert in Akku
» movwf OSCCAL ;korrigiere Oszillator
» goto Haupt ;zum Hauptprogramm
» ; Hier geht's richtig los
» Haupt ;Flankenauswertung timer0
» comf 0x20,0 ;Reg.20 negiert in Akku
» andwf TMR0,0 ;Akku alt & timer0 = Akku neu
» movwf 0x21 ;Akku in Reg.21 = Flankenbits
» movf TMR0,0 ;timer0 in Akku
» movwf 0x20 ;Akku in Reg.20
» movf 0x21,0
» movwf PORTC
»
» goto Haupt ;zum Hauptprogramm
» END ;directive 'end of program'
»
» Weiß jemand, weshalb die Flankenbits (im Register 21) nicht wie erhofft
» regelmäßig zur Verfügung stehen?
» Denkfehler meinerseits oder völlig falscher Ansatz?
» Besten Dank schonmal fürs Durchwurschteln:-|

Hallo,
zunächst: du kalibrierst den Oszillator falsch. Siehe Datenblatt 9.2.5.1, benutze den Code
von Example 9-1.
Um eine konstante Zykluszeit der Hauptschleife zu erreichen, geht man so vor:
Man setzt den TMR0 auf einen gewünschten Wert. Der Timer
zählt dann hoch bis zum Überlauf. Den Überlauf fragt man entweder über eine
Interrupt-Routine ab (siehe 9.4) oder man testet den Timer in einer Schleife, in der
die restliche Zeit "verbraten" wird.
Grüße
Altgeselle

Strippenzieher(R)

E-Mail

D-14806,
07.04.2020,
10:36

@ xy

PIC Assembler Anfängerfrage 20-04-06

mach ich

https://www.elektronik-kompendium.de/forum/upload/20200407103503.txt

Strippenzieher(R)

E-Mail

D-14806,
07.04.2020,
10:49
(editiert von Strippenzieher
am 07.04.2020 um 11:07)


@ Altgeselle

PIC Assembler Anfängerfrage 20-04-06

» Hallo,
» zunächst: du kalibrierst den Oszillator falsch.
Ja, ich weiß.
Hatte zu Beginn meiner Übungen einen Eigenbaubrenner nach Sprut, hat funktioniert - bis irgendwann der Kalibrierwert aus dem EEPROM weg (oder ungültig) war. Das Sprutprogramm hat 52 für meinen einen PIC angezeigt.

» Um eine konstante Zykluszeit der Hauptschleife zu erreichen,
Ich gaube, das ist nicht was ich anstrebe.
Die Hauptschleife soll möglichst schnell abgearbeitet werden, ohne künstliche Verzögerung. Es soll nach konstanter Zeit (2^12 Takte im vorliegenden Fall) ein Unterpr. aufgerufen werden
» Man setzt den TMR0 auf einen gewünschten Wert. Der Timer
» zählt dann hoch bis zum Überlauf. Den Überlauf fragt man entweder über
» eine
» Interrupt-Routine ab (siehe 9.4) oder man testet den Timer in einer
» Schleife, in der
» die restliche Zeit "verbraten" wird.
Muss ich mich mal damit beschäftigen.
Bis zum Interrupt bin ich geistig noch nicht vorgedrungen.
Dank erstmal.

xy(R)

E-Mail

07.04.2020,
17:40

@ Strippenzieher

PIC Assembler Anfängerfrage 20-04-06

» https://www.elektronik-kompendium.de/forum/upload/20200407103503.txt

Gibts kein btfsc und btfss mehr?

Strippenzieher(R)

E-Mail

D-14806,
08.04.2020,
18:59

@ Strippenzieher

Problem gelöst

Ändert Timer0 im Laufe der Flankenauswertung seinen Wert - was gelegentlich vorkommt, dann gehen die Flankenbits verloren. Also vor der Flankenauswertung den Timer0 in einem Register speichern.


https://www.elektronik-kompendium.de/forum/upload/20200408185807.txt