Forum: Mikrocontroller und Digitale Elektronik Newbi braucht hilfe Pic 16f876


von Bodo (Gast)


Lesenswert?

Hallo ich beschäftige mich seit 2 Wochen mit Pic’s. Ich habe den 
Pic16f876.

Ich habe folgendes prob. Ich möchte in ein vorhandenes Programm einige 
Ausgänge integriert.

Das original Programm habe ich von 
http://www.sprut.de/electronic/pic/projekte/thermo/thermo.htm

So und ich habe es folgendermaßen abgewandelt.

#define Offset D'250' ; Offset des PTC
#define Toff1 D'30'
#define Toff2 D'30'
#define Ton1 D'38'
#define Ton2 D'38'

Das sind die werte bei den der Lüfter an bzw aus gehen soll.
Lüfter ein/aus-schalten

Luft1
; prüfen ob Temp<Toff
MOVFW Toff1
subwf f0, w ; w:=f-33 = temp-Toff
btfss STATUS, C
bcf PORTC, 5 ; Lüfter aus
; prüfen ob Temp>Ton
MOVFW Ton1
subwf f0, w ; w:=f-38 = temp-Ton
btfsc STATUS, C
bsf PORTC, 5 ; Lüfter an
return

Luft2
; prüfen ob Temp<Toff
MOVFW Toff2
subwf f0, w ; w:=f-w = temp-Toff
btfss STATUS, C
bcf PORTC, 4 ; Lüfter aus
; prüfen ob Temp>Ton
MOVFW Ton2
subwf f0, w ; w:=f-w = temp-Ton
btfsc STATUS, C
bsf PORTC, 4 ; Lüfter an
return
Die Unterprogramme werden im Hauptprogramm auf gerufen.

Ich weiß niocht was ich falsch gemacht habe kann mir jemand helfen?


Danke im voraus Bodo K.

von Torsten S. (torstensc)


Lesenswert?

Wenn du uns noch sagst, was genau nicht geht oder falsch gemacht wird 
könnten wir mitdenken.

Torsten

von Bodo (Gast)


Lesenswert?

Hi ist ja super so schnell.

Also ich habe zwei Ausgänge eingefügt Port C4 und C5.

Diese sollen bei 38 Crad angehen und bei 30 Crad Ausgehen.

Dafür habe ich folgendes gemacht.

#define Toff1           D'30'
#define Toff2           D'30'
#define Ton1            D'38'
#define Ton2            D'38'

Für meine aus- einschalt Temperaturen.

; Lüfter ein/aus- schalten

Luft1
  ; prüfen ob Temp<Toff
  MOVFW  Toff1
  subwf  Digit, w    ; w:=f-33 = temp-Toff
  btfss  STATUS, C
  bcf  PORTC, 5    ; Lüfter aus
  ; prüfen ob Temp>Ton
  MOVFW  Ton1
  subwf  Digit, w    ; w:=f-38 = temp-Ton
  btfsc  STATUS, C
  bsf  PORTC, 5    ; Lüfter an
  return

Luft2
  ; prüfen ob Temp<Toff
  MOVFW  Toff2
  subwf  Digit, w    ; w:=f-w = temp-Toff
  btfss  STATUS, C
  bcf  PORTC, 4    ; Lüfter aus
  ; prüfen ob Temp>Ton
  MOVFW  Ton2
  subwf  Digit, w    ; w:=f-w = temp-Ton
  btfsc  STATUS, C
  bsf  PORTC, 4    ; Lüfter an
  return

Für die Lüfter.

Ich hoffe diese angaben reichen Dir.

Danke im voraus BodoK.

von Bodo (Gast)


Lesenswert?

Ach so die Ausgänge schalten nicht und weiß nicht warum

von Lupin (Gast)


Lesenswert?

Hast auch TRISC bit 4 und 5 auf 0 gesetzt?

von Bodo (Gast)


Lesenswert?

Ich glaube das habe ich.

