Översätta kod mellan processorer

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
FinnbyFraggel
Inlägg: 10
Blev medlem: 29 september 2013, 10:30:55

Översätta kod mellan processorer

Inlägg av FinnbyFraggel »

Hej, jag är ny här på forumet och funderar på hur mycket jobb det är att översätta koden från en PIC12F615 till en PIC16F690?

Jag hittade ett schema på hur man på ett ganska enkelt sätt kan utöka antal kanaler på en RC sändare med en PIC12F615 som jag skulle vilja prova.
Bild
Nu råkar jag ha en 16F690 hemma och undrar om nån kan hjälpa mig översätta koden så den passar?
Sen behövs en liten förändring då kretsen enligt texten triggar på positiva signaler från radion och skickar också ut positiva, men min radio jobbar med negativa signaler.
Skribenten skriver
The circuit requires a positive going logic-level PPM pulse stream.
Och den bifogade koden har vi här.

Kod: Markera allt

;=======================================================================================
;                   Extra Channels for 2 ~ 6 Channel Transmitter
;=======================================================================================
;                    Bruce Abbott bhabbott@paradise.net.nz
;
; for Microchip PIC12F615
;
; Features:
;
;     - 2 extra channels 
;     - Fully Proportional  
;
; Changes:
;
; 2010-05-22 V0.0 created
; 2010-06-30 V0.1 support 5 and 6 channel transmitters
;
		ifdef	__12F615
                PROCESSOR PIC12F615
                INCLUDE   <P12F615.inc>
CMCON		equ	CMCON0
VREN		equ	CMVREN
		endif

                radix     dec

		errorlevel -302,-305	; not reporting bank<>0, dest=file

;#DEFINE SIMULATE	; for debugging only!

#DEFINE	BASECHANNELS 6	; number of channels in transmitter (2~6)

#define VERSION " T X P 6 1 5   0 . 1"

; =====================================================================================
; Configuration is:
;   Master Clear pin is disabled (used for servo pulse input)
;   Code Protection is OFF
;   Watchdog Timer is ON
;   Oscillator is Internal RC
;
		ifdef	__12F615
		__config  _MCLRE_OFF & _INTRC_OSC_NOCLKOUT & _IOSCFS_8MHZ
		endif

; GPIO register bits 
CHAbit          EQU       GP0 ; pin 7. first expansion channel analog input 
CHBbit          EQU       GP1 ; pin 6. second expansion channel analog input
PPMoutBit       EQU       GP2 ; pin 5. PPM pulse stream output
PPMinBit        EQU       GP3 ; pin 4. PPM pulse stream input
;               EQU       GP4 ; pin 3.  
;               EQU       GP5 ; pin 2. 

; I/O direction register value
TrisBits        EQU       (1<<CHAbit)|(1<<CHBbit)|(1<<PPMinBit)	; inputs

; Bits to be set with the OPTION instruction
;     7 = Weak pullups disabled
;     6 = Interrupt on Rising Edge
;     5 = Timer 0 source internal
;     4 = Which edge is don't care
;   3~1 = Prescaler to watchdog, set to give 16*17 = 272ms timeout

OptionBits      EQU       B'11011100'

; =====================================================================================
;                        General Purpose Register Definitions  
; =====================================================================================
		ifdef	__12F615
		CBLOCK	0x40
		ENDC
		endif

		CBLOCK
                flags           ; Various boolean flags
		Pot1:2		; pot 1 current position (16 bits)
		Pot2:2		; pot 2 current position (16 bits)
		samples		; number of samples per pot measurement
		ChannelA	; channel A width 0-255 = 1~2mS
		ChannelB	; channel B width 0-255 = 1~2mS
                PulseDelay      ; output pulse delay timer   
                temp		; general purpose variable
		ENDC

; Bits in Flags

SyncBit 	EQU       1	; sync gap detected

;==================================================================================
;                     Macro for generating short time delays
;===================================================================================
NO_OP           MACRO   count
NO_OP_COUNT     SET     count
                WHILE   NO_OP_COUNT>1
		goto	$+1		; 2 clocks
NO_OP_COUNT     SET     NO_OP_COUNT-2
                ENDW
		IF	NO_OP_COUNT
		nop			; 1 clock
		ENDIF
                ENDM

;==================================================================================
;                       16 Bit Math Macros  (little-endian)
;==================================================================================

