Archiv verlassen und diese Seite im Standarddesign anzeigen : TMR0-Problem
michel f.
12.11.2004, 11:06
Hallo
Ich hab folgendes Problem:
Ich arbeite mit einem TMR0-Interrupt um an einer RS232 Schnittstelle Daten zu lesen. Ich starte also die Interruptfunktion sobald ich das StartBit des Bytes gelesen habe. Nun kann ich mit dem TMR0 acht mal einen Interrupt aufrufen um das Byte zu lesen. Ich habe allerdings die befürchtung dass der TMR nicht bei jedem zyklus inkrementiert, sondern auf irgend eine andrere Weise hochzählt.
Die Einstellungen im OPTION_REG hab ich alle auf 0 gesetzt
weiss jemand vielleicht wie der TMR0 hochzählt oder welche einstellungen man treffen muss, damit der TMR bei jedem zyklus inkrementiert??
danke wenn mir jemand behilflich ist.
gruss
michel f.
ein paar kurze Zwischenfragen:
- Welchen PIC nimmst du genau?
- du hast die serielle Schnittstelle in Software implementiert, oder hab ich das falsch verstanden?
- Wie äußert sich deine Vermutung, dass er nicht richtig zählt?
Ein Zyklus des Timers=1/4 des Taktes (wenn der Prescaler nicht aktiv ist).
Wenn das Bit PSA auf 0 steht, wird dem Prescaler der TMR0 zugewiesen. Zusammen mit PS2-0 ergibt das einen Vorteiler von 1:2.
Wenn man PSA auf 1 setzt, wird der Prescaler dem WDT zugeordnet und dein TMR0 hat nix mit zu tun (und damit das Verhältnis 1:1).
Und um deine Frage zu beantworten: das 4. Bit (PSA) muss auf HIGH gesetzt werden, damit der Timer bei jedem Durchlauf inkrementiert.
Vielleicht war das ja schon das einzige Problem ;)
MfG
Stefan
Danke für deine Hilfe. ; )
Also. ich arbeite mit dem PIC16f877. Ich habe die Schnittstelle nicht
in Software implementiert.
(Ich lese die Datenübertragung auf PORTC,7 ein)
Wenn ich mein Programm StepbyStep durchlaufe, und dabei das TMR0 Register kontrolliere, sehe ich dass das Register nicht schön inkrementiert.
dh. von einem step zum anderen ändert der Zahlenwert beispielsweise von 25 auf 56, und in einem nächsten step wider auf 2 (??!)
gruss
kannst du mal deinen Code posten?
Mfg
Christian
Hoffe ist einigermassen Verständlich 8-[
gruss
;*-----------------------------------
;* MF **
;* Sion, den 2.November 2004 **
;* **
;* RS232 Protokoll lesen, synchro **
;*-----------------------------------
;------------------------------------
;-------------------PIC-Settings-----
list p=16f877
include "p16f877.inc"
;------------------------Variablen definieren---
;-----------------------------------------------
CBLOCK H'070'
w_temp:1
status_temp:1
counter:1
mes_count:1
start_za:1
compt:1
ENDC
;------------------------------------------------
org 00h
nop
goto init
;------------------------------------------------
;----------------------Routine Interruption-----
org 0x004
movwf w_temp
swapf STATUS,w
movwf status_temp
;----------Verzögerungstest, zur synchronisation-
nop
decfsz mes_count
goto left
;---------------------------------------
bsf PORTD,1
movlw D'28'
movwf mes_count
nop
nop
incf counter
movlw D'8'
subwf counter,w
banksel TRISC
btfss STATUS,2
goto left
banksel PORTC
bcf INTCON,5
clrf PORTD
call Time_out
clrf counter
BANKSEL TMR0
clrf TMR0
BANKSEL PORTD
movlw D'28'
movwf mes_count
;----------------------------------------
left
BANKSEL PORTD
clrf PORTD
;----------------------------------------
swapf status_temp,w
movwf STATUS
swapf w_temp,f
swapf w_temp,w
retfie
;------------------------------------------------------
;-----------------------Initialisieren-----------------
init
BANKSEL TRISC
movlw B'11111111'
movwf TRISC
movlw B'11111111'
movwf TRISB
movlw B'00000000'
movwf TRISD
movlw B'00000000'
movwf OPTION_REG
bsf OPTION_REG,3;
BANKSEL PORTD
clrf INTCON
movlw B'10000000'
movwf INTCON
clrf PORTC
clrf PORTD
clrf counter
clrf mes_count
movlw D'28'
movwf mes_count
BANKSEL TMR0
clrf TMR0
BANKSEL PORTD
;-----------------------------------------------
;------------------------Programme Principal----
Main
btfss INTCON,5
btfsc PORTC,7
goto Main
Timer_on
bcf INTCON,2
bsf INTCON,5
goto Main
;----------------------------------------------------
Time_out
movlw D'100'
movwf compt
loop
decfsz compt
goto loop
return
;----------------------------------------------------
END
Also, was du machst ist praktisch RS232 in Software implementieren.
Wenn du Hardware-UART verwendest, ist es aber deutlich einfacher und du brauchst dich nicht um den Timer zu kümmern.
Du brauchst nur eine Initialisierung für den UART:
; USART initialisieren
BSF STATUS,RP0 ; Bank 1
MOVLW 0x20 ;
MOVWF TXSTA ;
MOVLW D'10' ; = 57 kbps bei 10 MHz
MOVWF SPBRG
BSF TXSTA, BRGH ;
BCF STATUS,RP0 ; Bank 0
MOVLW 0x90 ; Empfänger: RS232
MOVWF RCSTA ;
return
und dann ne Routine zum Ausgeben:
RS232out
btfss PIR1,TXIF ; kann ich senden?
goto RS232out
movwf TXREG
return[/code]
bzw. zum Empfangen:
RS232in
btfss PIR1,RCIF
goto RS232in
movwf RCREG
return
Allerdings bin ich mir bei dem Empfangsabschnitt nicht mehr ganz so sicher, ob ich den noch richtig im Kopf hab (schaff inzwischen hauptsächlich mit C). Am besten einfach mal im Datenblatt nachschaun. Da findest du alles unter dem Begriff USART.
Du schreibst:
>Ich habe allerdings die befürchtung dass der TMR nicht bei jedem zyklus inkrementiert
Meiner meinung nach ist TMR0 ein richtiges stuck hardware im PIC und lauft unabhangig und parallel zur anwenderprogram, und kann mann nicht benutzen om etwas stuckweise zu zahlen auserhalb eine Zeitabstand.
Wenn du 8 bits pro empfangen byte im interrupt zahlen willst sollst du ein variabelen dazu im interupt benutzen.
Gruss
Henk
Er meint damit, dass er damit die Synchronisation bei einer festen Baudrate macht... (denk ich zumindest)...
Und er braucht den Timer um alle 102 us (oder irgendein anderer Wert) nen Interrupt zu erzeugen, um dann das jeweilige Bit auszulesen...
Vielen Dank für eure Ideenanstösse!
Ich hab nun ne akzeptable Lösung für meine Problemstellung gefunden.
Ich musste nur in meinem Main Programm den TMR0 bei jedem einschalten initialisieren damit dieser immer nachderselben Zeit überlief.
Vielen Dank nochmals
freundliche Grüsse
Michel
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.