Hi group,
I found an instructables article on creating a boost mode power supply based on a PIC. Its programmed in MikroBasic so I thought Id try and convert it to PBP PRO.
There are a couple of questions I have and a few issues. I'd also like to add the ability to have pushbutton up and down dimming and soft start/soft stop too.
Anyway, here is the original program:
And here is my PBP PRO conversion so far:Code:dim temp as word dim final_period, final_duty, high_duty, low_duty, last_adjust as byte dim supply_multiplier, period_multiplier as float dim v_feedback, v_supply, t_rise, SMPS_duty, t_period, SMPS_period as float dim EE_pointer, EE_data as byte 'set values const v_ref as float=3.8 'float 5.1 in the example const supply_ratio as float=11.35 'float const osc_freq as float=8 'integer or float const L_Ipeak as float=67 'float const fb_value as word=443 'word 225 in the example sub procedure PRE_CALC 'precalculations supply_multiplier=v_ref*supply_ratio period_multiplier=(4/osc_freq) end sub sub procedure UPDATE_SMPS 'take Vss reading temp=0 temp=ADC_read(ANS0) ' ADC conversion 'convert to voltage v_feedback=temp 'put ADC in float v_supply=v_feedback/1024 'find supply % of vref v_supply=v_supply*supply_multiplier 'find supply volts 'calculate rise time t_rise=L_Ipeak/v_supply 'find rise time @ supply volts for L/Ipeak 'calculate CCPR1L:CCP1CON<5:4> SMPS_duty=t_rise*osc_freq 'find duty cycle value final_duty=SMPS_duty 'convert to byte 'calculate period t_period=(t_rise*1.33) 'dutycycle = .75period 'calculate PR2 SMPS_period=(t_period/period_multiplier) 'find period value final_period=SMPS_period-1.0 'put in byte 'put in register masks high_duty=(final_duty>>2) 'high 6 bits in CCPR1L low_duty=(final_duty<<6) 'low two bits for CCP1CON low_duty=(low_duty>>2) 'shift back to CCP1CON<5:4> low_duty.3=1 'PWM configuration bit low_duty.2=1 'PWM configuration bit 'LOG TO EEPROM 'only write if we measure somthing, 'prevents false writes durring programming b/c MCLR is disabled if temp > 0 then EE_data=word(temp>>8) 'high 8 bits first address Eeprom_Write(EE_pointer, EE_data) EE_pointer=EE_pointer+1 EE_data=temp 'low 8 bit second address Eeprom_Write(EE_pointer, EE_data) EE_pointer=EE_pointer+1 'put final_duty in eeprom Eeprom_Write(EE_pointer, final_duty) EE_pointer=EE_pointer+1 'put final_period in eeprom Eeprom_Write(EE_pointer, final_period) EE_pointer=EE_pointer+1 'reset write pointer if needed if EE_pointer > 197 then EE_pointer=1 end if 'update the write pointer Eeprom_write(0, EE_pointer) end if end sub main: 'set ADC GPIO = 0 CMCON0 = 7 TRISIO = 0 ' designate gpio as output TRISIO.ANS0 = 1 ' pin ANS0 as input (Supply feedback) TRISIO.ANS1 = 1 ' pin ANS1 as input (HV-feedback) ANSEL.ANS1=1 ANSEL.ANS0=1 ADCON0.VCFG = 0 ' Vdd as Vref 'Low Voltage Indicator Light GPIO.4=1 'indicator light on 'delay and take Vss reading EE_pointer=Eeprom_read(0) delay_ms(1000) PRE_CALC UPDATE_SMPS 'setup PWM PR2=final_period 'sets PWM frequency CCPR1L=0 '8 most sig. duty cycle bits =0 CCP1CON.5=0 'least significant bits = 0 CCP1CON.4=0 'least significant bits = 0 CCP1CON=12 'turns on PWM (set CCP1CON=0 at any time to turn off PWM) T2CON=4 'turns on TIMER2 module (required for PWM timing) last_adjust=0 while true temp=0 temp=ADC_read(ANS1) ' ADC conversion if temp > fb_value then 'feed back OVER set voltage if last_adjust=1 then 'if 0 then already off CCPR1L=0 CCP1CON.5=0 CCP1CON.4=0 GPIO.5=1 GPIO.4=0 last_adjust=0 end if else if last_adjust=0 then CCPR1L=high_duty CCP1CON=low_duty GPIO.5=0 GPIO.4=1 last_adjust=1 end if end if wend end.
Ok, first thing, I have not set up the ADC or inputs/outputs yet, this isnt an issue at the moment. i have also not finished with the EEprom yet.Code:define OSC 48temp VAR word final_period var byte final_duty var byte high_duty var byte low_duty var byte last_adjust var byte supply_multiplier var word 'as float period_multiplier var word 'as float v_feedback var word v_supply var word t_rise var word SMPS_duty var word t_period var word SMPS_period var word EE_pointer var byte EE_data var byte v_ref var byte supply_ratio var byte osc_freq var byte L_Ipeak var byte fb_value var word '------------------------------------------------------------------------------- 'set values v_ref = 38/10 'float 5.1 in the example, 3.8 here supply_ratio = 1135/100 'float, 11.35 here osc_freq = 8 'integer or float L_Ipeak = 67 'float fb_value = 443 'word 225 in the example '------------------------------------------------------------------------------- ADCON1 = %00001011 ADCON2 = %10000111 TRISA = %00011111 TRISB = %00000000 TRISC = %00000111 CMCON = 7 '------------------------------------------------------------------------------- PRE_CALC: 'precalculations supply_multiplier=v_ref*supply_ratio period_multiplier = 4/osc_freq return '------------------------------------------------------------------------------- UPDATE_SMPS: 'take Vss reading temp=0 ADCIN 0, temp 'convert to voltage v_feedback=temp 'put ADC in float v_supply=v_feedback/1024 'find supply % of vref v_supply=v_supply*supply_multiplier 'find supply volts 'calculate rise time t_rise=L_Ipeak / v_supply 'find rise time @ supply volts for L/Ipeak 'calculate CCPR1L:CCP1CON<5:4> SMPS_duty=t_rise*osc_freq 'find duty cycle value final_duty=SMPS_duty 'convert to byte 'calculate period t_period=t_rise*133/10 'dutycycle = .75period 'calculate PR2 SMPS_period=(t_period/period_multiplier) 'find period value final_period=SMPS_period-1 'put in byte 'put in register masks high_duty=(final_duty>>2) 'high 6 bits in CCPR1L low_duty=(final_duty<<6) 'low two bits for CCP1CON low_duty=(low_duty>>2) 'shift back to CCP1CON<5:4> low_duty.3=1 'PWM configuration bit low_duty.2=1 'PWM configuration bit 'LOG TO EEPROM 'only write if we measure somthing, 'prevents false writes durring programming b/c MCLR is disabled if temp > 0 then EE_data=(temp>>8) 'high 8 bits first address Write 0,EE_pointer, 10,EE_data EE_pointer=EE_pointer+1 EE_data=temp 'low 8 bit second address Write 0,EE_pointer, 10,EE_data EE_pointer=EE_pointer+1 'put final_duty in eeprom Write 0,EE_pointer, 20,final_duty EE_pointer=EE_pointer+1 'put final_period in eeprom Write 0,EE_pointer, 30,final_period EE_pointer=EE_pointer+1 'reset write pointer if needed if EE_pointer > 197 then EE_pointer=1 endif 'update the write pointer write 0, EE_pointer endif return '------------------------------------------------------------------------------- main: 'set ADC 'GPIO = 0 'CMCON = 7 'TRISa = 0 ' designate gpio as output 'TRISa.1 = 1 ' pin ANS0 as input (Supply feedback) 'TRISa.2 = 1 ' pin ANS1 as input (HV-feedback) 'ANSEL.ANS1=1 'ANSEL.ANS0=1 'ADCON0.VCFG = 0 ' Vdd as Vref 'Low Voltage Indicator Light porta.4=1 'indicator light on 'delay and take Vss reading Read 0, EE_pointer 'EE_pointer=Eeprom_read(0) pause 1000 gosub PRE_CALC gosub UPDATE_SMPS 'setup PWM PR2=final_period 'sets PWM frequency CCPR1L=0 '8 most sig. duty cycle bits =0 CCP1CON.5=0 'least significant bits = 0 CCP1CON.4=0 'least significant bits = 0 CCP1CON=12 'turns on PWM (set CCP1CON=0 at any time to turn off PWM) T2CON=4 'turns on TIMER2 module (required for PWM timing) last_adjust=0 while temp=0 ADCIN 0, temp ' ADC conversion if temp > fb_value then 'feed back OVER set voltage if last_adjust=1 then 'if 0 then already off CCPR1L=0 CCP1CON.5=0 CCP1CON.4=0 porta.5=1 porta.4=0 last_adjust=0 endif else if last_adjust=0 then CCPR1L=high_duty CCP1CON=low_duty porta.5=0 porta.4=1 last_adjust=1 endif endif wend end]
My first question is regarding the While - Wend loop.
If the program is stuck doing stuff in this loop it cant respond to any push button inputs to turn it on or off, or dim the brightness etc. This part of the program will have to be done at the same time as the buttons are monitored. So, do I have the buttons on an interrupt or does this loop run in the back ground somehow?






Bookmarks