; 16 bit unsigned addition with carry out.
;
; Operation: DST = DST + SRC                       
;
; DST is replaced, SRC is preserved
; Carry Set if SRC + DST > 65535
;
ADD16   MACRO   SRC,DST 
        MOVF    (SRC),W         ; Get low byte
        ADDWF   (DST),F         ; Add to destination
        MOVF    (SRC)+1,W       ; Get high byte
        BTFSC   STATUS,C        ; Check for carry
        INCF    (SRC)+1,W       ; Add one for carry
        ADDWF   (DST)+1,F       ; Add high byte into DST
        ENDM

; 16 bit unsigned subtraction with carry out.
; Word format is little endian (LSB at lower address)
;
; Operation: DST = DST - SRC
;
; DST is replaced, SRC is preserved
; Carry Set if DEST >= SRC (result >=0) 
;
SUB16   MACRO   SRC,DST
        MOVF    (SRC),W         ; Get low byte of subtrahend
        SUBWF   (DST),F         ; Subtract DST(low) - SRC(low)
        MOVF    (SRC)+1,W       ; Get high byte of subtrahend
        BTFSS   STATUS,C        ; If there was a borrow then
        INCF    (SRC)+1,W       ; decrement high byte of dst
        SUBWF   (DST)+1,F       ; Subtract the high byte 
        ENDM

; 16 bit copy
;
MOV16   MACRO   SRC,DST
        MOVF    SRC,W
        MOVWF   DST
        MOVF    SRC+1,W
        MOVWF   DST+1
        ENDM

; 16 bit clear 
;
CLR16   MACRO   VAR16
        CLRF    VAR16
        CLRF    VAR16+1
        ENDM
        
; 16 bit Logical Shift Right (= divide by 2)
;
LSR16   MACRO   VAR16
        CLRC		        ; Clear carry
        RRF     (VAR16)+1       ; Rotate high byte right
        RRF     (VAR16)         ; Rotate low byte right
        ENDM
        
; 16 bit Logical Shift Left  (= multiply by 2)
;
LSL16   MACRO   VAR16
        CLRC		        ; Clear carry
        RLF     (VAR16)         ; Rotate low byte left
        RLF     (VAR16)+1       ; Rotate upper byte left
        ENDM  

; 16 bit Rotate Left
;
RL16	MACRO	VAR16
	RLF	(VAR16)
	RLF	(VAR16)+1
	ENDM

; 16 bit Rotate Right
;
RR16	MACRO	VAR16
	RRF	(VAR16)+1
	RRF	(VAR16)
	ENDM

;==================================================================================
;                                     RESET
;==================================================================================
;
Coldstart:      ORG     0                

		goto	start

		org	4
		goto	isr

		org	0x8
                dw      VERSION

;----------------------------------------------------------------------------------
;                            Interrupt Service Routine
;----------------------------------------------------------------------------------

isr:		return	


;==================================================================================
;                         Wait for start of next PPM pulse
;==================================================================================
;
waitpulse:	clrwdt 
		btfsc   GPIO, PPMinBit	; wait for end of last pulse
                goto    waitpulse
waitpulse1: 	btfss   GPIO, PPMinBit  ; wait for start of next pulse
                goto    waitpulse1
		return

;==================================================================================
;                                Wait for sync gap
;==================================================================================
;
waitsync:	clrwdt 
		btfsc   GPIO, PPMinBit
                goto    waitsync	; Wait for end of last pulse
		movlw	2500/10
		movwf	temp
waitsync2:	clrwdt 			; prevent watchdog timeout
		btfsc	GPIO, PPMinBit	; 
                goto    waitsync	; Restart if pulse detected 	
		btfsc	GPIO, PPMinBit	; during next 20 cycles (10uS)
                goto    waitsync	;	
		btfsc	GPIO, PPMinBit	;
                goto    waitsync	;
		btfsc	GPIO, PPMinBit	;	
                goto    waitsync	; 
		btfsc	GPIO, PPMinBit	;
                goto    waitsync	;
		btfsc	GPIO, PPMinBit	;
                goto    waitsync	;	
		btfsc	GPIO, PPMinBit	;
                goto    waitsync	;
		btfsc	GPIO, PPMinBit	;	
                goto    waitsync	;
		decfsz	temp		; Repeat 250 times = 2500uS	
		goto	waitsync2	;
		return

;=================================================================================
;                Measure voltage on a potentiometer  
;=================================================================================
; input: w = pointer to 16 bit variable 'potx'  
;
; output: pot = 10 bit voltage ratio (0~1023 = 0~Vref)  
;  
GetPot:		movwf	FSR		; FSR = pot
		movlw	(200-3)/4
