PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Code zum Messwert verdreifachen/ pwm ein/aus-schalten ?



PsiQ
06.02.2007, 00:23
Hallo Leute:
Anfang:
Port RA0 bekommt poti (10k) wert von 0-5V
daraus wird pwm tastverhältnis von 0-100%

Jetzt habe ich das ganze modifiziert für ein poti, was 0-500Ohm hat (sitzheizungsreglerpoti,nicht austauschbar wegen optik),
also habe ich einen 1k widerstand dazugesetzt, damit der stromfluß durchs poti nicht so hoch wird. (5v:1000ohm=0,005A= maximal 5mA =>maximal 0,025Watt)
(Zur Ergänzung: das Poti hat keinen mittenabgriff,nur 2 kontakte)

[+5v]
I
I
[R=1k]
I
I---------------[R=1k]----RA0/IC Eingang
I
[Poti,0-500Ohm]
I
I
[GND]

Ich gebe also per poti einen wert an RA0 ein, der maximal 1/3 von 5V ist
(spannungsteiler), minimal 0V.

Um das gleiche ergebnis zu haben, muß ich den wert also verdreifachen

Ist der Code so korrekt, dass er den Wert ausliest,
dann 2 mal mit dem selben wert addiert, und dann weitergibt ans PWM ?
-Damit soll er wieder die maximalen 5V=100% PWM machen
Code:


;Eingangsspannung wandeln
BSF ADCON0, 2 ; ADC starten
loop2
BTFSC ADCON0, 2 ; ist der ADC fertig?
GOTO loop2 ; nein, weiter warten

;Eingangsspannung in work laden
movfw ADRESH ; wert auslesen
addwf ADRESH,0 ; wert verdoppelt, in work speichern
addwf ADRESH,0 ; wert verdreifacht, in work gespeichert

; Wert an PWM2 übergeben
MOVWF CCPR2L ; obere 8 Bit sind PWM


Passt das so?
Multiplizieren direkt geht ja net..
Hoffe ich hab das richtig zusammengebaut..
(funkioniert!)
Dankeschön!
Gute Woche noch!

#########################################

EDIT:
Versuch macht kluch!
also das verdreifachen scheint zu funktionieren.. nur leider passiert genau meine befürchtung:
geht damit über 5V raus, und wieder auf knapp über 0V -was nun ?
irgendwas mit dem flag.. hm mal schaun..
(erledigt)
edit2: so wieder 40minuten später..ich denke ich habs hingekriegt..
erst hat der assembler rumgemault, weil ich Status statt STATUS geschrieben hatte.. da sucht man ewig.. ](*,)

Code ist jetzt:



;Eingangsspannung wandeln
BSF ADCON0, 2 ; ADC starten
loop2
BTFSC ADCON0, 2 ; ist der ADC fertig?
GOTO loop2 ; nein, weiter warten

;Eingangsspannung in work laden
BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen
addwf ADRESH,0 ; wert verdoppelt
addwf ADRESH,0 ; wert verdreifacht
btfsc STATUS,C ; wenn carry flag gesetzt,
movlw D'255' ; dann: wert auf maximum setzen=255=5V=100%
; sonst normal weiter
; Wert an PWM2 übergeben
MOVWF CCPR2L ; obere 8 Bit sind PWM


damit sollte die toleranz erschlagen sein, so kann ich ja bis 2,5V einlesen, ohne das es wieder auf 0% pwm geht.

hmm..
Schön wenn man was selber hinkriegt. O:)
################################################

Zurück zum anderen "Problem"
-wie kann ich denn bei Endwerten von sagen wer mal 230 bis 255 auf dauer "high" setzen, ohne pwm? Damit die Verlustleistung am mosfet durchs schalten wegfällt? (immer an)

-wie geht das bei Endwerten von 0-25, dass er ganz abschaltet = dauernd low, ohne pwm..? (immer aus)

Danke fürs zuhören :-b
wopps-jetzt aber ab ins Bettchen.. :-#