Init  movlw  B'11111111'
  movwf  PORTB
  movwf  PORTC    ; LED aus
  bsf     STATUS, RP0  ; Bank 1
  movlw   Ini_opt       ; pull-up on
  movwf   OPTION_REG
  movlw  B'00000000'  ; PortB & C alle outputs
  movwf  TRISB
  movwf  TRISC
  bcf     STATUS, RP0  ; Bank 0
  movlw  B'11111111'
  movwf  PORTB
  movwf  PORTC    ; LED aus

von Bodo (Gast)


Lesenswert?

So hier ist das ganze Programm.

  list p=16f876
;**************************************************************
;*    Pinbelegung
;*  ----------------------------------
;*  PORTA:   0 < PTC-Spannung
;*    1 -
;*    2 -
;*    3 -
;*    4 -
;*    5 -
;*    6 -
;*    7 -
;*
;*  PORTB:  0 Segment A     AAAAA     AAAAA     AAAAA
;*    1 Segment F    F     B    F     B    F     B
;*    2 Segment E    F     B    F     B    F     B
;*    3 Segment D     GGGGG       GGGGG       GGGGG
;*    4 Segment H    E     C    E     C    E     C
;*    5 Segment C    E     C    E     C    E     C
;*    6 Segment G     DDDDD  HH     DDDDD  HH     DDDDD  HH
;*    7 Segment B
;*
;*  PORTC:  0 LED------------------------------------------------A
;*    1 LED--------------------------------A
;*    2 LED----------------A
;*    3 -
;*    4 -
;*    5 -
;*    6 - (> TX: RS-232-Ausgang zum Treiber)
;*    7 - (< RX: RS-232-Eingang vom Treiber)
;*
;**************************************************************
;
;sprut (zero) Bredendiek 06/2003
;
; Termometer mit 16F876 und KTY81-110
;
; Prozessor 16F876 / 16F673
;
; Prozessor-Takt 4 MHz
;
; PTC-Spannung:
;  Temp.  Spannung  ADC
;  -20°C  1,0106 V  206
;  0°C  1,1593 V  237
;  +20°C  1,3125 V  268
;  +40°C  1,4678 V  300
;  +100°C  1,9290 V  395
;
;
;
;**************************************************************
; Includedatei für den 16F876 einbinden

  #include <P16f876.INC>

  ERRORLEVEL      -302      ;SUPPRESS BANK SELECTION MESSAGES

; Configuration festlegen:
; Power on Timer, kein Watchdog, HS-Oscillator, kein Brown out, kein 
LV-programming
  __CONFIG  _PWRTE_ON & _WDT_OFF & _XT_OSC & _BODEN_OFF & _LVP_OFF


;**************************************************************
; Variablen festlegen

w_copy    Equ  0x20  ; nur für INT
s_copy    Equ  0x21  ; nur für INT
p_copy    EQU  0x22  ; nur für INT

Flags    EQU  0x23
NrMessung  EQU  0x24  ; zählt die 64 Temperaturmessungen
Fehler    equ  0x25  ; Fehlerregister für Mathematik

count    equ  0x26  ; universeller zähler
loops    equ  0x27  ; timer für wait
loops2    equ  0x28  ; timer für wait

; Dezimalstellen
Digit    EQU  0x29
Ziffer1    EQU  0x2A
Ziffer2    EQU  0x2B
Ziffer3    EQU  0x2C
HdH    EQU  0x2D  ;3  Hunderter
HdZ    EQU  0x2E  ;2  Zehner
HdE    EQU  0x2F  ;1  Einer
HdX    EQU  0x30  ; Puffer für eine Dezimalstelle

;16 Bit Rechenregister
f0    equ  0x31  ;
f1    equ  0x32  ;
;16 Bit Rechenregister
xw0    equ  0x33  ;
xw1    equ  0x34  ;
;16 Bit Rechenregister
g0    equ  0x35  ;
g1    equ  0x36  ;

; Konstanten festlegen
#define Leading0  Flags,7
#define  Negativ    Flags,6  ; 1: Temperatur ist negativ


; der Wert offset dient zur Kalibrierung des Termometers
; der Standardwert ist 150 dezimal
; zeigt das Termometer eine um x° zu hohe Temperatur an, dann
; muss offset um x erhöht werden
;
; Beispiel:
; mit einem offset von 150 zeigt das Termometer eine um 4 °C
; zu hohe Temperatur an, dann ist offset auf 154 zu ändern.

