-         

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 21

Thema: Code zum Messwert verdreifachen/ pwm ein/aus-schalten ?

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    09.05.2006
    Beiträge
    1.178

    Code zum Messwert verdreifachen/ pwm ein/aus-schalten ?

    Anzeige

    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:
    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:

    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
    	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.
    ################################################

    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
    wopps-jetzt aber ab ins Bettchen..
    GrußundTschüß \/
    ~Jürgen

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.05.2005
    Ort
    Wallis
    Beiträge
    137
    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

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    09.05.2006
    Beiträge
    1.178
    ö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..
    GrußundTschüß \/
    ~Jürgen

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.05.2005
    Ort
    Wallis
    Beiträge
    137
    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

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    09.05.2006
    Beiträge
    1.178
    PIC16F876A
    GrußundTschüß \/
    ~Jürgen

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.05.2005
    Ort
    Wallis
    Beiträge
    137
    Nun ich habe nachgesehen. Die beschriebenen Funktionen sind erst bei PIC18F zu finden. Dann ist deine Lösung sicher nicht schlecht.

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    09.05.2006
    Beiträge
    1.178
    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..
    GrußundTschüß \/
    ~Jürgen

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    09.05.2006
    Beiträge
    1.178
    Sooo
    wenn man adresh mit 0 überschreiben kann/darf, müsste das ganze so gehen..

    Code:
    ; 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


    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..
    GrußundTschüß \/
    ~Jürgen

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.05.2005
    Ort
    Wallis
    Beiträge
    137
    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

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    09.05.2006
    Beiträge
    1.178
    ä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:
    Code:
    ;==========================================================================
    ;
    ;       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..
    GrußundTschüß \/
    ~Jürgen

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •