CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PWM problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
saniat



Joined: 14 Mar 2015
Posts: 9

View user's profile Send private message

PWM problem
PostPosted: Tue May 19, 2015 11:17 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed May 20, 2015 5:28 pm     Reply with quote

Start by having a look at how long each of your instructions takes to execute.

Mike
temtronic



Joined: 01 Jul 2010
Posts: 9216
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed May 20, 2015 8:01 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed May 20, 2015 9:05 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed May 20, 2015 10:43 pm     Reply with quote

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: 19479

View user's profile Send private message

PostPosted: Thu May 21, 2015 12:53 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu May 21, 2015 4:34 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu May 21, 2015 10:40 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu May 21, 2015 10:52 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu May 21, 2015 11:17 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu May 21, 2015 11:51 am     Reply with quote

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: 19479

View user's profile Send private message

PostPosted: Thu May 21, 2015 1:45 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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