Ok, I understand everything up until this:
ccp1con=$0C
The pwm is already turned on as per the CCP1CON line.
Ok, I understand everything up until this:
ccp1con=$0C
The pwm is already turned on as per the CCP1CON line.
Last edited by jmgelba; - 25th October 2011 at 17:37.
Frustrated. Not sure what I am missing now. The CCP1 pin is always high, LED flashes correctly.
Code:DEFINE OSC 48 DEFINE ADC_BITS 10 DEFINE ADC_CLOCK 3 DEFINE ADC_SAMPLEUS 50 DEFINE CCP1_REG PORTC DEFINE CCP1_BIT 2 final_period var byte final_duty var byte high_duty var byte low_duty var byte ADCON1 = 00001011 ADCON2 = 00000011 TRISA = 00001111 TRISB = 01110000 TRISC = 00000000 CMCON = 7 CCP1CON = 00111100 PR2 = 44 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 CCPR1L=high_duty CCP1CON = $0C T2CON = 4 main: PORTC.0 = 1 pause 500 PORTC.0 = 0 Pause 500 goto main
Last edited by jmgelba; - 25th October 2011 at 18:39.
Figured it out. Helps to have a value for final_duty to load!
final_duty = 136
This gives me exactly what my calculations showed. 3.76uS at 75% duty cycle. 265.90KHz
Splendid!!
Sorry I was not online earlier. Which PIC are you using?
Ioannis
I am using a 18F2550.
I seem to have it working at the moment however it is not very smooth.
When the on/off button is pressed I need to sweep from 0% duty cycle up to the set limit in 1 second. I can see this happening by writing the incremental counter results to EEPROM and reading them later, however, the duty cycle does not increase for every +1 increase of the duty cycle byte. I assume this is a resolution issue due to running at 48MHz?
I really need to smooth that out and give a very nice gradual increase in light over time.
Also, what is a good way to have the program wait for a pin to go high?
Currently I am using:
waitforon:
If PORTB.7 = 1 then 'on/off button pulled high = on
gosub rampup 'increments final_duty and outputs value to CCP1
endif
PORTC.0 = 1 'flash heartbeat LED
pause 100
PORTC.0 = 0
pause 100
If final_duty = limit then 'if returned to waitforon from rampup, then final_duty is at set limit, so move on to main program
goto main
endif
goto waitforon
Sometimes this will not move to rampup: or move on to main: but the heartbeat LED will always flash correctly.
This is the rampup subroutine.
rampup:
For final_duty = 1 to limit
delay = 1000 / limit
pause delay
CCP1CON = %00111100
PR2 = 44
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
CCPR1L=high_duty
CCP1CON = $0C
T2CON = 4
Next final_duty
return
Alright, last question of the day, I promise!
This is the main loop code. It works fine holding the current limit by pulse skipping. The current limit is set by comparing the ADC reading to a value stored in fb, 205 in this case, or about 175mA for this application.
The problem comes when the down button is pressed. Instead of lowering fb by 1 it goes to 100% duty cycle, and my current goes as high as the current limit is set on my bench power supply and I have to yank the power.
I thought by lowering, or raising the value in fb, I would be able to control the current limit? What is going on?
Code:main: If PORTB.6 = 1 then fb = fb - 1 If fb => 205 then fb = fb endif endif adcin 1, temp If temp > fb then final_duty = final_duty - 1 IF final_duty = 0 then final_duty = final_duty endif endif If temp < fb Then final_duty = final_duty + 1 If final_duty = 44 then final_duty = final_duty endif endif CCP1CON = %00111100 PR2 = 44 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 CCPR1L=high_duty CCP1CON = $0C T2CON = 4 goto main
Bookmarks