Benji
06.02.2007, 07:41
Zurück zum anderen "Problem"
-wie kann ich denn bei Endwerten von sagen wer mal 230 bis 255 auf dauer "high" setzen, ohne pwm? Damit die Verlustleistung am mosfet durchs schalten wegfällt? (immer an)

-wie geht das bei Endwerten von 0-25, dass er ganz abschaltet = dauernd low, ohne pwm..? (immer aus)

Kannst ja eine Prüfroutine unterbringen. Diese prüft den Wert ADRESH...
ADRESH > 230?
Ja: ADRESH = 255 oder direkt CCPR2L = 255
Nein: ADRESH = ADRESH (oder NOP)

ADRESH < 25?
Ja: ADRESH = 0 oder direkt CCPR2L = 0
Nein: ADRESH = ADRESH (oder NOP)

MfG Benji

PsiQ
06.02.2007, 13:23
öm..
und wie sähe das in assembler aus?

-carryflag auf 0 setzen
-adresh wert verdreifachen
-auf überlauf achten , wenn überlauf wert auf 255 setzen

-carryflag auf 1 setzen
-wert zwischenspeichern
-von wert 241abziehen
-carryflag bleibt=1 also zahl größer als240,
dann pwm ausschalten, port high

sonst carryflag=0, also weiter im normalen programm


das gleich nochmal andersrum für den unteren wert
..hmmm.. wärs da nicht besser erst 8 vom original Wert abzuziehen,
und wenns dann kleiner null ist, das ding abschalten, und dafür die obere vollast spanne um 10 vergrößern..
hm.. doch das wäre besser.. schau ich gleich mal nachm essen..
uh, kom-pilli-ziert ..
und irgendwie doppelt gemoppelt.. :-k

Benji
06.02.2007, 14:00
Mit welchem PIC arbeitest du?

Suche einmal nach "cpfsgt" und "cpfslt"... Diese vergleichen ein Register mit dem WREG. (grösser- und kleiner als). Je nach dem überspringen sie die nächse Operation oder eben nicht.

Ich bin mir jetzt nicht sicher, aber ich glaube diese Funktionen gibt es erst ab PIC18F...

MfG Benji

PsiQ
06.02.2007, 14:12
PIC16F876A 8-[

Benji
06.02.2007, 14:36
Nun ich habe nachgesehen. Die beschriebenen Funktionen sind erst bei PIC18F zu finden. Dann ist deine Lösung sicher nicht schlecht.

PsiQ
06.02.2007, 15:29
achso: ja ich hab den befehl auch nicht gefunden)

da nag ich grad noch dran rum an dem rumrechnen..
3. anlauf wieder verbessert ;-)..

ABER:
darf ich ADRESH überschreiben, bzw geht das?

mit dem ADC setze ich ja den messwert in ADRESH
den lese ich aus, und im normalen programm addiere ich den 2mal mit sich selbst, und hab somit die reale einstellung vom poti

kann ich ADRESH auf 0 setzen:

clrf ADRESH ;auf 0 setzen

um den port im normalen programm auf 0 zu setzen,
(wäre dann 0 + 0 + 0 = 0)
oder überschreibt das der adc sofort wieder ?
(läuft der noch und schreib in ADRESH oder läuft der nichtmehr)

ich mach mal den code vollns wie ichs denke (wenn das adresh = 0 setzen geht), aber mein hirn dreht schon knoten.. ](*,)

PsiQ
06.02.2007, 15:35
Sooo
wenn man adresh mit 0 überschreiben kann/darf, müsste das ganze so gehen..



; Wert auslesen und schreiben
; #### Nebenrechung

;Der Wert von ADRESH wird ausgelesen, wenn er kleiner 15 ist, soll der Ausgang ausgeschaltet bleiben
;dazu wird das carryflag abgefragt: wenn der messwert +240 das flag setzt,bedeutet das, er ist größer/gleich 15,
;also wird normal weitergemacht, wenn die flag nicht gesetzt wird, ist der wert kleiner 15, und der pwm ausgang soll "aus" bleiben
;dafür wird dann adresh 0 gesetzt,somit wird im folgenden code 0 + 0 + 0 = 0 und der port auf 0 gesetzt.

BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen, in work setzen
addlw D'240' ; 240 mit work addieren,
btfss STATUS,C ; carryflag gesetzt durch addition?
clrf ADRESH ; dann wird der befehl übergangen, da wert größer 15 (sonst adresh=0 => PWM=ausschalten da wert zu klein)
; sonst normal weiter
; #### Nebenrechnung Ende
BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen (0 oder messwert), in work setzen
addwf ADRESH,0 ; wert verdoppelt
addwf ADRESH,0 ; wert verdreifacht
btfsc STATUS,C ; wenn carry flag gesetzt,
movlw D'255' ; dann: wert auf maximum setzen=255=5V


; Wert an PWM1 übergeben
MOVWF CCPR1L ; obere 8 Bit sind PWM

korrekt?

Danke fürs betreuen soweit O:)


Edit:

Soweit scheints in echt zu funktionieren...

(Erledigt)

Das abschalten nach unten (0% Tastverhältnis) ist damit egal, das hat ja sowieso keinen wärmeverlust.. (Erledigt)

Aber wie setz ich das beim oberen Wert auf dauer high..
hmpf?

2 Lösungen:
Software:
PWM deaktivieren, port auf high setzen

Grobmechanisch:
Anderen Pin an PortB bei gewünschter schwelle auf "high" setzen, damit den mosfet-pin mit vorwiderstand (20mA) und diode dauernd auf high (4,7V wegen sperrdiode) ziehen.. dann ist egal was der pwm pin-port macht..
wenn der portB-Pin low ist verhindert die diode dass der mosfet darüber entladen wird..
allerdings ist das nicht gerade schonend für den PIC.. hmmm

ich frag das glaub nochmal neu, hier ists ja schon ziemlich unübersichtlich..

Benji
06.02.2007, 19:22
Es kommt jetzt draufan was du für PWM Einstellungen gemacht hast. (Frequenz)

Man kann sagen: Duty Cycle = CCPR1L / PR2

Wenn die Frequenz "egal" ist stellst du am besten so ein:
PR2 = 255
CCPR1L = ADRESH

Nützlich zum Nachlesen betreffend PWM:
http://www.sprut.de/electronic/pic/grund/pwm.htm

PsiQ
06.02.2007, 20:32
äm.. die frequenz sind ca 720Hz, niedriger geht mit 10Mhz laut sprut auch net.

ich will ja auch 2 voneinander unabhängige pwm machen
kann das teil also net komplett ausschalten wenns eine vollast ist und das andere 50%..
öm

ja..

code mit intro:


;================================================= =========================
;
; Configuration
;
;================================================= =========================


__CONFIG _CP_OFF & _DEBUG_OFF & _LVP_OFF & _WRT_OFF & _PWRTE_ON & _WDT_OFF & _BODEN_OFF & _HS_OSC



;================================================= =========================
;
; Variable Definition
;
;================================================= =========================

wait EQU 0x20
loops2 EQU 0x22
summe EQU 0x21

; Anfangsinitialisierung

init
; PWM vorbereiten
; Vorteiler 16:1 und Timer2 einschalten
BSF T2CON,T2CKPS1 ; Vorteiler 16:1
BSF T2CON,TMR2ON ; Timer2 ein

; Frequenz auf ~700 Hz einstellen
BSF STATUS,RP0 ; Bank1
MOVLW D'255' ;
MOVWF PR2 ; ~700 Hz
BCF STATUS,RP0 ; Bank1

; Tastverhältnis auf 0% einstellen
MOVLW D'0'
MOVWF CCPR1L ; 0%
MOVLW D'0'
MOVWF CCPR2L ; 0%

