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

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