|
|
View previous topic :: View next topic |
Author |
Message |
sonicfire
Joined: 11 Feb 2007 Posts: 19 Location: Cedar Rapids
|
Unexpected method behavior? |
Posted: Mon Mar 12, 2007 7:43 am |
|
|
I've written the basic program architecture for a PIC 16F877 to control a buck converter. I tested this basic program with a potentiometer input and read the output with the oscilloscope. Everything was fine. However, yesterday, when I connected the PWM output from the PIC to the actual buck converter/dc motor setup, the PIC would stop functioning after a few seconds. I realized that I had a couple of methods that are meant to make the duty cycle 0%, but in my program they are forced to not do so. It seems that the methods are not always returning 0 when I use this in conjuction with the buck converter and dc motor. Can anyone explain why?
Code: | #include <16F877.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
void check_reset() {
int reset_value = 0;
while (reset_value==0) {
reset_value = input(PIN_B1); //delays circuit until user resets circuit (emits high signal to pin B1
}
}
int check_current() {
int16 current_value;
int32 scale = 100;
int overload;
set_adc_channel( 0 );
//delay_us(10); //may need this, but leave out for now
current_value = (read_adc()*scale)/1024; //for a 5V input signal, gives number between 0 and 100
if (current_value > 90) //NOT SURE WHAT THIS VALUE WILL BE YET, BUT 90 is probably a good guess
overload = 1;
else
overload = 0;
//return overload;
return 0;
}
int check_speed() {
return 0; //not sure how to handle this just yet...
}
void compare_with_user() {
int16 value1;
//int16 value2;
int32 scale = 100;
value1=(read_adc()*scale)/1024; //note, adc_channel should already be set to 0 from check_current method!
//set_adc_channel( 1 );
//delay_us( 10 ); //10uS delay is necessary for proper ADC reading.
//value2=(read_adc()*512)/1024;
//COMPARISON GOES HERE...
set_pwm1_duty(value1);
/* This sets the time the pulse is high each cycle.
The high time will be:
if value is LONG INT: value*(1/clock)*t2div
if value is INT: value*4*(1/clock)*t2div
for example a value of 30 and t2div of 1 the high time 12uS
A value too high or too low will prevent the output from changing.
*/
}
void main() {
int shutdown1;
int shutdown2;
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_1, 24, 1); //output at 50KHz
//Period = (1/clock)*4*t2div*(period+1)
setup_port_a(ALL_ANALOG);
setup_adc(adc_clock_internal);
while( TRUE ) {
shutdown1 = check_current(); //returns 0 if okay and 1 if overloaded
shutdown2 = check_speed(); //returns 0 if okay and 1 if it's too fast
if ( (shutdown1==0)&&(shutdown2==0) )
compare_with_user();
else {
set_pwm1_duty(0);
check_reset();
}
}
} |
|
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 12, 2007 11:13 am |
|
|
Seriously, you do not have any 'methods'. CCS C, is not an object orientated language... You have functions.
Now, you have functions that claim they are meant to return values, but don't. So (for instance), the 'check current' function, returns 0 all the time, no matter what happens inside it...
Now, having knocked these, the obvious comment is _noise_. The big difference now, is that there is energy flowing in the power circuits, and if te design of the supply to the PIC, isolation, and smoothing, is not adequate, 'anything can happen', with the most likely things being hanging, or resetting.
Best Wishes |
|
|
sonicfire
Joined: 11 Feb 2007 Posts: 19 Location: Cedar Rapids
|
|
Posted: Mon Mar 12, 2007 5:29 pm |
|
|
Given that the problem doesn't lie with my functions, the only thing I can think of is the connection of the PWM output to the switching transistors in the buck converter. If there is too high a demand on current, would this stop the pic from functioning correctly? Someone suggested using a buffer, but the simple one I devised was unable to retain the output shape. Any pointers? |
|
|
Ttelmah Guest
|
|
Posted: Tue Mar 13, 2007 3:32 am |
|
|
I'd suggest that the current demand is not the problem. The PIC will run with a short on the output. Not 'nice', but it won't stop the chip (but will introduce the RMW problem - the current code though, would not be affected by this problem). However far more likely to be the energy path when the motor coils switch off/on. Examples of designs that can give problems, would be:
1) Relying on the diode effect inside a FET to trap the energy on switch off - though power FETs all display a diode stucture, the energy handling ability, and recovery time of this, is generally not adequate to deal wth inductive spikes of a reasonable level - (some exceptions, Hitachi for example, make MOSFETs with a proper trap diode built in).
2) Inadequate capacitance on the rail receiving the energy. If a trap diode to a power rail is used, will the capacitance and loads be enough to ensure the voltage on this rail does not rise.
3) No trap diode at all. Can result in the energy routing into the driving logic...
4) Inadequate/poorly laid out grounds. If (for instance), the power component 'ground', runs back via the processor.
5) Poor design on the processor supply. Regulators, are effectively quite high gain amplifiers. As such, unless design is carefully done, they can be fairly unstable. If noise appears on the incoming rail, from power switching, this can lead to momentary oscillation, and problems
Best Wishes |
|
|
sonicfire
Joined: 11 Feb 2007 Posts: 19 Location: Cedar Rapids
|
|
Posted: Tue Mar 13, 2007 7:24 am |
|
|
The solution was right under my nose. It required a gate drive. All is well now. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|