Timer0 mit 628A, zeitberechnung
Montag, 21. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  PIC Mikrocontroller Allgemein  |  Timer (Allgemein)  |  Timer0 mit 628A, zeitberechnung « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: Timer0 mit 628A, zeitberechnung  (Gelesen 2050 mal)
 
Phaiax
Newbie
*
Offline Offline

Beiträge: 2


Profil anzeigen
« am: Mai 02, 2007, 20:42:37 »

Hi

Eigentlich hatte ich mir vorgenommen, meine Anfängerprobleme selbst zu lösen, aber hier versagt meine Mathemathik (obwohl ich eigentl ziemlich gut in Mathe bin)  Lächelnd

Zu meinem Aufbau:
Ich habe einen PIC16F628A auf einer Laborsteckkarte aufgebaut.
An Port B hängen 3 LEDs,
eine Rote an RB0,
eine Gelbe an RB1 und
eine Grüne an RB2, jeweils mit 470 Ohm an Masse.

Die rote LED ist die Lebenszeichenled, damit ich weiß, ob der PIC läuft.
Die grüne LED wird nach jedem AN+AUS der roten LED nach dem Wert von PortB, 5 gestellt. (Kein Interrupt)
D.h. wenn ich RB5 von Vdd auf Vss oder andersherum wechsele, folgt mit kurzer Verzögerung die grüne LED.
Die gelbe LED soll nach jedem Überlauf von Timer0 wechseln.

Das tut sie zur Zeit alle 5 Sekunden.

Nach meiner Rechnung müsste Timer0 aber jede Sekunde mehrmals überlaufen.

4 Mhz ist der Takt, den ich verwende (Interner Oszillator)
Dann kriegt T0 ein 1 Mhz Signal

1 Mhz = 1*10^6 Hz
das entspricht einem Schlag alle 1*10^-6 Sekunden    (t = 1/f)
Jetzt ist mein Teiler 256
also

10^-6 sek * 256 = 0,000256 sek  (also ziemlich oft in der Sekunde, sodass man ein Flimmern oder halbes Leuchten der LED sehen müsste. Sie wechselt aber nur alle 4-5 Sekunden)

Um jeden Interrupt mitzukriegen, mache ich dann noch beim Interrupt die Grüne LED an. Die geht dann auch alle 4-5 Sekunden an, und nach 0,1-0,3 Sekunden durch die Hauptprogrammschleife wieder aus.

Hier mein Programm:

Code:
list      p=16F628A           ; list directive to define processor
#include <p16F628A.inc>       ; processor specific variable definitions

errorlevel  -302              ; suppress message 302 from list file


__CONFIG   _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT




;***** VARIABLE DEFINITIONS

w_temp RES     1 ; variable used for context saving
status_temp RES     1 ; variable used for context saving


loops    equ 0x20              ; timer für wait
loops2   equ 0x21              ; timer für wait
; 0x22 bis 0x2C für die Bits (jeweils bit 0)
clockcounter equ 0x30


timerflags equ 0x32
; 0 (1) Timer läuft
; (0) Timer läuft nicht -> interrupts ignorieren
; 1 (1) läuft für high
; (0) läuft für low
; 2 (1) Gelb ist an
; (0) Gelb ist aus
; 3 testweise

; PORT-Zuweisungen
LED_gr equ H'0002' ; Ausgang, LED über 470 Ohm auf +5V (Vdd)
LED_rt equ H'0000' ; Ausgang, LED über 470 Ohm auf +5V (Vdd)
LED_ge equ H'0001' ; Ausgang, LED über 470 Ohm auf +5V (Vdd)
In_Data equ H'0003' ;Normaler Input
In_Clock equ H'0005' ;Interrupt


;**********************************************************************
org 0x000 ; processor reset vector
goto    main              ; go to beginning of program

;                         Interrupt
;###########################################################
org 0x004 ; interrupt vector location


; STATUS und W sichern
; ***************************
movwf   w_temp            ; save off current W register contents ;1
movf STATUS,w          ; move status register into W register ;2
movwf status_temp       ; save off contents of STATUS register ;3


bcf STATUS, RP0 ; bank0 ;4

bsf PORTB, LED_gr


; Timer 0 ist übergelaufen
;****************************
btfss INTCON, T0IF
goto nextinterrupt2

; Interruptflag zurücksetzen
bcf INTCON, T0IF ;13

; Grün an, wenn Timer für high läuft


;Wenn gelb an war, dann ausschalten, sonst einschalten
btfss timerflags, 2
goto anschalten

; setted
bcf timerflags, 2
bcf PORTB, LED_ge
goto nextinterrupt2
anschalten
; cleared
bsf timerflags, 2
bsf PORTB, LED_ge




nextinterrupt2

; nächster Interrupt ...

; Status Register zurückschreiben
; ****************************
movf    status_temp,w     ; retrieve copy of STATUS register ;15
movwf STATUS            ; restore pre-isr STATUS register contents ;16
swapf   w_temp,f ;17
swapf   w_temp,w          ; restore pre-isr W register contents ;18

retfie                    ; return from interrupt ;19,20



;                    Init
;##########################################################
main
; timer aus
;bank1
;----------------------------
bsf STATUS, RP0
bcf STATUS, RP1