; RC2/CCP1 und RC1/CCP2 auf Ausgang stellen
BSF STATUS,RP0 ; Bank1
BCF TRISC, 2 ; RC2: output=0
BCF TRISC, 1 ; RC1: output=0
BCF STATUS,RP0 ; Bank 0

; PWM MODE mit CCP1 initialisieren
CLRF CCP1CON ; CCP1-Modus aus
BSF CCP1CON,CCP1M3 ; CCP1-Modus PWM-Mode
BSF CCP1CON,CCP1M2 ;

; PWM MODE mit CCP2 initialisieren
CLRF CCP2CON ; CCP2-Modus aus
BSF CCP2CON,CCP2M3 ; CCP2-Modus PWM-Mode
BSF CCP2CON,CCP2M2 ;

; ADC vorbereiten
; PortB vorbereiten
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'00000000' ; PortB alle output
movwf TRISB
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
clrf PORTB ; alle LEDs ausschalten

; ADC einschalten
BSF ADCON0, 0 ; ADON=1

; ADC speed für 20 MHz einstellen
BSF ADCON0, 7 ; ADCS1=1
BCF ADCON0, 6 ; ADCS0=0

; Daten linksbündig
BSF STATUS,RP0 ; Bank1
BCF ADCON1, 7 ; ADFM=0
BCF STATUS,RP0 ; Bank0


;************************************************* *********
; Hauptprogrammschleife

Main
; Ablauf für 1.PWM ausgang
; ADC-Eingang AN0 auswählen
BCF ADCON0, 5 ; ADCHS2=0
BCF ADCON0, 4 ; ADCHS1=0
BCF ADCON0, 3 ; ADCHS0=0

;Pause zum ADC aufladen?
;************************************************* *********
; Warteschleife 1 ms für einen 10MHz-PIC-Takt
Wai
movlw .249 ; Zeitkonstante für 1ms
movwf loops2

Wai2 nop
nop
nop
nop
nop
nop
nop
decfsz loops2, F ; 1 ms vorbei?
goto Wai2 ; nein, noch nicht



;Eingangsspannung wandeln
BSF ADCON0, 2 ; ADC starten
loop
BTFSC ADCON0, 2 ; ist der ADC fertig?
GOTO loop ; nein, weiter warten

; Wert auslesen und schreiben
; #### Nebenrechung

;Der Wert von ADRESH wird ausgelesen, wenn er kleiner 15 ist, soll der Ausgang ausgeschaltet bleiben
;dazu wird das carryflag abgefragt: wenn der messwert +240 das flag setzt,bedeutet das, er ist größer/gleich 15,
;also wird normal weitergemacht, wenn die flag nicht gesetzt wird, ist der wert kleiner 15, und der pwm ausgang soll "aus" bleiben
;dafür wird dann adresh 0 gesetzt,somit wird im folgenden code 0 + 0 + 0 = 0 und der port auf 0 gesetzt.

BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen, in work setzen
addlw D'240' ; 240 mit work addieren,
btfss STATUS,C ; carryflag gesetzt durch addition?
clrf ADRESH ; dann wird der befehl übergangen, da wert größer 15 (sonst adresh=0 => PWM=ausschalten da wert zu klein)
; sonst normal weiter
; #### Nebenrechnung Ende
BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen (0 oder messwert), in work setzen
addwf ADRESH,0 ; wert verdoppelt
addwf ADRESH,0 ; wert verdreifacht
btfsc STATUS,C ; wenn carry flag gesetzt,
movlw D'255' ; dann: wert auf maximum setzen=255=5V
movwf PORTB ; sonst: normal weiter, obere 8 Bit nach PortB schreiben

; Wert an PWM1 übergeben
MOVWF CCPR1L ; obere 8 Bit sind PWM

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

; Ablauf für 2.PWM ausgang
usw...


vielleicht hilfts dir was..
ich weiß net wirklich wie oder was ich da modifizieren könnte..

Benji
06.02.2007, 21:00
doch...!

