View previous topic :: View next topic |
Author |
Message |
M.Yasser
Joined: 26 Jul 2011 Posts: 9
|
interaction problem (CCP1 and CCP2) |
Posted: Sun Feb 12, 2012 5:40 pm |
|
|
Hi,
I’m trying to control the width of a 2 PWM signals using potentiometers. One pot is connected to analog input AN0 and the other is connected to analog AN1 as shown in the schematic below.
I’ve experienced a weird problem. If the pot connected to AN1 is supplying 0v, the other pot can adjust the width of ccp1 to less than 50% duty max. On the other hand if I vary AN1 pot while AN0 pot is supplying 5v and readings on ccp1 is less than 50%, ccp1 will be affected by AN1 pot and may reach 100% duty.
Vice versa is also true (i.e. adjusting AN0 pot affect ccp2 duty).
The code for the real circuit is below.
XTAL=20MHz
Programmer is PICkit3
Compiler v 4.120
How can I solve the interaction problem?
Regards.
Code: | #include <16F887.H>
#fuses HS, NOWDT, NOLVP ,NOPROTECT
#use delay(clock=20000000)
void Initial();
void main()
{
int v1,v2;
Initial();
while(TRUE)
{
delay_ms(3);
set_adc_channel(0);
v1 = read_adc();
delay_ms(5);
set_pwm1_duty(v1);
delay_ms(3);
set_adc_channel(1);
v2 = read_adc();
delay_ms(5);
set_pwm2_duty(v2);
}
}
void Initial()
{
setup_ccp1(CCP_PWM); // Setup ccp1 as pwm1
setup_ccp2(CCP_PWM); // Setup ccp2 as pwm2
setup_timer_2(T2_DIV_BY_16,255,1); // The cycle time will be (1/clock)*4*t2div*(period+1)
// In this program clock=20000000 and period=127 (below)
// (1/20000000)*4*16*256 = 819.2 us or 1.220703125 khz
setup_adc_ports(sAN0|sAN1); // Set ports A0 and A1 as analog
setup_adc(ADC_CLOCK_INTERNAL); // ADC is inernally generated
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 12, 2012 6:24 pm |
|
|
Quote: | delay_ms(3);
set_adc_channel(0);
v1 = read_adc();
delay_ms(5);
set_pwm1_duty(v1);
delay_ms(3);
set_adc_channel(1);
v2 = read_adc();
delay_ms(5);
set_pwm2_duty(v2); |
You need to add a delay of at least 5 usec after you set the A/D channel.
You don't have it and that's likely why you have the problem. You need
the delay in two places in the code above. For safety you might want
to use a 10 usec delay.
See this section in the 16F887 data sheet:
Quote: |
9.3 A/D Acquisition Requirements
|
|
|
|
M.Yasser
Joined: 26 Jul 2011 Posts: 9
|
|
Posted: Mon Feb 13, 2012 6:40 am |
|
|
Hi PCM programmer,
Thank you for your fast and informative reply. You solved my problem
I’ve read section 9.3 of the data sheet, but I’m curious why the interaction happened? It’s supposed that ADC unit won’t have the time to complete setup and only one of the CCP units will be affected?
I’m still learning about microcontroller, and I appreciate every single comment concerning the issue, starting from code writing style …
Regards. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Mon Feb 13, 2012 8:07 am |
|
|
Nothing to do with 'setup'. Purely electrical.
Internally the ADC, is a small capacitor in series with a resistor, fed by the multiplexer. 'Set_adc_channel', connects the required incoming voltage to the capacitor, which then takes _time_ to charge to (nearly) match the voltage. The time taken to charge to within one 'bit level', is given in the data sheet.
Now, ignoring the first sample for a moment, after this the adc is connected to input 0 from the first selection. You then delay, so the ADC capacitor is now charged to be really close to the channel 0 voltage, connect the adc to channel 1, and immediately read it. The voltage you get will reflect the value on channel 0, with a _tiny_ affect from the channel 1 voltage (probably about 1/10th the difference). The same then happens the 'other way round', when you go back to read channel 0.....
Best Wishes |
|
|
M.Yasser
Joined: 26 Jul 2011 Posts: 9
|
|
Posted: Mon Feb 13, 2012 11:56 am |
|
|
Thank you Ttelmah,
Your explanation seems logical to me.
Regards. |
|
|
|