#define  Offset    D'250'  ; Offset des PTC
#define Toff1           D'130'
#define Toff2           D'130'
#define Ton1            D'138'
#define Ton2            D'138'


Ini_con    Equ  B'00000000'  ; TMR0 -> Interupt disable
Ini_opt    Equ  B'10000011'  ; Timer0 int 16:1

;**************************************************************
  org  0
  goto  Init


;**************************************************************
; die Interuptserviceroutine

  org   4
intvec
  movwf  w_copy    ; w retten
  swapf  STATUS, w   ; STATUS retten
  clrf  STATUS
  movwf  s_copy    ;
  movf  PCLATH, W
  movwf  p_copy
  clrf  PCLATH    ; Bank 0

; Intrupt servic routine
Int_serv

  bsf  PORTC, 2  ; Ziffer1 aus
  bsf  PORTC, 1  ; Ziffer2 aus
  bsf  PORTC, 0  ; Ziffer3 aus

  decf  Digit,f    ; Ziffernzähler verringern

;Digit=2: anzeigen Ziffer 3    1er
;Digit=1: anzeigen Ziffer 2   10er
;Digit=0: anzeigen Ziffer 1  100er

  btfsc  STATUS, Z
  goto  Int_0    ; Z-Flag=1 ergo Digit=0
  decf  Digit, w
  btfsc  STATUS, Z
  goto  Int_1    ; Digit=1
  goto  Int_2    ; Digit=2

Int_0
  movfw  Ziffer1    ; Wert der 1. Ziffer (100er)
  call  Segmente
  movwf  PORTB    ; Segmente einschalten
  bcf  PORTC, 2  ; 1. Ziffer einschalten
  movlw  3
  movwf  Digit
  goto  Int_end

Int_1
  movfw  Ziffer2    ; Wert der 2. Ziffer (10er)
  call  Segmente
  movwf  PORTB    ; Segmente einschalten
  bcf  PORTC, 1  ; 2. Ziffer einschalten
  goto  Int_end

Int_2
  movfw  Ziffer3    ; Wert der 3. Ziffer (1er)
  call  Segmente
  movwf  PORTB    ; Segmente einschalten
  bcf  PORTC, 0  ; 3. Ziffer einschalten
  goto  Int_end

Int_end
  movf  p_copy, W
  movwf  PCLATH
  swapf  s_copy, w  ; STATUS zurück
  movwf  STATUS
  swapf  w_copy, f  ; w zurück mit flags
  swapf  w_copy, w

  bcf  INTCON, T0IF  ; Interupt-Flag löschen
  retfie

;**************************************************************
; 7-Segment-Tabelle

;*  PORTB:  0 Segment A     AAAAA
;*    1 Segment F    F     B
;*    2 Segment E    F     B
;*    3 Segment D     GGGGG
;*    4 Segment H    E     C
;*    5 Segment C    E     C
;*    6 Segment G     DDDDD  HH
;*    7 Segment B
;
Segmente
  addwf  PCL, f
;      76543210
;       BGCHDEFA
  retlw  B'01010000'  ; 0
  retlw  B'01011111'  ; 1
  retlw  B'00110010'  ; 2
  retlw  B'00010110'  ; 3
  retlw  B'00011101'  ; 4
  retlw  B'10010100'  ; 5
  retlw  B'10010000'  ; 6
  retlw  B'01011110'  ; 7
  retlw  B'00010000'  ; 8
  retlw  B'00010100'  ; 9
  retlw  B'11111111'  ; dunkel
  retlw  B'10111111'  ; -

;**************************************************************


;**************************************************************
; Das Programm beginnt mit der Initialisierung

Init  movlw  B'11111111'
  movwf  PORTB
  movwf  PORTC    ; LED aus
  bsf     STATUS, RP0  ; Bank 1
  movlw   Ini_opt       ; pull-up on
  movwf   OPTION_REG
  movlw  B'00000000'  ; PortB & C alle outputs
  movwf  TRISB
  movwf  TRISC
  bcf     STATUS, RP0  ; Bank 0
  movlw  B'11111111'
  movwf  PORTB
  movwf  PORTC    ; LED aus

  movlw   Ini_con       ; Interupt disable
  movwf   INTCON

  movlw  3
  movwf  Digit

  movlw  D'1'
  movwf  Ziffer1
  movlw  D'2'
  movwf  Ziffer2
  movlw  D'3'
  movwf  Ziffer3    ; Anzeige '321'