pot_delay:	addlw	-1
		skpnc			; wait 100uS for A/D input to stabalize
		goto	pot_delay	
		movlw	8		; 8 x oversampling
		movwf	samples
		clrf	INDF		; pot (low byte) = 0		  
		incf	FSR		
		clrf	INDF		; pot (high byte) = 0
pot_read:	bsf	ADCON0,GO	; start A/D conversion
pot_wait:	btfsc	ADCON0,GO	; wait for conversion to complete
		goto	pot_wait
		movf	ADRESH,w	; get A/D result (high byte)
		addwf	INDF		; add to pot (high byte)
		banksel	ADRESL
		movf	ADRESL,w	; get A/D result (low byte)
		banksel	0
		decf	FSR
		addwf	INDF		; add to pot (low byte)
		incf	FSR
		skpnc			; low byte overflow?
		incf	INDF		; yes, add 1 to high byte
		decfsz	samples
		goto	pot_read	; next sample 
		movlw	3
pot_div:	clrc
		rrf	INDF
		decf	FSR
		rrf	INDF		;  divide by 8
		incf	FSR
		addlw	-1
		skpz
		goto	pot_div
		return

;=================================================================================
;                               Get Pot positions
;=================================================================================
;
GetPots:	bcf	ADCON0,CHS0	; select A/D channel 0
		movlw	Pot1
		call	GetPot		; get pot1 voltage (10 bit)
		RR16	Pot1
		RR16	Pot1		; rotate right * 2 = / 4 = convert to 8 bit
		movf	Pot1,w
		movwf	ChannelA	; channelA = pot1 position (0~255)
		bsf	ADCON0,CHS0	; select A/D channel 1
		movlw	Pot2
		call	GetPot		; get pot2 voltage (10 bit)
		RR16	Pot2
		RR16	Pot2		; rotate right * 2 = convert to 8 bit
		movf	Pot2,w
		movwf	ChannelB	; channelB = pot2 position (0~255)
		return
 
;================================================================================
;                         Generate PPM output pulse  
;================================================================================
; finish previous channel pulse, create channel width, start channel ending pulse 
;
; input: w = channel width
;
DoChannel:	movwf	PulseDelay	
		call	delay300	; delay 300uS
		bcf	GPIO,PPMoutBit	; finish previous pulse
		movlw	((700-12)/4)-1
dp_2:		NO_OP	4
		addlw	-1
		skpnc			; delay +690uS
		goto	dp_2
		incf	PulseDelay
dp_3:		NO_OP	5
		decfsz	PulseDelay	; total delay = 0.99~2.01mS
		goto	dp_3
		bsf	GPIO,PPMoutBit	; start next pulse
                retlw   0              

;================================================================================
;                               300uS Delay
;================================================================================		
delay300:	movlw	((300-2)/4)-1
delay_300a:	NO_OP	4
		addlw	-1
		skpnc			
		goto	delay_300a
		return


;==================================================================================
;                       Copy PPM pulse from input to output
;==================================================================================
;
copypulse:	btfss   GPIO, PPMinBit
		goto	copypulse
                bsf	GPIO,PPMoutBit	
copypulse1:	btfsc   GPIO, PPMinBit
		goto	copypulse1
                bcf	GPIO,PPMoutBit	
		return

;------------------------------------------------------------------------------------
;                                     STARTUP 
;------------------------------------------------------------------------------------
;
; Initialise GPIO register

start:          clrf    GPIO		; all outputs will be low
                movlw   TrisBits
                tris    GPIO		; set I/O directions

 		banksel	ANSEL		; Register bank 1

		movlw	(1<<ADCS2)|(1<<ADCS0)|(1<<AN0)|(1<<AN1)
		movwf	ANSEL		; clk/8, Analog I/O on GP0 and GP1 
		
		banksel	0		; register bank 0

;		movlw	1<<CMON|1<<CMR  ; Comparator enabled, in- to GP1, in+ to VREF       

;
; Move the prescaler from tmr0 to the watchdog, without accidental resets.
;
                clrwdt                    
                clrf      TMR0            
                movlw     OptionBits | 7  
                option                    
                clrwdt
                movlw     OptionBits
                option
                clrwdt

; set up A/D convertor
		movlw	(1<<ADFM)|(1<<ADON) ; right-justify, A/D on
		movwf	ADCON0

; ready to go!            
		clrf	flags
		call	GetPots		; get initial pot positions

		call	waitpulse	; must NOT start in middle of sync gap!		