Nachdem du ADRESH bearbeitet hast, (verdreifachen usw.) hast du ja den gewünschten Wert. Wenn grösser als 240, dann 255 oder so ähnlich.

Nachher musst du ja nur noch den Wert von ADRESH in CCPR1L übertragen und das wars.

Nicht:
MOVWF CCPR1L ; obere 8 Bit sind PWM

Sondern:
movf ADRESH, W
movwf CCPR1L

PsiQ
06.02.2007, 23:10
äm, moment:
ich lese eine spannung ein die maximal 1/3 von 5V ist, deswegen muß ich den wert verdreifachen..

wenn das verdreifachen nen überlauf gibt (carry flag gesetzt wird) heißt das ja einfach nur, dass ich zb 5,1V habe, wegen dem verdreifachen,
und damit dann der wert nicht wieder auf 0,1V fällt lese ich das carry flag aus, das sagt mir der wert ist über 5V, also vollast.

Der wert in ADRESH !bleibt! aber ca 1/3 von 5V (der original messwert)
deswegen muß ich den 3fachen wert aus !work! ins ccp-dingens laden (adresh wird nicht geschrieben nur gelesen),

Wenn ich adresh übertragen würde, wäre es maximal 1/3, aber nicht vollast..

das flag soll nur den überlauf auffangen, nicht die vollast schalten..

das klappt ja alles, aber das ist immernoch eine taktung ein aus ein aus ein aus, also weiterhin schaltverluste.

jetzt möchte ich aber dass von 4,9 bis 5,1V (überlauf) immer
vollast= dauer high
ist, ohne aus ein aus ein, also muß doch das pwm modul deaktiviert werden, damit ich keine schaltverluste mehr habe..
das würde das ganze von maximal 10Watt verlust auf <2W Verlust runtersetzen, also deutlich Wärme sparen..

hmmm

jetzt klar was ich meinte ? (ich weiß net wie ichs anders sagen soll)
Das Problem ist nicht die 4,9 bis 5,1V zu erkennen und zu nutzen, das bekomme ich irgendwie hin, nur den pin umzuschalten auf dauer ein, das klappt net.

Vollast hab ich von 5,0V bis 9,9V =100% PWM (berechnete spannung 9,9V,gemessen=3,3V) (bei 10V doppelte überlauf => Flag wieder=0)

ich hätte aber gerne den ausgangspin "high" von 4,9 bis 9,9V, ohne pwm, taktung oder frequenz..


ist doof zum sagen, und in assembler noch blöder, saß an dem bisherigen verdreifachen etc auch heute einige Stunden dran..

-evtl läufts doch auf nen zusatz-digital-pin raus

hmpf

Danke Trotzdem

PsiQ
06.02.2007, 23:20
doch...!

Nachdem du ADRESH bearbeitet hast, (verdreifachen usw.) hast du ja den gewünschten Wert. Wenn grösser als 240, dann 255 oder so ähnlich.

Nachher musst du ja nur noch den Wert von ADRESH in CCPR1L übertragen und das wars.

Nicht:
MOVWF CCPR1L ; obere 8 Bit sind PWM

Sondern:
movfw ADRESH
movwf CCPR1L

Am Ende von dem Code-Teil: Nehmen wer mal an messwert = 1,7V (also ca 1/3 von 5V)

also ist ADRESH = 1,7V
Work ist 3x1,7V = 5,1V
die 5,1V werden vom flag erkannt und WORK wird auf 5V = 100% Tastverhältnis=Vollast gesetzt

ADRESH ist immernoch = 1,7V
WORK ist 5,0V
Dann wird WORK=5V nach CCPR1L geschrieben,
und somit das modul auf 100% gesetzt. (immernoch getaktet)


wenn ich stattdessen wie du vorschlägst
adresh nach work,
und dann
work nach CCPR1L schreiben würde, hätte ich nur 33%


hmmm?

hm!

Gut Nacht!

vielleicht fällt mir ja noch was geniales ein.. aber dazu weiß ich zuwenig über den pic


