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?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?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
Thanks
Bo
Bookmarks