mainloop:	call	waitsync	; wait for sync gap
		variable channel=0
		while	channel<BASECHANNELS		
		call	copypulse	; pass through base channel pulses 
channel=channel+1
		endw
		call	waitpulse	; wait for start of final base channel pulse
		bsf	GPIO,PPMoutBit	; start output pulse
		movf	ChannelA,w
		call	DoChannel	; add first expansion channel 

		movf	ChannelB,w
		call	DoChannel	; add second expansion channel 

		call	delay300	
		bcf	GPIO,PPMoutBit	; finish final output pulse 

		call	GetPots		; get new pot positions

		goto	mainloop

                END

Någon som har lust att hjälpa till?

/Jonas
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Översätta kod mellan processorer

Inlägg av sodjan »

Det borde inte vara något jättestort problem. Sannolikt är det ungefär
samma jobb med själva bytet av processor som med anpassningen till
den "vända" PWM signalen. Jag skulle inte kalla det för en "översättning"
utan mer en "anpassning"... :-)

Varför har du en 16F690 hemma? Har du programmerat PIC något innan?
I så fall borde det inte vara något större problem, även för sig.

Vad har du gjort? Har du jämfört databladen t.ex?
FinnbyFraggel
Inlägg: 10
Blev medlem: 29 september 2013, 10:30:55

Re: Översätta kod mellan processorer

Inlägg av FinnbyFraggel »

Jag programmerade 16F84 en del på 90-talet men använde i stort sätt bara andras kod och ändrade bara lite variabler och sånt.
Orsaken är för att jag köpte en "PicKit2" för jag tänkte återuppta programmerandet för ett antal år sen och då medföljer just 16F690 och när jag jämförde databladen så ser jag att båda har DAC med samma upplösning och jag tolkade det som att dom har samma hastighet vilket troligen förenklar översättningen.
Nu fick jag inte tid att återuppta programmerandet så det har bara blivit liggande tills nu när jag sprang på detta lilla projekt som jag ville prova.
Jag gissar att man måste göra lite mer än byta GP0 mot RA0 och GP1 mot RA1 och GP2 mot RA3 och GP3 mot RA4 för att skifta in och utgående ben till 690?

Jag har hittat en översättning till PIC18F2550 där signalen är rätt vänd (negativ) men eftersom min PicKit2 har en 20 pin sockel och PIC18F2550 är 28 pin tror jag inte att den går att programmera utan något tillbehör.
Skillnaden vad gäller att vända på pulsen gissar jag ligger här:

Kod: Markera allt

;================================================================================
;                         Generate PPM output pulse  
;================================================================================
; finish previous channel pulse, create channel width, start channel ending pulse 
;
; input: w = channel width
;
DoChannel:	movwf	PulseDelay	
		call	delay300	; delay 300uS
		bcf	GPIO,PPMoutBit	; finish previous pulse      <------------ ändras till bsf
		movlw	((700-12)/4)-1
dp_2:		NO_OP	4
		addlw	-1
		skpnc			; delay +690uS
		goto	dp_2
		incf	PulseDelay
dp_3:		NO_OP	5
		decfsz	PulseDelay	; total delay = 0.99~2.01mS
		goto	dp_3
		bsf	GPIO,PPMoutBit	; start next pulse           <----------- ändras till bcf
                retlw   0      
För det är den enda skillnaden i den kod delen som jag hittar mellan positiv och negativ signal i sändning.

Jag antar att det här är skillnaden ligger i läsningen:

Kod: Markera allt

;==================================================================================
;                                Wait for sync gap
;==================================================================================
;
waitsync:	clrwdt 
		btfsc   GPIO, PPMinBit
                goto    waitsync	; Wait for end of last pulse
		movlw	2500/10
		movwf	temp
waitsync2:	clrwdt 			; prevent watchdog timeout
		btfsc	GPIO, PPMinBit	;                                             <------ ändras till btfss
                goto    waitsync	; Restart if pulse detected 	
		btfsc	GPIO, PPMinBit	; during next 20 cycles (10uS)      <------ ändras till btfss                
goto    waitsync	;	
		btfsc	GPIO, PPMinBit	;                                             <------ ändras till btfss
                goto    waitsync	;
		btfsc	GPIO, PPMinBit	;                                             <------ ändras till btfss
                goto    waitsync	; 
		btfsc	GPIO, PPMinBit	;                                             <------ ändras till btfss
                goto    waitsync	;
		btfsc	GPIO, PPMinBit	;                                             <------ ändras till btfss
                goto    waitsync	;	
		btfsc	GPIO, PPMinBit	;                                             <------ ändras till btfss
                goto    waitsync	;
		btfsc	GPIO, PPMinBit	;                                             <------ ändras till btfss
                goto    waitsync	;
		decfsz	temp		; Repeat 250 times = 2500uS	
		goto	waitsync2	;
		return