(den Befehl "movf Adresh, W" gibts doch garnicht, verschrieben?
der befehl würde doch lauten (laut sprut)
ADRESH in WORK laden:
movf ADRESH,0
oder
movfw ADRESH )

phaidros
07.02.2007, 00:04
Was für einen Assembler benutzt du denn?
Fast alle Assembler, die ich kenne, kommen mit der Syntax
movf ADRESH,w
klar.
Das ist doch auch viel deutlicher als ..,0 zu schreiben.
Besonders sinnvoll ist diese Notation, wenn man sowohl ins W-Register als auch in irgendein anderes Register (file) schreiben kann:

addwf ADRESH,w
oder
addwf ADRESH,f

Einmal wird das Ergebnis in W geschrieben, ein andernmal in ADRESH.

Alles viel einfacher zu lesen als 0 oder 1.

Gruß
Phaidros

PsiQ
07.02.2007, 00:14
ich sag nicht mein assembler kanns nicht,
habs ehrlich gesagt net probiert ;-) ,habs nur net bei sprut gesehen

die anderen gehen ja auch
..heute hab ich in MPlab-ide getippt..und mit mpasmwin assembliert
hab ja jetzt drei gleichwertige befehle zur auswahl..

aaaaber , das bringt mich der Lösung nicht näher O:)

ich find
movfw schon übersichtlich move f=dingensbumens nach w=work

und movwf move w=work nach f=dingensbumens ..
ich hab ja nicht gesagt ich schreibs mit d=0 oder 1 ..
nur dass das bei sprut so steht.. :-b

phaidros
07.02.2007, 00:15
Zu deinem eigentlichen Problem:
Das PWM-Modul hat zwei Parameter: Duty-Cycle und Periode. Mit dem Wert von CCPR1 stellst du den Duty-Cycle ein. Wenn der größer ist als die Periode (bestimmt durch PR2), bleibt der Pin immer auf High!
Poste doch mal den kompletten PWM-Code.
Gruß
Phaidros

PsiQ
07.02.2007, 00:21
aaaah, ooooh, echt?

ich hab da noch net wirklich ahnung von :-b

der komplette code (ab config) wie er jetzt im ic steckt (und läuft):



;================================================= =========================
;
; Configuration
;
;================================================= =========================


__CONFIG _CP_OFF & _DEBUG_OFF & _LVP_OFF & _WRT_OFF & _PWRTE_ON & _WDT_OFF & _BODEN_OFF & _HS_OSC



;================================================= =========================
;
; Variable Definition
;
;================================================= =========================

wait EQU 0x20
loops2 EQU 0x22
summe EQU 0x21

; Anfangsinitialisierung

init
; PWM vorbereiten
; Vorteiler 16:1 und Timer2 einschalten
BSF T2CON,T2CKPS1 ; Vorteiler 16:1
BSF T2CON,TMR2ON ; Timer2 ein

; Frequenz auf ca 700Hz einstellen
BSF STATUS,RP0 ; Bank1
MOVLW D'255' ;
MOVWF PR2 ; ca 700 Hz
BCF STATUS,RP0 ; Bank1

; Tastverhältnis auf 0% einstellen
MOVLW D'0'
MOVWF CCPR1L ; 0%
MOVLW D'0'
MOVWF CCPR2L ; 0%

; RC2/CCP1 und RC1/CCP2 auf Ausgang stellen
BSF STATUS,RP0 ; Bank1
BCF TRISC, 2 ; RC2: output=0
BCF TRISC, 1 ; RC1: output=0
BCF STATUS,RP0 ; Bank 0

; PWM MODE mit CCP1 initialisieren
CLRF CCP1CON ; CCP1-Modus aus
BSF CCP1CON,CCP1M3 ; CCP1-Modus PWM-Mode
BSF CCP1CON,CCP1M2 ;

