Antworten

Einschränkungen: 8 pro Beitrag (8 verbleibend), maximale Gesamtgröße 8,79 MB, maximale Individualgröße 1 MB
Entfernen Sie den Haken der Dateianhänge, die gelöscht werden sollen
Klicken Sie hier oder ziehen Sie Dateien hierher, um sie anzuhängen.
Anhänge und andere Optionen
Verifizierung:
Bitte lassen Sie dieses Feld leer:
Geben Sie die Buchstaben aus dem Bild ein
Buchstaben anhören / Neues Bild laden

Geben Sie die Buchstaben aus dem Bild ein:

Tastenkürzel: Alt+S Beitrag schreiben oder Alt+P für Vorschau

Zusammenfassung

Autor pic18
 - 31.07.2025, 23:23:22 CEST
Ist schon richtig, nur die Zählerei ist mir zu kompliziert. Zumal ich in C programmiere. Je nachdem welchen C-Compiler genommen wird, ändert sich dann der Code. Dann stimmt alles nicht. 
Autor Ottmar
 - 31.07.2025, 21:42:02 CEST
Hi pic18,
das Abzählen fällt leicht, den in MPLAB 8 gibt es einen praktischen Timer zum Zählen der Arbeitstakte zwischen zwei Haltepunkten.
Intervall stoppen, Sollzeit - Istzeit = Extratakte (wc) hinzuzufügen. So kann auch die Ausführungszeit z.B. von Schleifen mit ein paar Clicks, taktgenau festgestellt werden. Nachstehend ein Beispiel.

ISR:
bcf  INTCON,TMR0IF
NOP        ->1wc
GOTO $ +1  ->2wc 
; und so weiter.....und wenn es ganz extrem werden sollte:

isr_taktehinzufügen:
movlw  (n)                  ->1wc   n * (8wc) = 8...-x wc zum Abgleich verfügbar
movwf  dummy                ->1wc 
decfsz dummy,f              ->2-3wc 
GOTO   isr_taktehinzufügen  ->2wc 
;
movlw  tmr0preset
movwf  TMR0     --- hier endet das alte, beginnt das neue Intervall


Autor pic18
 - 31.07.2025, 20:32:58 CEST
Da muss genau die Taktzyklen abgezählt werden, damit der Timer richtig gestellt wird. Bei mir gleicht sich dies automatisch aus. Gut es ist manchmal ein Takt etwas kürzer. Eine Uhr läuft aber über Monate Ganggenau.
Autor Ottmar
 - 31.07.2025, 20:15:16 CEST
@pic18 
Hm... meine Interrupt-Intervalle stimmen auf den Arbeitstakt genau. In der ISR, deren Intervall fast immer einige Arbeitstakte zu kurz ist, gleiche ich das dann mit einigen sinnvollen der auch wirkungslosen Instruktionen aus.
Autor PICkel
 - 31.07.2025, 19:35:00 CEST
Noch ein Tipp zum Thema Timerauslegung:

Von mikroe gibt es ein Programm, das auch "standalone" läuft: den Timer- Calculator:  https://www.mikroe.com/timer-calculator
Hier kann man PIC-Typ, Timer, Taktfrequenz und Verzögerung eingeben und erhält einen Code wahlweise in mikro-C/-Basic oder -Pascal.
Eine Portierung in ASM ist bei den paar Zuweisungen auch kein Problem.
Aber seht selbst im Anhang. Bei Bedarf kann ich Euch ein zip-File mit den Daten bereitstellen.


Gruß
PICkel
Timer_Calculator.jpg
Autor pic18
 - 31.07.2025, 16:14:41 CEST
das mit dem Timer stellen mache ich schon lange nicht mehr, das ist mir zu ungenau.
Ich würde es so machen:
den Vorteiler auf 32 setzen Timer auf 8 Bit (256 Überlauf)
bei 4Mhz würde ich dann 100ms zählen.
| bedeutet hoch, kann ich hier nicht darstellen.

256 und 32 Teiler 4 TOS/4
4*10|-6 s|-1 = 4MHz
100|10-3s =100ms

(256*32*4)/(4*10|-6s|-1 *100|10-3s) = 8,192E-2 = (256/3125)
 
jedes mal wenn der Interrupt aufgerufen wird, Variable Z  256 addieren
wenn Z >=3125 ist dann Z=Z-3125 und hier sind 100ms vorbei.
Autor Ottmar
 - 31.07.2025, 14:54:52 CEST
Hi picass,
Du hast recht. das war von mir ein Ablesefehler auf dem Windowsrechner "Programmierer", habe "B" anstatt korrekt "8" abgelesen. Die dezimale Berechnung stimmt jedoch, hättest Du das beim Nachvollziehen der Berechnung bemerken können?
Die Blinkfrequenz 1Hz mit dem LF-Osillator habe ich in dem ASM-File vom 25.7 bereits dargestellt.

