View previous topic :: View next topic |
Author |
Message |
saniat
Joined: 14 Mar 2015 Posts: 9
|
PWM problem |
Posted: Tue May 19, 2015 11:17 am |
|
|
i have generated two PWM signals and added a phase shift in the 2nd signal. the code works fine. but the problem is that i want to generate 50 us period signal. though i have given the delay in microsecond the two signals generated comes in millisecond range. i want high frequency PWM (20khz= 50us period) but the signals are in millisecond.
PS: you might be wandering why i am not using the PWM modules. i tried my best to generate phase shift between two PWM using CCP in 77a and power PWM+ CCP in 4431. i was unsuccessful
Code: | #include <16F877A.h>
#device adc=10
#include <math.h>
#fuses XT,NOWDT,NOLVP
#use delay(clock=20000000)
#include "flex.c"
void main()
{
//setup_adc_ports( ALL_ANALOG );
//setup_adc(ADC_CLOCK_INTERNAL);
//set_adc_channel( 0 );
int16 counter=0, period=50, shift=25;
int16 counter1=0;
while (1){
//shift= read_adc();
if(counter==0 || counter==period){ //starting the 1st PWM signal and restarting it after a cycle (a complete cycle is 50 us
output_high(pin_B6);
counter=0;
}
delay_us(1);
counter=counter+1;
counter1=counter1+1;
if(counter==period/2){
output_low(pin_B6);
}
if(counter1==shift || counter1==period+shift){ //starting the 2st PWM signal after the shift time has passed and restarting it after a cycle
output_high(pin_B7);
counter1=shift;
}
if(counter1==(period/2)+shift ){
output_low(pin_B7);
}
}
} |
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed May 20, 2015 5:28 pm |
|
|
Start by having a look at how long each of your instructions takes to execute.
Mike |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Wed May 20, 2015 8:01 pm |
|
|
I wonder why you're using an obsolete PIC ! Though I used them 20 years ago, newer PICs are cheaper,better,faster,....etc.
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 20, 2015 9:05 pm |
|
|
Quote: | #include <16F877A.h>
#device adc=10
#include <math.h>
#fuses XT,NOWDT,NOLVP
#use delay(clock=20000000) |
The oscillator fuse and the frequency show that you're not running this
in hardware. |
|
|
saniat
Joined: 14 Mar 2015 Posts: 9
|
|
Posted: Wed May 20, 2015 10:43 pm |
|
|
i understand now that i have some instruction delay in each line.
temtronic
can you suggest me advance 40 pin chip (if possible suggest me some coz i have to check my country has those chips or not) where instruction delay is much less.
PCM
how did you know? true i did not try it in hardware. i tried it in Proteus. i know you guys dont like proteus but what can i do i dont have access to hardware i have to take permission so i chose the best way i have to test |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu May 21, 2015 12:53 am |
|
|
Go back to the hardware approach.
All you will have to do, is tweak the timings a little, to allow for the setup instruction delays. You are going to have to do this for anything that requires 'tight' timing, and with the hardware it becomes a 'one time' calculation. trying to get this timing in software is just going to prevent the chip from doing anything else, and be a lot of work. As soon as the chip needs to do anything 'else' a timing will change, and everything will fall apart.
A faster PIC will help a little, and almost certainly be cheaper (newer PIC versions tend to be cheaper than their older brethren), but only a little. There is no PIC that is more than about 3* faster (for the PIC16/18).
Get your clock settings right. I'm surprised it is even working. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Thu May 21, 2015 4:34 am |
|
|
saniat wrote: | PCM
how did you know? true i did not try it in hardware. i tried it in Proteus. i know you guys dont like proteus but what can i do i dont have access to hardware i have to take permission so i chose the best way i have to test |
Because he very kindly highlighted your error in bold.
Presumably the PWM is a small part of a larger work.
You are telling us nothing else about what you are trying to achieve.
With so little to go on, it's difficult to help you any more.
Tell us.
1) The accuracy you want from the PWM.
2) The frequency and shift ranges required.
3) What other tasks the processor will have to do.
4) Anything else which is useful/important.
Mike
The code you presented includes a "delay_us(1)", in a loop.
I think you expected this to define your period as 50us.
Your code only spends 5% to 10% of its time in the delay.
Hence your ms period and severe disappointment.
You need a radical re-think. |
|
|
saniat
Joined: 14 Mar 2015 Posts: 9
|
|
Posted: Thu May 21, 2015 10:40 am |
|
|
1)could not understand what you mean by accuracy
2)PWM 20 khz shift range 0 to 180
3)processor has to do only ADC other than shift
thanks
saniat |
|
|
saniat
Joined: 14 Mar 2015 Posts: 9
|
|
Posted: Thu May 21, 2015 10:52 am |
|
|
Quote: | You are going to have to do this for anything that requires 'tight' timing, and with the hardware it becomes a 'one time' calculation |
could not understand this sentence?
thanks saniat |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Thu May 21, 2015 11:17 am |
|
|
saniat wrote: | 1)could not understand what you mean by accuracy
2)PWM 20 khz shift range 0 to 180
3)processor has to do only ADC other than shift
thanks
saniat |
1) How much wobble are you expecting in your 50us pulses?
2) I assume you mean 0 to 25us delay between pulses.
Mike
Have you actually got any hardware and which real processor are you using?
When you use a real chip you will probably find that the pulses vary in width and duty ratio, unless you use the built in hardware PWM. |
|
|
saniat
Joined: 14 Mar 2015 Posts: 9
|
|
Posted: Thu May 21, 2015 11:51 am |
|
|
1. moderate wobbling is fine but not too much
2. yes 0 to 25 us
i currently have 77a and 4431. and no i actually did not try it in hardware only used proteus. my prof wants to see the result in proteus 1st, thats the problem. i showed him in proteus his only complain was period is too low |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu May 21, 2015 1:45 pm |
|
|
The time it takes to load the registers of the two timers (if using hardware), is a fixed amount. So calculate/measure this, then just adjust the time to correct for this.
If (for instance) it takes 10 machine instructions to load the second timer after the first, and you want a delay of 10uSec, then (since at 20MHz, you are running at 5MIPS), load one timer, then delay_cycles(40);
10uSec=50 instructions
delay for the timer update = 10 instructions, so 40 cycles will then give 10uSec.
Since the offset is constant, you can do this calculation in code if you want a variable time.
So:
cycles_required = uSec*5
delay_required = cycles_required-10 (assuming this is the measured error).
load the first timer.
delay for 'delay_required'
load second timer.
Obviously the calculation must be done outside the actual update of the delays (as shown). Since it takes quite a few cycles _minimum_ to perform any delay (especially one with a variable), you may well get a better solution using a state machine with fixed delays for the lower values. |
|
|
|