; PWM MODE mit CCP2 initialisieren
CLRF CCP2CON ; CCP2-Modus aus
BSF CCP2CON,CCP2M3 ; CCP2-Modus PWM-Mode
BSF CCP2CON,CCP2M2 ;

; ADC vorbereiten
; PortB vorbereiten
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'00000000' ; PortB alle output
movwf TRISB
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
clrf PORTB ; alle LEDs ausschalten

; ADC einschalten
BSF ADCON0, 0 ; ADON=1

; ADC speed für 20 MHz einstellen
BSF ADCON0, 7 ; ADCS1=1
BCF ADCON0, 6 ; ADCS0=0

; Daten linksbündig
BSF STATUS,RP0 ; Bank1
BCF ADCON1, 7 ; ADFM=0
BCF STATUS,RP0 ; Bank0


;************************************************* *********
; Hauptprogrammschleife

Main
; Ablauf für 1.PWM ausgang
; ADC-Eingang AN0 auswählen
BCF ADCON0, 5 ; ADCHS2=0
BCF ADCON0, 4 ; ADCHS1=0
BCF ADCON0, 3 ; ADCHS0=0

;Pause zum ADC aufladen?
;************************************************* *********
; Warteschleife 1 ms für einen 10MHz-PIC-Takt
Wai
movlw .249 ; Zeitkonstante für 1ms
movwf loops2

Wai2 nop
nop
nop
nop
nop
nop
nop
decfsz loops2, F ; 1 ms vorbei?
goto Wai2 ; nein, noch nicht



;Eingangsspannung wandeln
BSF ADCON0, 2 ; ADC starten
loop
BTFSC ADCON0, 2 ; ist der ADC fertig?
GOTO loop ; nein, weiter warten

; Wert auslesen und schreiben
; #### Nebenrechung

;Der Wert von ADRESH wird ausgelesen, wenn er kleiner 15 ist, soll der Ausgang ausgeschaltet bleiben
;dazu wird das carryflag abgefragt: wenn der messwert +240 das flag setzt,bedeutet das, er ist größer/gleich 15,
;also wird normal weitergemacht, wenn die flag nicht gesetzt wird, ist der wert kleiner 15, und der pwm ausgang soll "aus" bleiben
;dafür wird dann adresh 0 gesetzt,somit wird im folgenden code 0 + 0 + 0 = 0 und der port auf 0 gesetzt.

BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen, in work setzen
addlw D'240' ; 240 mit work addieren,
btfss STATUS,C ; carryflag gesetzt durch addition?
clrf ADRESH ; dann wird der befehl übergangen, da wert größer 15 (sonst adresh=0 => PWM=ausschalten da wert zu klein)
; sonst normal weiter
; #### Nebenrechnung Ende
BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen (0 oder messwert), in work setzen
addwf ADRESH,0 ; wert verdoppelt
addwf ADRESH,0 ; wert verdreifacht
btfsc STATUS,C ; wenn carry flag gesetzt,
movlw D'255' ; dann: wert auf maximum setzen=255=5V
movwf PORTB ; sonst: normal weiter, obere 8 Bit nach PortB schreiben

; Wert an PWM1 übergeben
MOVWF CCPR1L ; obere 8 Bit sind PWM

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

; Ablauf für 2.PWM ausgang
; ADC-Eingang AN1 auswählen
BCF ADCON0, 5 ; ADCHS2=0
BCF ADCON0, 4 ; ADCHS1=0
BSF ADCON0, 3 ; ADCHS0=1

;Pause zum ADC aufladen?
;************************************************* *********
; Warteschleife 1 ms für einen 10MHz-PIC-Takt
Waii
movlw .249 ; Zeitkonstante für 1ms
movwf loops2

Wai3 nop
nop
nop
nop
nop
nop
nop
decfsz loops2, F ; 1 ms vorbei?
goto Wai3 ; nein, noch nicht

;Eingangsspannung wandeln
BSF ADCON0, 2 ; ADC starten
loop2
BTFSC ADCON0, 2 ; ist der ADC fertig?
GOTO loop2 ; nein, weiter warten