Ok, ich gebe Dir 2 Beispiele für 50 Hz bzw. 1 Hz Blinkfrequenz mittels TIMER1-overflow-Interrupt, wie man dafür den Vorteiler und den Preset berechnet. Beachte bitte, daß der Arbeitstakt stets 1/4 der Oszillatorfrequenz beträgt. TMR1 zählt nur den Arbeitstakt.
;
a) 50Hz, Periodendauer 0,02s, zusammengesetzt aus
   0,01s High, 0,01s Low

b) 1Hz, Periodendauer 1s, zusammengesetzt aus 0,5s High, 0,5s Low
 
Gesucht a) Interrupt-intervall 0,01s (50Hz
        b) "                "              0,5s  (1Hz)
        dazu TMR1.Prescaler

Gegeben:fosc=4MHz (eingestellt z.B. mit OSCCON)
        TMR1-Modul (Zählbereich 0-2^16) + TMR1 overflow interrupt
        und Prescaler 1:1-1:8 vgl. Register TMR1CON

a) TMR1-Zähltakt = fosc/4 also 1.000.000 wc (Arbeitszyklen/sek.)
   ISR-Aufruf muss  für 10ms  (Peridodendauer 2x10ms) alle 10ms
   erfolgen. 
   Prescaler 1:1 wird verwendet, da TMR1 den Zählbereich offensichtlich
   ohne Vorteiler überstreicht, was Rechenarbeit erspart.

   Preset: = 2^16 - 10.000 = 55536 = 0xD8F0

b) TMR1-Zähltakt = fosc/4 also 1.000.000 wc (Arbeitszyklen/sek.)
   ISR-Aufruf muss  für 1Hz (Peridodendauer 2x0,5s) alle 0,s erfolgen

   Prescaler: 500.000 wc / 65536 = 7,6 nicht verfügbar!
   daher: nächsthöherer, verfügbarer Prescale: 1:8
   Preset TMR1: 2^16 - (500.000/8) = 3036 = 0x0BDC
   TMR1CON,T1CKPS<1:0>  = 11

   Der Vorteil einer zweckentsprechend gewählten Oszillatorfrequenz
   liegt damit wohl auf der Hand.

   mdG Ottmar

  
Autor picass
 - 31.07.2025, 12:03:03 CEST
Hallo Ottmar !
Deine Rechenübung kann ich nicht nachvollziehen.
Zunächst stimmt deine Zuordnung nicht: h'dbf0' sind d'56.304'

Dann ist völlig unklar, was genau du denn nun den PIC zählen lassen willst, um von seiner hohen Frequenz runter zu kommen auf 1 Hz. Takt soll 4 Mhz sein, ein Cyclus dann 1 Mhz, also jeder Cyclus belegt 1 µS. Dann soll nach deiner Rechnung der Counter1 gesamt 55.536 µS abzählen. Und wie kommt man nun auf eine Sekunde ?
Grüße, picass
 
Autor Ottmar
 - 30.07.2025, 15:41:50 CEST
A
Zitateinen Preset 2^16us - 20.000us = 45536 = 0xB1EO
richtig ist: 
2^16us - 10.000us = 55536us = 0xDBF0
denn die Periodendauer von 50Hz ist 20ms und dafür bedarf es 2 ISR-Intervalle zu je 10ms.
Autor Ottmar
 - 30.07.2025, 15:17:17 CEST
Hi picass,
langer Rede kurzer Sinn: Es geht einfacher, ohne Netzanbindung/Optokoppler und Halbwellenbildung, eine exakte 50Hz-Frequenz zu generieren.

Nimm das von mir anfänglich übermittelte ASM-File mit diesen Änderungen:
Internen Oszillator, Fosc = 4Mhz, das ergibt Fosc/4=1.000.000 wc (working cycles). 

Diese nimmst Du als clock für den TMR1, dazu den TMR1 overflow-Interrupt. In der ISR machst Du einen Preset 2^16us - 20.000us = 45536 = 0xB1EO.

Die "Denkpause" wird  vermieden, wenn man direkt vor Freigabe des Interrupts, (bsf INTCON,GIE) den TMR1 auf den Preset wie nachstehend setzt.

ZitatISR_H:
bcf        PIR1,TMR1IF
movlw   0xB1
movwf   TMR1H
movlw   0xE0
movwf   TMR1L
movlw   b'10000000' ;LED ist an bit 7
xorwf    PORTA,f        ;RA7 toggelt alle 200ms und LED blinkt mt 50Hz
RETFIE  FAST
Voila - das geht ganz ohne Vorteiler... fertig! Solls genauer sein, nimm einen 4MHz Quarz.
🡱 🡳