; ADC initialisieren
  ; ADC einschalten
  BSF  ADCON0, 0  ; ADON=1
  ; ADC-Eingang AN0 auswählen
  BCF  ADCON0, 5  ; ADCHS2=0
  BCF  ADCON0, 4  ; ADCHS1=0
  BCF  ADCON0, 3  ; ADCHS0=0
  ; ADC speed für 1,25 ... 5 MHz einstellen
  BCF  ADCON0, 7  ; ADCS1=0
  BSF  ADCON0, 6  ; ADCS0=1
  ; Daten rechtsbündig
  BSF  STATUS,RP0  ; Bank1
  clrf  ADCON1
  BSF  ADCON1, 7  ; ADFM=1
  BCF  STATUS,RP0  ; Bank0

; 244 Hz-Timer0-Interupt einstellen
  bsf     STATUS, RP0  ; auf Bank 1 umschalten
  movlw  B'10000011'  ; internen Takt zählen, Vorteiler zum Timer0, 16:1
        ; T0CS=0, PSA=0, PS=100, xx0x0100
  movwf  OPTION_REG
  movlw  D'0'    ; (1MHz : 16 ): 256= 244Hz
  bcf     STATUS, RP0  ; auf Bank 0 zurückschalten
  movwf  TMR0

  bcf  INTCON, T0IF
  bsf  INTCON, T0IE  ; Timer0 interupt erlauben
  bsf  INTCON, GIE  ; Interupt erlauben


;   1. Temperaturregister (16-Bit) auf 82 setzen (32+50)
;   2. 64 mal ADC abfragen, ADC-Wert jeweils zum Temperaturregister 
addieren (16 Bit Addition)
;   3. Temperaturregister durch 101 dividieren (16 Bit Division)
;   4. Vom Temperaturregister 150 subtrahieren (16 Bit Subtraktion)
;   5. Temperaturregister in BCD umrechen (3-stellig), Vorzeichen 
beachten


mainloop
  ; Startwert für korrektes Runden
  clrf  f1
  movlw  D'82'
  movwf  f0

  ; 64 Messungen
  movlw  D'64'
  movwf  NrMessung
Messung
  call  UMessen1  ; AN0 nach xw1,xw0
  call  Add16     ; 16-bit add: f = f + xw
  decfsz  NrMessung, f
  goto  Messung

  ; Division durch 101
  movlw  0x00    ; 101 = 00 65 h
  movwf  xw1
  movlw  0x65
  movwf  xw0
  call  Div16    ; Division f:= f / xw

  ; 150°C Offset entfernen
  bcf  Negativ    ; angenommen: positive Temperatur
  clrf  xw1
  movlw  Offset
  movwf  xw0
  call  Sub16    ; 16 bit f:=f-xw   calc=xw cnt=f;  neg=C
  btfss  STATUS, C
  goto  Positiv
  bsf  Negativ
  movfw  f0
  movwf  xw0
  movfw  f1
  movwf  xw1
  clrf  f1
  clrf  f0
  call  Sub16    ; 16 bit f:=f-xw   calc=xw cnt=f;  neg=C

Positiv
  call  Hex2Dez8  ; Umrechnung in BCD

  call  wait75ms
        call    Luft1
        call    Luft2
  goto  mainloop


;**************************************************************
; Spannung wandeln nach xw1, xw0
UMessen1
  clrf  count
aqui        ; 0,3 ms  ADC Aqusitionszeit nach Eingangswahl
  DECFSZ  count, f
  goto  aqui

  BSF  ADCON0, 2  ; ADC starten