Kan det stämma?


/Jonas
Senast redigerad av FinnbyFraggel 29 september 2013, 16:05:45, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Översätta kod mellan processorer

Inlägg av sodjan »

OK.

> Jag gissar att man måste göra lite mer än byta GP0 mot RA0 och GP1 mot RA1 och GP2 mot RA3 och
> GP3 mot RA4 för att skifta in och utgående ben till 690?

Först får man ju se om just de pinnarna är de man vill använda, men vi säger att det är det.
Man får sedan kolla i databladet om pinnarna har några andra funktioner (t.ex analoga)
som behöver stängas av. Sen finns det sannolikt någonstans där man sätter TRIS
registren så att in/ut definieras korrekt. Men sen är det väl inte så mycket mer. :-)

> Jag har iofs hittat en översättning av koden till en PIC18F2550

Vardå?

> men jag är osäker på den går att programmera i min PicKit2 eftersom den har en 20 pin sockel och 2550 är 28 pin.

Du menar det lilla labb-kortet? Du behöver så klar inte köra med det.
Det är bara att dra ut de rellevanta signalerna till något annat. Du kan
ansluta 6-pin kontakten på PICkit2 till vad du vill...

> Jag tittade lite på koden för att försöka lista ut var signalen vändes...

Antingen vänder man själva signalen eller så tolkar man den omvänt i koden.
Man kan ju även sätta en inverter före porten så att koden kan köras
som den är. Men kanske gäller inverteringen även utsignalen (?).
FinnbyFraggel
Inlägg: 10
Blev medlem: 29 september 2013, 10:30:55

Re: Översätta kod mellan processorer

Inlägg av FinnbyFraggel »

Här är koden för PIC18F2550

Kod: Markera allt

;=======================================================================================
;                   Extra Channels for 2 ~ 6 Channel Transmitter
;=======================================================================================
;                    Bruce Abbott bhabbott@paradise.net.nz
;
; for Microchip PIC18F2550
;
; Features:
;
;     - 2 extra channels 
;     - Fully Proportional
;     - negative going input and output pulses  
;
; Changes:
;
; 2013-03-29 V0.1 created from 12F615 version
;
                PROCESSOR PIC18F2550
                INCLUDE   <P18F2550.inc>

                radix     dec

		errorlevel -305	; not reporting dest=file

;#DEFINE SIMULATE	; for debugging only!

#define	skpnc btfsc STATUS,C
#define skpz btfss STATUS,Z

#DEFINE	BASECHANNELS 4	; number of channels in transmitter (2~6)

#define VERSION " T X P 2 5 5 0   0 . 1"

; config bits! 
   CONFIG PLLDIV=1, CPUDIV=OSC3_PLL4, USBDIV=2
   CONFIG FOSC=INTOSC_EC, FCMEN=OFF, IESO=OFF
   CONFIG PWRT=OFF, BOR=ON, BORV=2, VREGEN=OFF
   CONFIG WDT=OFF, WDTPS=32
   CONFIG MCLRE=ON, LPT1OSC=OFF, PBADEN=OFF, CCP2MX=ON
   CONFIG STVREN=ON, LVP=OFF, XINST=OFF, DEBUG=OFF
   CONFIG CP0=OFF, CP1=OFF, CP2=OFF, CPB=OFF, CPD=OFF 
   CONFIG WRT0=OFF, WRT1=OFF, WRT2=OFF
   CONFIG WRTB=OFF, WRTC=OFF, WRTD=OFF
   CONFIG EBTR0=OFF, EBTR1=OFF, EBTR2=OFF       
   CONFIG EBTRB=OFF, WRT3=OFF, EBTR3=OFF, CP3=OFF

; I/O Port pin assignments  
#define PPMinPin  PORTB,RB0	; PPM input pulse stream on RB0 (pin 21) 
#define PPoutPin  PORTB,RB1	; PPM output pulse stream on RB1 (pin 22)  

; I/O port direction bits
TrisAbits = (1<<RA0)|(1<<RA1)	; analog inputs on RA0 (pin 2) and RA1 (pin 3)
TrisBbits = (1<<RB0)		; PPM input on RB0 (pin 21)
TrisCbits = 0



