PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : unerklärlicher Spannungsverlust



seven
08.05.2005, 00:53
Hallo zusammen,

Ich wandle mit einem 12F675 zwei Spannungen und geb an zwei pins zwei manuell erzeugte pwm-signale aus (675 hat keine pwm).

Das ganze läuft wie bei anderen auch über timer-interrupt:
- in der hauptprogrammschleife werden nur die beiden spannungen gewandelt und das ergebnis in zwei registern (ad_fan1, ad_fan2) gespeichert (für jedes poti ein register)
- tritt ein timer-interrupt auf, wird das register pos inkrementiert und geprüft ob das ergebnis null ist. wenn ja, werden beide pins (out_fanX) auf 1 gesetzt (falls ad-wert des zug. potis größer 0).
- die pegel sind jetzt also beide auf high und werden erst wieder auf low gelegt wenn pos == ad_fanX ist. also muss wenn zB ad_fan1 = 120 , der timer 120 mal überlaufen bis das pin out_fan1 auf null gesetzt wird.
- Kurz: pos wird in der isr immer inkrementiert, wenn null ->pins auf 1, falls pos gleich dem ad-wert -> pins auf 0



; pin assignment: ---------
; VDD -|1 8|- VSS
; Fan1 -|2 7|- Poti Fan 1
; Fan2 -|3 6|- Poti Fan 2
; -|4 5|-
; ---------
;
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

#include <P12f675.INC>
ERRORLEVEL -302 ;SUPPRESS BANK SELECTION MESSAGES

__CONFIG 0x3FA4
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

cblock h'20'
pos ; counts timer overflows
; if pos == NULL then out_fanX = 1
; if ad_fanX == pos then
; out_fanX = 0
ad_fan1 ; pulse width for fan 1
ad_fan2 ; pulse width for fan 2

wait ; waitloop

W_TEMP
STATUS_TEMP
endc

#define out_fan1 GPIO,5
#define out_fan2 GPIO,4

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
; program start

org 0x00
goto init
org 0x04
isr
bcf INTCON,GIE ; disable all interrupts
MOVWF W_TEMP ;copy W to temp register,could be in either bank
SWAPF STATUS,W ;swap status to be saved into W
BCF STATUS,RP0 ;change to bank 0 regardless of current bank
MOVWF STATUS_TEMP ;save status to bank 0 register

movlw D'230'
movwf TMR0

incfsz pos,f
goto notzero
; new periode: switch fans on (if required)
movf ad_fan1,w
btfss STATUS,Z
bsf out_fan1 ; turn fan1 on if pulse width greater 0
movf ad_fan2,w
btfss STATUS,Z
bsf out_fan2 ; turn fan2 on if pulse width greater 0
goto done
notzero ; turn fanX off if value is reached
movf ad_fan1,w
subwf pos,w
btfsc STATUS,Z
bcf out_fan1 ; turn fan1 off if ad_fan1 == pos
movf ad_fan2,w
subwf pos,w
btfsc STATUS,Z
bcf out_fan2 ; turn fan2 off if ad_fan2 == pos
done

SWAPF STATUS_TEMP,W ;swap STATUS_TEMP register into W,
;sets bank to original state
MOVWF STATUS ;move W into STATUS register
SWAPF W_TEMP,F ;swap W_TEMP
SWAPF W_TEMP,W ;swap W_TEMP into W

bcf INTCON,T0IF ; clear interrupt flag
bsf INTCON,GIE ; interrupts wieder erlauben
retfie
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
; initial process
init
; port/ad initialization
bcf STATUS, RP0 ; Bank 0
clrf GPIO ; all off
movlw b'00000111'
movwf CMCON ; comparator off
bsf STATUS, RP0 ; Bank 1
movlw b'00000011'
movwf TRISIO ; GP0:GP1 - input
movlw b'00000101'
movwf ANSEL ; AD-Clock, ANS0:ANS1 A-inp
bcf STATUS, RP0 ; Bank 0
movlw b'00000001'
movwf ADCON0 ; left, ref vdd, ch 0, ad-converter on

; internal clock
bsf STATUS, RP0 ; Bank 1
call 0x3FF
movwf OSCCAL ; 4-MHz-Calibration
bcf STATUS, RP0 ; Bank 0

; timer 0 configuration
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'10000000' ; pull-ups disabled, internal instruction cycle clock
movwf OPTION_REG
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
clrf TMR0

; init register
clrf pos
clrf ad_fan1
clrf ad_fan2

; interrupt
bsf INTCON, T0IE ; Timer 0 activated
bsf INTCON, GIE ; global activated

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
; main loop

main
; poti fan 1 ~~~~~~~~~~~~~~~~~~~~~~~~~
bcf ADCON0, 3
bcf ADCON0, 2 ; channel 0 - poti fan1
bsf ADCON0, 1 ; start ADC

loop_1
btfsc ADCON0, 1 ; ADC ready?
goto loop_1

movfw ADRESH
movwf ad_fan1 ; store upper 8bits

clrf wait
warten_1
decfsz wait, f
goto warten_1 ; adc has to recover

; poti fan 2 ~~~~~~~~~~~~~~~~~~~~~~~~~
bcf ADCON0, 3
bsf ADCON0, 2 ; channel 1 - poti fan 2

bsf ADCON0, 1 ; start ADC

loop_2
btfsc ADCON0, 1 ; ADC ready?
goto loop_2

movfw ADRESH
movwf ad_fan2 ; store upper 8bits

clrf wait
warten_2
decfsz wait, f
goto warten_2 ; adc has to recover


goto main

end


PROBLEM:
- wenn ich an einem poti drehe und die puls-weite verringere, wird die pulsweite des anderen pins auch kleiner!?
Mir fiel das auf weil ich zwei leds angeschlossen habe, und die helligkeiten von einander abhängig waren. wenn also eine led komplett aus ist, leuchtet die andere nicht mehr so hell! das funktioniert in beide richtungen.
hab mit dem multi nachgemessen:
beide leds an (pulsweite 100%): Spannungsabfall an LEDs: ~1,8V
nur eine LED an (gleicher Wert/spannung an Poti wie vorher): Spannung LED ~0,8V

nach meinem Verständnis sollte die pulsweite gleich bleiben, da die Spannung am Poti auch gleich bleibt!? oder hab ich da was übersehen?

Wie schon gesagt, das ganze pwm-zeugs läuft alles in der isr ab, im hauptprog werden nur die Spannungen gewandelt.
würde mich freuen wenn sich jemand die Mühe macht sich den Code anzuschauen.

Vielen Dank im Vorraus

Grüße
Sebastian

seven
08.05.2005, 11:42
Hallo,

die Lösung zu dem Problem findet ihr im PIC Forum unter www.fernando-heitor.de

Grüße
Sebastian