loop
  BTFSC  ADCON0, 2  ; ist der ADC fertig?
  GOTO  loop    ; nein, weiter warten
  movfw  ADRESH    ; obere  2 Bit auslesen
  movwf  xw1    ; obere  2-Bit nach xw1
  bsf  STATUS,RP0  ; Bank1
  movfw  ADRESL    ; untere 8 Bit auslesen
  bcf  STATUS,RP0  ; Bank0
  movwf  xw0    ; untere 8-Bit nach xw0

  clrf  count    ; Warten, damit der ADC sich erholen kann
warten
  DECFSZ  count, f
  goto  warten
  return


;**************************************************************
;Warteroutinen verschiedener Länge ****************************

; 75 ms warten
wait75ms
  movlw  D'75'    ; 75ms
  movwf  loops
  goto  WAIT

;**************************************************************
;Zeitverzögerung um loops * 1 ms
; 4 MHz externer Takt bedeutet 1 MHz interner Takt
; also dauert 1 ms genau 1000 Befehle
; 100 Schleifen a 10 Befehle sind 1000 Befehle = 1 ms

WAIT
top     movlw   .100           ; 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



;**************************************************************
;+++Mathematik-Routinen ***************************************

;**************************************************************
; 16 Bit Subtraktion, bei Überlauf (neg. Ergebnis) ist C gesetzt
Sub16        ; 16 bit f:=f-xw   calc=xw cnt=f
  clrf  Fehler    ; extraflags löschen
  movf    xw0, w    ; f0=f0-xw0
  subwf   f0, f
  btfsc   STATUS,C
  goto    Sub16A
  movlw   0x01    ; borgen von f1
  subwf   f1, f
  btfss   STATUS,C
  bsf  Fehler, C  ; unterlauf
Sub16A
  movf    xw1,w    ; f1=f1-xw1
        subwf   f1    , f
        btfss   STATUS, C
   bsf  Fehler, C  ; Unterlauf
  bcf  STATUS, C
  btfsc  Fehler, C
  bsf  STATUS, C
  return

;**************************************************************
;16 bit Adition, C-Flag bei Überlauf gesetzt
Add16         ; 16-bit add: f = f + xw
  movf  xw0,W    ; low byte
  addwf  f0,F     ; low byte add

  movf  xw1,W     ; next byte
  btfsc  STATUS,C   ; skip to simple add if C was reset
  incfsz  xw1,W     ; add C if it was set
  addwf  f1,F     ; high byte add if NZ

  return       ; finished


;**************************************************************
;primitive 16 bit Division   f:= f / xw
Div16
  clrf  g0
  decf  g0, f
  clrf  g1
  decf  g1, f
Div16Loop
  incf  g0, f
  btfsc  STATUS, Z
  incf  g1, f
  call  Sub16    ;
  btfss  STATUS, C  ;Überlauf
  goto  Div16Loop  ;Stelle 1 mehr
  movfw  g0
  movwf  f0
  movfw  g1
  movwf  f1
  return


;**************************************************************
; 8 Bit Wert w auf LED 3-stellig dezimal anzeigen

;              100 = 0064 h
;               10 = 000A h
;                1 = 0001 h

Hex2Dez8      ; 8-bit (f1, f0) in 3-stellen BCD
  bsf  Leading0
  movlw  0x00    ; 100 = 00 64 h
  movwf  xw1
  movlw  0x64
  movwf  xw0
  call  Hex2Dez1  ; 100er
  movfw  HdX
  btfsc  Negativ
  movlw  D'11'    ;'-'
  movwf  HdH
  movwf  Ziffer1

  movlw  0x00    ; 10 = 00 0A h
  movwf  xw1
  movlw  0x0A
  movwf  xw0
  call  Hex2Dez1  ; 10er
  movfw  HdX
  movwf  HdZ
  movwf  Ziffer2

  movfw  f0
  movwf  HdE
  movwf  Ziffer3
  return

Hex2Dez1
  clrf  HdX
  decf  HdX, f
HdLoop
  incf  HdX, f
  call  Sub16    ;
  btfss  STATUS, C  ;Überlauf
  goto  HdLoop    ;Stelle 1 mehr
  call  Add16

  ; falls führende 0 dann Wert=D'10'
  movfw  HdX
  btfss  STATUS, Z
  bcf  Leading0
  btfss  Leading0
  return
  movlw  D'10'
  movwf  HdX
  return

;**************************************************************
; Lüfter ein/aus-schalten

Luft1
  ; prüfen ob Temp<Toff
  MOVFW  Toff1
  subwf  Digit, w    ; w:=f-33 = temp-Toff
  btfss  STATUS, C
  bcf  PORTC, 5    ; Lüfter aus
  ; prüfen ob Temp>Ton
  MOVFW  Ton1
  subwf  Digit, w    ; w:=f-38 = temp-Ton
  btfsc  STATUS, C
  bsf  PORTC, 5    ; Lüfter an
  return

Luft2
  ; prüfen ob Temp<Toff
  MOVFW  Toff2
  subwf  Digit, w    ; w:=f-w = temp-Toff
  btfss  STATUS, C
  bcf  PORTC, 4    ; Lüfter aus
  ; prüfen ob Temp>Ton
  MOVFW  Ton2
  subwf  Digit, w    ; w:=f-w = temp-Ton
  btfsc  STATUS, C
  bsf  PORTC, 4    ; Lüfter an
  return

  end

von Severino R. (severino)


Lesenswert?

Forumsregel:
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Hast Du den Code mal im Simulator single-gesteppt?

von Bodo (Gast)


Lesenswert?

Ich weiß nicht was Du für einen Simulator meinst. Wo gibt es so was?

von Severino R. (severino)


Lesenswert?

Bodo wrote:
> Ich weiß nicht was Du für einen Simulator meinst. Wo gibt es so was?

Unter den Annahme, dass Du Microchips MPLAB verwendest:
Debugger -> Select Tool -> MPLAB SIM

von Bodo (Gast)


Lesenswert?

Ja ich habe MPLAB aber mit meine englisch ist es nicht so gut bestellt.
Komme damit nicht zurecht. Kennst du vieleicht eine Sim aud deutsch oder 
gibt es eine Anleitung in deutsch für MPLAB?

Danke

von Michael (Gast)


Lesenswert?

Schau mal auf der Seite http://www.fernando-heitor.de unter 
Downloads-Dokumente nach. Da gibt es ein Tutorial zu MPLAB auf deutsch, 
vielleicht hilft es dir ;)

von Bodo (Gast)


Lesenswert?

Hallo

Ich finde meinen Denkfehler nicht vielleicht hat ja einer von euch 
Profis mir helfen. Zumindest einen Tipp ich möchte es ja auch lernen, 
damit ich nicht immer fragen muss. Geht mir ja auch auf die nerven.

Ich bin über jede Anregung dankbar. MFG Bodo K.

von Peter D. (peda)


Lesenswert?

Bodo wrote:
> Ich finde meinen Denkfehler nicht vielleicht hat ja einer von euch
> Profis mir helfen.

Ob jemand Profi ist, hat damit nichts zu tun.
Du bräuchtest jemanden, der PIC-Asssembler kann und da siehts hier im 
Forum ziemlich mau aus.
Hier sind hauptsächlich AVR-ler unterwegs.


Und Postingregel 2 beachten:
"Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang"


Peter

von Severino R. (severino)


Lesenswert?

Bodo wrote:
> Hallo
>
> Ich finde meinen Denkfehler nicht vielleicht hat ja einer von euch
> Profis mir helfen. Zumindest einen Tipp ich möchte es ja auch lernen,
> damit ich nicht immer fragen muss. Geht mir ja auch auf die nerven.

Wie weit bist Du mit dem Simulator?

Und schau mal nach was MOVFW und MOVLW bewirken resp. was der 
Unterschied ist.

von Chris (Gast)


Lesenswert?

Der Denkfehler ist ganz einfach, du verwendest die Variable Digit,
welche das aktuelle Display fuer das Multiplexing der 7-seg Anzeigen
enthaelt (Werte 0-2) und nicht die Temperatur. !!!

Chris

von Bodo (Gast)


Lesenswert?

Hi das ist mir auch schon aufgefallen. Das da mein Fehler ist habe das 
in f0 geändert.(Ich glaube das das die aktuelle errechnete Temp ist) bin 
mir aber nicht sicher das der wert beim Sprung noch da ist.

von Chris (Gast)


Lesenswert?