; Bits to be set with the OPTION instruction
;     7 = Weak pullups disabled
;     6 = Interrupt on Rising Edge
;     5 = Timer 0 source internal
;     4 = Which edge is don't care
;   3~1 = Prescaler to watchdog, set to give 16*17 = 272ms timeout

OptionBits      EQU       B'11011100'

; =====================================================================================
;                        General Purpose Register Definitions  
; =====================================================================================

		CBLOCK	8
                flags           ; Various boolean flags
		Pot1:2		; pot 1 current position (16 bits)
		Pot2:2		; pot 2 current position (16 bits)
		samples		; number of samples per pot measurement
		ChannelA	; channel A width 0-255 = 1~2mS
		ChannelB	; channel B width 0-255 = 1~2mS
                PulseDelay      ; output pulse delay timer   
                temp		; general purpose variable
		ENDC

; Bits in Flags

SyncBit 	EQU       1	; sync gap detected

;==================================================================================
;                       16 Bit Math Macros  (little-endian)
;==================================================================================

; 16 bit Rotate Right
;
RR16	MACRO	VAR16
	RRCF	(VAR16)+1
	RRCF	(VAR16)
	ENDM

;==================================================================================
;                                     RESET
;==================================================================================
;
Coldstart:      ORG     0                

		goto	start

		org	4
		goto	isr

		org	0x8
                dw      VERSION

;----------------------------------------------------------------------------------
;                            Interrupt Service Routine
;----------------------------------------------------------------------------------

isr:		return	


;==================================================================================
;                         Wait for start of next PPM pulse
;==================================================================================
;
waitpulse:	btfsc   PPMinPin	; wait for end of last pulse
                goto    waitpulse
waitpulse1: 	btfss   PPMinPin	; wait for start of next pulse
                goto    waitpulse1
		return

;==================================================================================
;                                Wait for sync gap
;==================================================================================
;
waitsync:	btfss   PPMinPin
                goto    waitsync	; Wait for end of last pulse
		movlw	2500/10
		movwf	temp
waitsync2:	btfss	PPMinPin	; 
                goto    waitsync	; Restart if pulse detected 	
		btfss	PPMinPin	; during next 20 cycles (10uS)
                goto    waitsync	;	
		btfss	PPMinPin	;
                goto    waitsync	;
		btfss	PPMinPin	;	
                goto    waitsync	; 
		btfss	PPMinPin	;
                goto    waitsync	;
		btfss	PPMinPin	;
                goto    waitsync	;	
		btfss	PPMinPin	;
                goto    waitsync	;
		btfss	PPMinPin	;	
                goto    waitsync	;
		decfsz	temp		; Repeat 250 times = 2500uS	
		goto	waitsync2	;
		return

;=================================================================================
;                Measure voltage on a potentiometer  
;=================================================================================
; input: w = pointer to 16 bit variable 'potx'  
;
; output: pot = 10 bit voltage ratio (0~1023 = 0~Vref)  
;  
GetPot:		clrf	FSR0H
		movwf	FSR0L		; FSR = pot
		movlw	(200-3)/4
pot_delay:	addlw	-1
		skpnc			; wait 100uS for A/D input to stabalize
		goto	pot_delay	
		movlw	8		; 8 x oversampling
		movwf	samples
		clrf	INDF0		; pot (low byte) = 0		  
		incf	FSR0L		
		clrf	INDF0		; pot (high byte) = 0
pot_read:	bsf	ADCON0,GO	; start A/D conversion
pot_wait:	btfsc	ADCON0,GO	; wait for conversion to complete
		goto	pot_wait
		movf	ADRESH,w	; get A/D result (high byte)
		addwf	INDF0		; add to pot (high byte)
		movf	ADRESL,w	; get A/D result (low byte)
		decf	FSR0L
		addwf	INDF0		; add to pot (low byte)
		incfsz	FSR0L		; point to high byte, without affecting flags!
		skpnc			; low byte overflow?
		incf	INDF0		; yes, add 1 to high byte
		decfsz	samples
		goto	pot_read	; next sample 
		movlw	3
pot_div:	bcf	STATUS,C
		rrcf	INDF0
		decfsz	FSR0L
		rrcf	INDF0		;  divide by 8
		incf	FSR0L
		addlw	-1
		bnz	pot_div
		return