;Timer 0 intialisieren
;**********************
bcf OPTION_REG, T0CS ; Timer-Source von T0 auf Clock ( nicht pin)
bsf OPTION_REG, PSA ; Vorteiler für Timer0
bcf OPTION_REG, T0SE ; egal, da pin nicht für T0 verwendet
bsf OPTION_REG, PS2 ; Vorteiler auf 256
bsf OPTION_REG, PS1
bsf OPTION_REG, PS0
bsf OPTION_REG, NOT_RBPU ; Pull-ups aus
; Interrupts im Interrupt-Abschnitt



;bank 0
;-----------------------------
bcf STATUS, RP0


clrf TMR0 ; Damit T0 nicht gleich überläuft


; Interrupts aus, nur PortB-Interrupt und Timer0-Interrupt an
; *********************************
movlw B'00100000'
movwf INTCON
; Werte für INTCON
; 7 : General Interrupt Enable 1 ; erst am ende der Intialisierung
; 6 : Peripherial IE 0
; 5 : TMR0 Overf IE 1
; 4 : RB0/INT external IE 0
; 3 : RB Port Change IE 1
; 2 : TMR0 Flag 0
; 1 : RB0/Int ext Flag 0
; 0 : RB Port Flag 0



; Timer 1 intialisieren ( nicht Benutzt )
; *********************
bcf T1CON, TMR1ON ; Timer 1 aus
bcf T1CON, T1OSCEN ; Timer1 Oszillator aus
bcf T1CON, TMR1CS ; Clock als TimerSource (alle 4 Takte -> 1Mhz -> 1µs) (nicht PIN)
; Anmerkungen zu Timer 1
; Timer 1 nehm ich doch nicht, weil der 16 bit bzw 2 Register hat, die man setzen muss.
; Das verbraucht Zeit


; Timer 2 (nicht benutzt)
; *********************
bcf T2CON, TMR2ON ; Timer 2 aus



; B-Ports auf Ein/Ausgänge
; *********************************
bsf STATUS, RP0 ;Bank1
movlw B'00101000'
movwf TRISB
;TrisB:
; 0 : Ausgang
; 1 : Eingang
;PORT-B Beschaltung TRIS-Wert
; 7I : - 0
; 6I : - 0
; 5I : Clock 1
; 4I : - 0
; 3 : Data 1
; 2 : grün 0
; 1 : gelb 0
; 0 : rot 0

nop
nop
nop

bcf STATUS, RP0 ;Bank0
clrf TMR0 ; Timer0 nochmal zurücksetzen
bsf INTCON, GIE ; ab jetzt interrupts erlauben

goto programmstart

;                        Start
;###########################################################



programmstart

bcf STATUS, RP0
bsf PORTB, LED_rt ; Rot an

CALL WAIT

bcf STATUS, RP0
bcf PORTB, LED_rt ; Rot aus

CALL WAIT

; grün nach Clock schalten

btfss PORTB, In_Clock
goto aus
bsf PORTB, LED_gr
goto weiter
aus bcf PORTB, LED_gr
weiter



goto programmstart


;                         WAIT
;########################################################


WAIT_kurz
        movlw   D'50'
        movwf   loops

goto top

WAIT
        movlw   D'150'
        movwf   loops

top     movlw   .250           ; timing adjustment variable (1ms)
        movwf   loops2
top2    nop                    ; sit and wait
        nop
        nop
        nop
  nop
        nop
        nop
        decfsz  loops2, F      ; inner loops complete?
        goto    top2           ; no, go again
                               ;
        decfsz  loops, F       ; outer loops complete?
        goto    top            ; no, go again
        retlw   0              ; yes, return from subWAIT


; initialize eeprom locations


END                       ; directive 'end of program'
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #1 am: Mai 03, 2007, 19:22:02 »

Zitat
4 Mhz ist der Takt, den ich verwende (Interner Oszillator)
Dann kriegt T0 ein 1 Mhz Signal

Richtig.

Zitat
Jetzt ist mein Teiler 256
also

10^-6 sek * 256 = 0,000256 sek  (also ziemlich oft in der Sekunde, sodass man ein Flimmern oder halbes Leuchten der LED sehen müsste.

Falsch. Timer0 ist ein 8-Bit Timer, d.h. er läuft nach 1µs * 256 * 256 = 0,065536s über.

Ich habe mir das Programm noch nicht näher angesehen, mir ist aber aufgefallen, daß das Programm wohl im "absolute mode" (d.h. MPASM ohne Linkerscript) geschrieben ist. Zumindest verwendest Du equ für Variablen und org für Programmspeicheradressen.

Der Code für die beiden Sicherungsregister

Zitat
Code:
;***** VARIABLE DEFINITIONS

w_temp RES     1 ; variable used for context saving
status_temp RES     1 ; variable used for context saving

ist aber nur im "relocatable mode" (d.h MPASM mit Linkerscript) zulässig. Damit wird die Sicherung dieser Register so nicht funktionieren (mich wundert es übrigens, daß der Code fehler- und warnungsfrei übersetzt wird). Im "absolute mode" müßten diese Variablen über equ in den Adreßbereich 0x70-0x7F gelegt werden.


Viele Grüße

Bernd
Gespeichert

Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.048 Sekunden mit 19 Zugriffen.
 
Top! Top!