HI All,
This explanation has been the best one that I have found concerning the use of the PCPWM. That said, there still seems to be a bit of mystery surrounding it's use, at least to me. I mapped out the formulas in Excel, but I am still having trouble getting my head around the details. I'm trying to make a generic H-bridge for low frequencies and keep running into the wall. An 18F1330 with two pots, a switch, and the FETs with drivers. One Pot is for Frequency, the other is for Duty. The switch controls if the output is pulsed DC or cycles both ways. I'm not understanding the interaction of the frequency to the Duty. I can control the Freq just fine, but it makes a mess of the duty. Currently, the application needs it to run from 3 Hz to 100Hz with control from low power to high power (~5%-95% duty). I can see that there is a dependency with the PWM resolution, but I'm not sure how to manage it. I can get the PTPER values within 0-4096, but the resolution gets out of range. I'm thinking I need to find some way to scale the Duty to the PTPER values, and adjust accordingly, but I haven't managed to make it click. Any suggestions?
Code:
'****************************************************************
'* Name : PCPWM_1330_H-bridge84.BAS *
'* Author : Mark Rokus *
'* Notice : Copyright (c) 2012 Controlled Surroundings Inc. *
'* : All Rights Reserved *
'* Date : 6/9/2012 *
'* Version : 1.0 *
'* Notes : 18F1330 to drive H bridge: *
'* : (2)L6378 drivers to (4) FDP22N50N N-FETs *
'* used PCPWM_1330_H-bridge5 to test Hardware on separate FETS
'* New rewrite using ints
'* moved switch to RB3, rewire drivers complementary
'* NOTE: Int not working, Not going into AC
'* Freq and Duty not correct
'****************************************************************
' 18F1330
' ---------------------u----------------------
' Freq -1|RA0/AN0/INT0 RB3/INT3/CMP1|18- Switch
' Duty -2|RA1/AN1/INT1 RB2/INT2/CMP2|17- Pad
' Pad -3|RA4/TOCKI/AN2 RA7/OSC1/CLKI|16- Pad
' Vpp -4|RA5/MCLR/vpp RA6/OSC2/CLKO/AN3|15- Pad
' Gnd -5|-- VSS VDD++|14- 5 vdc
' Tx -6|RA2/TX/CK RB7/PGD/PWM5|13- PGD
' Rx -7|RA3/RX/DT RB6/PGC/PWM4|12- PGC
' Pad -8|RB0/PWM0 RB5/PWM3|11- Q1/Q4 PWM
' Pad -9|RB1/PWM1 RB4/PWM2|10- Q2/Q3 PWM
' |___________________________________________|
#CONFIG
CONFIG OSC = INTIO2 ;Internal oscillator, port function on RA6 and RA7
#ENDCONFIG
DEFINE OSC 4 ' Actually @ 2MHz
OSCCON = %11011100 ' INTOSC primary, 2MHz
'****** Hardware Serial Setup ***************
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 8 ' 57600 Baud @ 2MHz, -3.55%
SPBRGH = 0
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
'***************************************
TRISA = %00000011 ' PortA : outputs except RA.0/RA.1= AN
TRISB = %00001000 ' all outputs ex: RB.3 switch i/p
INTCON = 0 '
INTCON2 = 0
CMCON = 0 ' Comparators off
clear
'**** Analog setup ****
ADCON1 = %00001100 ' AN0,AN1 Analog: VDD ref. RA4 & RA6 DIO
ADCON2 = %10010001 ' Right justified, 8 Tad, Fosc/8
'***** PWM Setup ? ********************
PTCON0 = %00001110 ' 1:1 post, Fosc/256 (1:64) pre, UpDown(...00 free)
PTCON1 = %11000000 ' PWM Time Base timer on, Count Down
PWMCON0 = %00110111 ' 0-3 PWM, complementary
PWMCON1 = 1 ' 1:1 postscale, updates enabled, overrides sync
DTCON = 0 ' zero dead-time
PTCON1 = %10000000 ' PWM time base is ON, counts up
FLTCONFIG = 0 ' disable fault A
OVDCONS = %00000000 '
'::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
' Variable definition
'::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
PORTB = 0 ' clear port latch
Fraw var word ' Raw reading for Frequency
Freq var word ' Frequency of PWM
Draw var word ' Raw reading for Duty
Duty Var Word ' Duty of PWM
Sw var PORTB.3 ' switch input for AC or Positive only
'************************************************
Start:
hserout ["1330_H-bridge83",13,10]
pause 500
'*************************************
PosOnly:
If sw = 0 then ac ' mode check
ADCON0 = %00000011 ' Start conversion on AN0
WHILE ADCON0.1=1 ' Wait for it to complete
WEND
Fraw.HighByte = ADRESH ' get result from AN0
Fraw.LowByte = ADRESL '
ADCON0 = %00000111 ' Start conversion on AN1
WHILE ADCON0.1=1 ' Wait for it to complete
WEND
Draw.HighByte = ADRESH ' get result from AN1
Draw.LowByte = ADRESL '
Freq = (Fraw) max 3 '
Duty = (Draw*3) max 1 '
PTPERH = Freq.highbyte 'load timer: Freq low byte
PTPERL = Freq.lowbyte ' Freq low byte
PDC1H = Duty.HighByte ' PWM duty on Out1
PDC1L = Duty.LowByte
OVDCOND = %00001000 ' enable PWM3 OUT1 (Q1/Q4 on RB5)
hserout ["Duty ",dec duty," PosFreq ",dec Freq]
goto PosOnly ' Loop
'***************************************************************************
AC: ' sequence for generating Alternating pulses
PosAlt: 'drive Positive pulse on bridge
If sw = 1 then posonly ' mode check
PIR3.4 = 0 ' reset PWM Int flag
while PIR3.4 = 0
OVDCOND = %00001000 ' enable PWM3 OUT1 (Q1/Q4 on RB5)
ADCON0 = %00000011 ' Start conversion on AN1
WHILE ADCON0.1=1 ' Wait for it to complete
WEND
Fraw.HighByte = ADRESH ' get result from AN0
Fraw.LowByte = ADRESL '
Freq = Fraw max 3 '
PTPERH = Freq.highbyte 'load timer: Freq low byte
PTPERL = Freq.lowbyte ' Freq low byte
wend ' one cycle until Int
NegAlt: ' drive Negative pulse on bridge
PIR3.4 = 0 ' reset PWM Int flag
while PIR3.4 = 0
OVDCOND = %00000100 ' enable PWM1 OUT2 (Q2/Q3 on RB4)
ADCON0 = %00000111 ' Start conversion on AN0
WHILE ADCON0.1=1 ' Wait for it to complete
WEND
Draw.HighByte = ADRESH ' get result from AN1
Draw.LowByte = ADRESL '
Duty = (Draw) max 1 '
PDC1H = Duty.HighByte ' PWM duty on Out1
PDC1L = Duty.LowByte
wend ' one cycle until Int
hserout ["Duty ",dec duty," ACFreq ",dec Freq]
goto AC ' Loop
end
So I guess the question is: Can anyone explain the relationship between PTPER and PDCx in this dynamic environment in a way that I'm not seeing?
Thanks
Bo
Bookmarks