;=================================================================================
;                               Get Pot positions
;=================================================================================
;
GetPots:	bcf	ADCON0,CHS0	; select A/D channel 0
		movlw	Pot1
		call	GetPot		; get pot1 voltage (10 bit)
		RR16	Pot1
		RR16	Pot1		; rotate right * 2 = / 4 = convert to 8 bit
		movf	Pot1,w
		movwf	ChannelA	; channelA = pot1 position (0~255)
		bsf	ADCON0,CHS0	; select A/D channel 1
		movlw	Pot2
		call	GetPot		; get pot2 voltage (10 bit)
		RR16	Pot2
		RR16	Pot2		; rotate right * 2 = convert to 8 bit
		movf	Pot2,w
		movwf	ChannelB	; channelB = pot2 position (0~255)
		return
 
;================================================================================
;                         Generate PPM output pulse  
;================================================================================
; finish previous channel pulse, create channel width, start channel ending pulse 
;
; input: w = channel width
;
DoChannel:	movwf	PulseDelay	
		call	delay300	; delay 300uS
		bsf	PPoutPin	; finish previous pulse
		movlw	((700-12)/4)-1
dp_2:		nop
		nop
		nop
		nop
		addlw	-1
		skpnc			; delay +690uS
		goto	dp_2
		incf	PulseDelay
dp_3:		nop
		nop
		nop
		nop
		nop
		decfsz	PulseDelay	; total delay = 0.99~2.01mS
		goto	dp_3
		bcf	PPoutPin	; start next pulse
                retlw   0              

;================================================================================
;                               300uS Delay
;================================================================================		
delay300:	movlw	((300-2)/4)-1
delay_300a:	nop
		nop
		nop
		nop
		addlw	-1
		skpnc			
		goto	delay_300a
		return


;==================================================================================
;                       Copy PPM pulse from input to output
;==================================================================================
;
copypulse:	btfsc   PPMinPin
		goto	copypulse
                bcf	PPoutPin	
copypulse1:	btfss   PPMinPin
		goto	copypulse1
                bsf	PPoutPin	
		return

;------------------------------------------------------------------------------------
;                                     STARTUP 
;------------------------------------------------------------------------------------
;
; Initialise GPIO register

start:          clrf    PORTA		; all outputs will be low
		clrf	PORTB
		clrf	PORTC
                movlw   TrisAbits
		movwf	TRISA
		movlw	TrisBbits	; set I/O port directions
		movwf	TRISB
		movlw	TrisCbits
		movwf	TRISC

; switch internal oscillator to 8MHz 
		movlw	b'01110010'	 
		movwf	OSCCON

; set up comparators
		movlw	b'00000111'	; comparators disabled
		movwf	CMCON

; set up A/D convertor
		movlw	(1<<ADON) 	; A/D convertor on
		movwf	ADCON0
		movlw	b'00000111'	; 2 analog inputs
		movwf	ADCON1
		movlw	((1<<ADCS2)|(1<<ADFM)|(1<<ADCS0)) ; right-justify, clk/16
		movwf	ADCON2
; ready to go!            
		clrf	flags
		call	GetPots		; get initial pot positions

		call	waitpulse	; must NOT start in middle of sync gap!		

mainloop:	call	waitsync	; wait for sync gap
 	variable channel=0
 	while	channel<BASECHANNELS		
		call	copypulse	; pass through base channel pulses 
channel=channel+1
 	endw
		call	waitpulse	; wait for start of final base channel pulse
		bcf	PPoutPin	; start output pulse
		movf	ChannelA,w
		call	DoChannel	; add first expansion channel 

		movf	ChannelB,w
		call	DoChannel	; add second expansion channel 

		call	delay300	
		bsf	PPoutPin	; finish final output pulse 

		call	GetPots		; get new pot positions

		goto	mainloop

                END

sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Översätta kod mellan processorer

Inlägg av sodjan »

Du har ingen sida som beskriver vad det hela går ut på?
victor_passe
Inlägg: 2436
Blev medlem: 28 januari 2007, 18:45:40
Ort: Kungsbacka

Re: Översätta kod mellan processorer

Inlägg av victor_passe »

Endast baserat på schemat så antar jag att den läser av bredden på X pulser och spottar ut X+2 pulser där de X första har samma bredd som de avlästa och de 2 sista har bredd abserat på potarnas position.
Min rekommendation, skriv själv och skriv i C.
Det är ett enkelt program som krävs, speciellt om man har input capture, (output capture/pwm) eller liknade det rör sig inte om många rader kod, skulle uppskatta runt 100rader max
FinnbyFraggel
Inlägg: 10
Blev medlem: 29 september 2013, 10:30:55