Ja, der Wert ist in f0 sowie f1, ein 16bit Wert.
du solltest Sub16 benutzen, und vorher den Schwellwert in xw0 sowie xw1 
laden. Wenn das Carry gesetzt ist, ist der Wert unterschritten, 
andersweitig ist die Temperatur hoeher oder gleich.

**************************************************************
; 16 Bit Subtraktion, bei Überlauf (neg. Ergebnis) ist C gesetzt
Sub16        ; 16 bit f:=f-xw   calc=xw cnt=f
  clrf  Fehler    ; extraflags löschen
  movf    xw0, w    ; f0=f0-xw0
  subwf   f0, f
  btfsc   STATUS,C
  goto    Sub16A
  movlw   0x01    ; borgen von f1
  subwf   f1, f
  btfss   STATUS,C
  bsf  Fehler, C  ; unterlauf
Sub16A
  movf    xw1,w    ; f1=f1-xw1
        subwf   f1    , f
        btfss   STATUS, C
   bsf  Fehler, C  ; Unterlauf
  bcf  STATUS, C
  btfsc  Fehler, C
  bsf  STATUS, C
  return

von Bodo (Gast)


Lesenswert?

Hallo



Zur Verständnis.

Wenn der Wert des einschalt punkt überschritten ist wird ein Flag 
gesetzt auf 1.

Aber wie frage ich den Flags ab? Ich glaube das das die Zeile ist mit 
btfss  STATUS, C.

Aber muss ich nicht noch irgendwo definieren welcher Flags für was ist?

Wie binde ich das in mein Programm ein?

Das mit dem Sub 16 und Sub 16A habe ich ja in meinem Programm schon 
drin.

Ich sagte ja schon, bin ein Newbie sorry.

Danke für eure mühe

von Sven S. (stepp64) Benutzerseite


Lesenswert?

Bodo wrote:
> Hallo
>
>
>
> Zur Verständnis.
>
> Wenn der Wert des einschalt punkt überschritten ist wird ein Flag
> gesetzt auf 1.
>
> Aber wie frage ich den Flags ab? Ich glaube das das die Zeile ist mit
> btfss  STATUS, C.

Richtig. Die Flags stehen im Statusregister und werden mit btfss ( Bit 
testen im Speicher (f) und skip wenn Bit gesetzt) oder btfsc (Das selbe, 
halt nur wenn bit nicht gesetzt) abgefragt.
>
> Aber muss ich nicht noch irgendwo definieren welcher Flags für was ist?
>
Nein, steht im Datenblatt.

> Wie binde ich das in mein Programm ein?
Die Status Flag werden bei jedem Befehl, den die CPU ausführt durch die 
CPU gesetzt. Welche Flags wie und bei welchem Befehl gesetzt werden 
erfährst du auch im Datenblatt (bei der Befehlsübersicht). Im 
wesentlichen brauchst du aber nur zwei Flags. C (wenn ein Byte 
überläuft, nach einer Addition, Subtraktion oder Verschiebebefehle) und 
Z (wenn das Ergebnis 0 ist).

>
> Das mit dem Sub 16 und Sub 16A habe ich ja in meinem Programm schon
> drin.
>
> Ich sagte ja schon, bin ein Newbie sorry.

Dann ließ mal sprut.de durch. Da erfährst du ganz gut die Grundlagen.

>
> Danke für eure mühe
Gerne. Sven

von Bodo (Gast)


Lesenswert?

Hallo

Also ich bekomme es einfach nicht hin.
Ich habe mir alles mögliche durchgelesen, finde meinen Fehler nicht.

Wer kann mir BITTE ganz konkret meinen Denkfehler sagen?

Mfg Bodo und DANKE im voraus.

von Bodo (Gast)


Lesenswert?

Hallo

Also ich bin der meinung das der Flags Carry immer 1 ist.

Da mein Ausgang immer High ist, egal was ich für eine Temp habe.

Also ist f0 nicht da. zB 0 für aktuelle Temp. - 38Grad für Toff1 = -38

Flegs 1 also Ausgang immer da. Selbst wenn ich 110 Grad am Fühler habe 
ändert sich nichts am Ausgang immer High.

HILFE Danke

Gruß Bodo

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.