DEFINE OSC 20
DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true
T1 VAR WORD
T2 var word
T3 var word
Capture1 VAR PIR3.1
Capture2 var pir3.2
Capture3 var pir3.3
False CON 0
True CON 1
' auto time base reset, frequency mode, capture on every rising edge
period1 CON %01000101
period2 CON %01000101
period3 CON %01000101
ANSEL0=0 ' All digital
TRISA.2 = 1 ' this is your (CAP1) input pin measuring the frequency
TRISA.3 = 1
TRISA.4 = 1
INTCON = 0 ' Interrupts off
TMR5H = 0 ' Clear high byte of TMR5 counter
TMR5L = 0 ' Clear low byte
T5CON = %00000001 ' prescale=1:1, int clock, TMR5=on
CAP1CON = period1 ' we're measuring a period
CAP2CON = period2
CAP3CON = period3
Main:
Capture = False ' Reset capture flag
GOSUB pulsewidth ' get pulsewidth
' At 20MHz, to figure a PWM frequency of 19.455kHz
'
' TPWM = time period of PWM frequency
' PTPER = 12-bit period register PTPERL and PTPERH
' PTMRPS = PWM time base prescaler
'
' (PTPER+1)*PTMRPS 257
' TPWM = ---------------- = ------------ = 0.0000514
' Fosc/4 5000000
'
' Frequency = 1/TPWM = 1/0.0000514 = 19.455kHz
'
' PWM resolution (bits resolution for duty cycle)
'
' log(20MHz/19.455kHz) 3.01
' Resolution = ------------------ = ----------- = 10 bits
' .301 .301
' so we'll need a word sized var for Duty
Duty Var Word
PORTB = 0 ' clear port latch
TRISB = %11000000 ' PWM0,1,2,3,4,5 outputs
TRISC = 2 ' RC1 = FLTA input (ground RC1 to halt PWM)
' RC1 should be pulled high for normal PWM operation
' when fault A is enabled.
' PCPWM init
PTCON0 = %00000000 ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
' PTCON0 = %00000100 would give 19.45kHz/4
PTPERL = 0 '
PTPERH = 1 ' PTPER = $0100 or 256d for ~19.45kHz
' PWM4,5 independent
PWMCON0 = %01010100 ' PWM[5:0] outputs enabled
PWMCON1 = 1 ' updates enabled, overrides sync w/timebase
PTCON1 = %10000000 ' PWM time base is ON, counts up
FLTCONFIG = %00000011 ' enable fault A, cycle-by-cycle mode
Duty = dutycycle ' ~50% however this will be changed in respect to algorithm
PDC2L = Duty.LowByte ' maintain a duty cycle on PWM4,5
PDC2H = Duty.HighByte ' independent PWM outputs.
PAUSE 5
GOTO Main
pulsewidth:
' Frequency measurement mode, capture Timer5 count every rising edge
' with auto reset of Timer5 on each event
WHILE Capture = False
WEND
T1.HighByte = CAP1BUFH
T1.LowByte = CAP1BUFL
T2.HighByte = CAP2BUFH
T2.LowByte = CAP2BUFL
T3.HighByte = CAP3BUFH
T3.LowByte = CAP3BUFL
F69H VAR BYTE 'Value of period at CAP1 ready for calculation, f69h being its address from data sheet
F67H VAR BYTE 'Value of period at CAP2 ready for calculation
F65H VAR BYTE 'Value of period at CAP3 ready for calculation
''''''''''''''''''''''''''''''''''''Algorithm for finding power''''''''''''''''''''''''
averageperiod var byte 'saving average period to ram
averageperiod = (F69H+F67H+F65H)/3 'average period found using 3 periods
'for now im using arbitary random scaling factors, until i have the actual graphs to get the real rpm against power
rpmvalue var byte 'saving rpm value to ram
rpmvalue=60/(8*averageperiod) 'finding rpm value using current period measurement
power var byte 'saving power to ram
IF rpmvalue<=300 Then
power=rpmvalue/15
else
power=rpmvalue/10
endif
' now i need to link power to the arbitary pwm output
'this is a standard quadratic function (quadratic in example case anyway)
dutycycle var byte 'byte being the one that is answer of algorithm when thats created
dutycycle = (power^2)+(5*power)+3 'finding dutycycle using rpmvalue
RETURN
END
Bookmarks