|
|
View previous topic :: View next topic |
Author |
Message |
jaybmiller Guest
|
complement of PWM function |
Posted: Mon Mar 01, 2010 4:41 pm |
|
|
OK, it's been awhile since I've coded and need some help. Basically I want to PWM one LED off---on---off while the other is the exact opposite.
Code: | #include <12f683.h>
#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOMCLR
#use delay(clock=4000000) // 4MHz xtal
//================================
void main()
{
int8 value;
int8 i;
int8 adcdata;
setup_ccp1(CCP_PWM);
// Set the PWM frequency for 244 Hz (with a 4 MHz crystal)
setup_timer_2(T2_DIV_BY_16, 255, 1);
setup_port_a(sAN0);
setup_adc(ADC_CLOCK_DIV_8); // Divisor for 4 MHz crystal
set_adc_channel(0);
delay_us(20);
while(1)
{
adcdata=read_adc();
for(i=0;i<adcdata;i++)
{
delay_ms(50);
value=i;
set_pwm1_duty(value);
if(input(PIN_A3)) output_bit(PIN_A5,0);
if(!input(PIN_A3))output_bit(PIN_A5,1);
}
for(i=adcdata;i>0;i--)
{
delay_ms(50);
value=i;
set_pwm1_duty(value);
if(input(PIN_A3)) output_bit(PIN_A5,0);
if(!input(PIN_A3))output_bit(PIN_A5,1);
}
// }
}//end of while(1) loop
}//end of main
Pin_a2 is tied back to Pin-A3.
Pin_A2(ccp output) works great, but Pin_A5 is NOT the exact opposite,it flashes instead. So, what's wrong with my IF statements?
I do not want to add a silly discrete invertor(7404) to the PIC.
ccs c version 4.064,mplab 7.51, pic12f683
Thanks for any help
Jay
|
|
|
|
Ttelmah Guest
|
|
Posted: Tue Mar 02, 2010 3:46 am |
|
|
Think about it.
Your minimum time interval between tests on the PWM pin, is over 50mSec. 20Hz. How can it follow a signal over ten times as fast?....
You need to be testing significantly _faster_ than the PWM frequency.
Your tests are unecessarily complex. the pin is either high or low. You can do the entire test and output in a single test.
Code: |
int8 loop;
adcdata=read_adc();
for(i=0;i<adcdata;i++) {
set_pwm1_duty(i); //Why waste time copying the value to another...
for (loop=0;loop<100;loop++) {
output_bit(PIN_A5,!input(PIN_A3));
delay_us(38);
}
}
|
Instead of delaying for 50mSec, the code sits in a fast loop, 'copying' the pin. The tests, and loop count, will take about 12uSec, so 100 loops, will give a total delay close to the 50mSec you were using.
The 'flash' you are seeing on the second LED, is the 'beat' between the sample interval, and the PWM interval.
Best Wishes |
|
|
jbmiller
Joined: 07 Oct 2006 Posts: 73 Location: Greensville,Ontario
|
|
Posted: Tue Mar 02, 2010 2:18 pm |
|
|
Many thanks for the prompt and informative reply, with your help I've got it working like a charm.
Now, if you could fix the guts that came out of my riding lawn tractor last night !
Cheers
Jay |
|
|
Boyce
Joined: 07 Feb 2010 Posts: 39
|
|
Posted: Tue Mar 02, 2010 10:27 pm |
|
|
I just came up with this code tonight. It may be useful.
Code: | /*******************************
PCW 4.104 PIC 16F690
This gives me the performance I am looking for to do microstepping.
It gives two sets of two outputs. Each set has one rise while the
other falls as needed to microstep from one motor pole to the next.
Boyce
********************************/
for(;;)
{ if(q>=period){q=0; C++; }
delay_ms(1);
//P1A=C5 P1B=C4 P1C=C3 P1D=C2
if(C==0)
{ set_pwm1_duty(q);
setup_ccp1(CCP_PWM_L_H | CCP_PULSE_STEERING_A | CCP_PULSE_STEERING_B);
}//end if(C=0)
if(C==1)
{ set_pwm1_duty(q);
setup_ccp1(CCP_PWM_H_L | CCP_PULSE_STEERING_A | CCP_PULSE_STEERING_B);
}//end if(C=1)
if(C==2)
{ set_pwm1_duty(q);
setup_ccp1(CCP_PWM_L_H | CCP_PULSE_STEERING_C | CCP_PULSE_STEERING_D);
}//end if(C=1)
if(C==3)
{ set_pwm1_duty(q);
setup_ccp1(CCP_PWM_H_L | CCP_PULSE_STEERING_C | CCP_PULSE_STEERING_D);
}//end if(C=1)
if(C>=4) C=0;
q++;
}//end for |
_________________ [email protected] |
|
|
|
|
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
|