Re: Översätta kod mellan processorer

Inlägg av FinnbyFraggel »

Tanken är att lägga till två kanaler till dom befintliga sex som min radio har.
https://bitbucket.org/fpvkiwi/channel-w ... ngChannels
Är en generell beskrivning av hur det fungerar.

Och sen finns den här:
http://www.rcgroups.com/forums/showthread.php?t=1725033

Och det var här jag hittade den jag tänkte bygga:
http://www.bhabbott.net.nz/txpander.html

/Jonas
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Översätta kod mellan processorer

Inlägg av sodjan »

OK.
Så man använder en av originalkanalerna för att muxa ett antal extra kanaler.
Det är den hel del processerande av signalen för att säkerställa att sändare
och mottagare ligger i synk och så att inte de extra kanalerna blandas ihop.

> Och det var här jag hittade den jag tänkte bygga:

Den ser ut att köra via den enklare metoden där man "bara" lägger
till extra kanaler som sändaren inte har. T.ex 2 extra kanaler för
att få 6, det kräver en 6-kanals mottagare. Där är det alltså inte
multiplexning av extra kanaler inom en enskild kanels "slot".

Hur som helst, absolut enklast är ju att skaffa ett par 16F615, om det
är just den lösnigen du vill bygga. Ca 10:- hos ELFA. Då kan du bara
plocka HEX filen som den är och blåsa in den...
FinnbyFraggel
Inlägg: 10
Blev medlem: 29 september 2013, 10:30:55

Re: Översätta kod mellan processorer

Inlägg av FinnbyFraggel »

I det här fallet är inte inte frågan om muxning utan bara den enkla metoden att addera till två pulser till på den befintliga signalen.

Viktor_passe: jag kan inte skriva i C, möjligen tolka redan skriven kod och hade gärna skrivit om koden själv om jag haft kunskapen.
Frågan jag ställde var hur mycket jobb det var att översätta koden till en annan processor än den som jag har källkoden för och hur man skulle vända på signalen från positiv till negativ, det sista tror jag att jag har hittat om du tittar en bit upp i tråden.
Om det nu är så enkelt som jag tror att skifta från positiv till negativ trigg på signalen kan jag lätt fixa det och köpa en 12F615 och peta in koden i så är problemet löst.

Så om någon kan bekräfta att bcf genererar en positiv och bsf en negativ puls och att btfsc läser en positiv puls och btfss läser en negativ puls så är problemet löst.

/Jonas
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Översätta kod mellan processorer

Inlägg av sodjan »

> Så om någon kan bekräfta att bcf genererar en positiv och bsf en negativ puls...

Nej. BCF sätter en bit till "0" ("Bit Clear File") och BSF sätter den till "1" ("Bit Set File").

> och att btfsc läser en positiv puls och btfss läser en negativ puls.

Inte riktigt. BTFSC/BTFSS ("Bit Test File Skip if Clear/Set") läser en bit och hoppar
över ("skippar") nästa instruktion beroende på om den var "0" eller "1".

"Puls" är inte ett korrekt uttryck ovan, men det är möjligt att du tänkte rätt.

Visst kan man anpassa koden till en annan processor, och det är sannolikt rellativt
enkelt, men det lär kosta mer än 10:-... :-)
FinnbyFraggel
Inlägg: 10
Blev medlem: 29 september 2013, 10:30:55

Re: Översätta kod mellan processorer

Inlägg av FinnbyFraggel »

Så om någon kan bekräfta att bcf genererar en positiv och bsf en negativ puls...

Nej. BCF sätter en bit till "0" ("Bit Clear File") och BSF sätter den till "1" ("Bit Set File").
Ja, men då stämmer det eftersom man skiftar plats på BCF och BSF, d.v.s i ena fallet sätter man 0 i början av rutinen och 1 i slutet - negativ - fallande puls och i andra fallet 1 i början och 0 i slutet - positiv - stigande puls.

Tack!

/Jonas
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Översätta kod mellan processorer

Inlägg av sodjan »

Jo, så är det nog...

Det jag menade är att en "puls" är en komplett 0->1->0 eller 1->0->1.
Varje puls har två "flanker", en stigande (BSF) och en fallande (BCF).

Så det krävs en kombination av BCF/BSF eller BSF/BCF för att få en "puls"...

"Fallande puls" och "stigande puls" låter lite underligt. Du menar "flank" där.

Det var bara det... :-)
Skriv svar