; Wert auslesen und schreiben
; #### Nebenrechung

;Der Wert von ADRESH wird ausgelesen, wenn er kleiner 15 ist, soll der Ausgang ausgeschaltet bleiben
;dazu wird das carryflag abgefragt: wenn der messwert +240 das flag setzt,bedeutet das, er ist größer/gleich 15,
;also wird normal weitergemacht, wenn die flag nicht gesetzt wird, ist der wert kleiner 15, und der pwm ausgang soll "aus" bleiben
;dafür wird dann adresh 0 gesetzt,somit wird im folgenden code 0 + 0 + 0 = 0 und der port auf 0 gesetzt.

BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen, in work setzen
addlw D'240' ; 240 mit work addieren,
btfss STATUS,C ; carryflag gesetzt durch addition?
clrf ADRESH ; dann wird der befehl übergangen, da wert größer 15 (sonst adresh=0 => PWM=ausschalten da wert zu klein)
; sonst normal weiter
; #### Nebenrechnung Ende
BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen (0 oder messwert), in work setzen
addwf ADRESH,0 ; wert verdoppelt
addwf ADRESH,0 ; wert verdreifacht
btfsc STATUS,C ; wenn carry flag gesetzt,
movlw D'255' ; dann: wert auf maximum setzen=255=5V
; sonst normal weiter
; Wert an PWM2 übergeben
MOVWF CCPR2L ; obere 8 Bit sind PWM

; Warten, damit der ADC sich erholen kann
clrf wait
warten2
DECFSZ wait, f
goto warten2

goto Main

end



Alles angelehnt an spruts PWM Beispiel..inzwischen etwas erweitert..

jetzt schau ich nochmal was du da grade gemeint hast..

PsiQ
07.02.2007, 00:24
äm, moment, heißt das ich muß anstatt
RP2 = 255
einfach nur
RP2=254 machen, und ich hab mein high-pin (OHNE schaltverluste am mosfet) sobald ich 255 ins CCPL1 reinschreibe?

also aus dem hier:



; Frequenz auf ca 700Hz einstellen
BSF STATUS,RP0 ; Bank1
MOVLW D'255' ;
MOVWF PR2 ; ca 700 Hz
BCF STATUS,RP0 ; Bank1


das hier machen?:


; Frequenz auf ca 700Hz einstellen
BSF STATUS,RP0 ; Bank1
MOVLW D'254' ; HIER 1 WENIGER
MOVWF PR2 ; ca 700 Hz
BCF STATUS,RP0 ; Bank1

PsiQ
07.02.2007, 00:45
ES leeeeeeebt! :evil:

MUAHAHAHAAA!

jup, funktioniert ..
oder in messwerten gesagt:
vorher ging er gemessen mitm multimeter bis auf 99,5% duty cycle hoch
(ohne dauerhigh)
jetzt springt er von 98,5% direkt auf 0, bei voller helligkeit ..
exakt bei stufe 6 aufm Drehschalter!

Jetzt noch bissl an den Werten rumspielen, dass er ab Stufe 5 1/2 auf dauerhigh geht, und das ganze passt!
(da werd ich einfach noch +5 zum ersten Work addieren, und dann erst übertragen, dann ist das carry flag um 5 früher dran, also insgesamt um
5 alles höher....

Schön!
Sehr Schön!
Danke!!
Vielen Dank!

-Als nächstes die Weltherrschaft :-k .. :)

Benji
07.02.2007, 19:53
Oh Sorry

Habe mich tatsächlich ein bisschen "verlesen". Habe gemeint du überschreibst direkt ADRESH.

Nadann, Hauptsache es funktioniert jetzt.

(Sorry, das ich erst jetzt zurückschreibe, aber manchmal muss ich halt auch noch arbeiten ;-) )

PsiQ
07.02.2007, 19:58
macht doch nix, manche leute arbeiten, schlafen und essen sogar, hab ich gehört 8-[

Danke Trotzdem!