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:

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.
And here is my PBP PRO conversion so far:

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]
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.

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?