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 with changing frequency
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PWM with changing frequency
PostPosted: Thu Dec 03, 2015 6:33 am     Reply with quote

Hi everybody.
I'm have a problem when tried to create a PWM signal with frequency change like as an image.
I'm using PIC16F877A and CCS C ver 5.021
Can give me a solution to make it because I only create a PWM signal with fixed frequency.
Thanks you.

https://drive.google.com/file/d/0Bz215_lkn4g-SUg1WVE1M0NobGs/view?usp=sharing
_________________
Begin Begin Begin !!!
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Thu Dec 03, 2015 7:28 am     Reply with quote

You've been here a while now, so should know the form.

You must show us short complete compilable code we can copy and paste to test.

Also, I can't tell what it is you are trying to achieve.

Do you want (say) a constant 60% duty ratio over a range of frequencies?
As it stands you are not giving us enough to work on. Please be more specific.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Thu Dec 03, 2015 8:50 am     Reply with quote

Also try searching the forum.
This has been discussed before.

The PWM, is not very suitable for variable frequencies. Low resolution, and limited range. Some chips offer a better range. The CCP can be used to do this, but still quite 'code heavy'. However some PIC's have the NCO module, and this is much more suitable for this
temtronic



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

View user's profile Send private message

PostPosted: Thu Dec 03, 2015 9:00 am     Reply with quote

OK, I have to ask what your application is that requires both PWM and VF ?

I'm thinking the algorithm needed to do BOTH functions could be 'intensive' and the 877 wouldn't be the correct PIC for the job.


Jay
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Dec 04, 2015 2:40 am     Reply with quote

Thanks for your solutions.
Sorry because I'm used PWM phrase to introduce for the signal.
I think it a PWM signal but not sure.
Can you check it again?
About this circuit, I'm want to make a pulse generator circuit with output same the waveform in a picture using PIC ( a current version using AT89S51 IC).
So that, now i'm looking a solutions to make it with a PIC MCU.
I need helping from all you.
Thanks you.

https://drive.google.com/file/d/0Bz215_lkn4g-S1ZmVllYcG1NSzA/view?usp=sharing
_________________
Begin Begin Begin !!!
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Dec 04, 2015 5:47 am     Reply with quote

OK.

I can see your waveform trace.
You've got a sort of gated pulse generator.

You've still not told us what it's for.

Which properties of the waveform are you wanting to change/control?

Mike
temtronic



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

View user's profile Send private message

PostPosted: Fri Dec 04, 2015 6:25 am     Reply with quote

Mike's right ! We need more information.That waveform you showed us doesn't vary the frequency,just a simple gated pulse genny.

Jay
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Dec 04, 2015 12:09 pm     Reply with quote

You've already programmed a device to get what you want.
Surely you know what you did.
You should then be able to translate to PIC 'C'.
I don't see why you need us.

Mike
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Mon Dec 07, 2015 1:25 am     Reply with quote

Thanks for yours helping:)
In this project, I must make a circuit to generate pulse same the waveform in the picture above.
The original circuit in sewing machine of my sister, is using for control Triac through PWM signal to drive an AC motor. Now, It's stopped procecude, I can't buy a new to replace so that i think make a new circuit to backup for tomorow.
Because i check the signal with ossciloscope, saw an delay time in waveform, so that I not sure is it a PWM signal.
I dont know that oscciloscope measure PWM frequency is included a delay time or not?
I'm checking a PWM signal frequency to try programe on PIC16F877A/or PIC16F684.
I uploaded an new picture, please reference it and helping me how to creat this signal, in my solution, i think creat a PWM signal, with number of period is change, then, insert a delay, and continues with PWM, ..delay ... PWM... delay..
Pls help me.
Thanks you.
https://drive.google.com/file/d/0Bz215_lkn4g-bWNWY0dJQTExb3c/view?usp=sharing
_________________
Begin Begin Begin !!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Dec 07, 2015 2:19 am     Reply with quote

There is no need for PWM to drive a TRIAC. The way TRIAC's work, you need a signal synchronised to the mains. which is a pulse at an interval _before_ the next zero crossing. The TRIAC then turns 'on', and remains on until the zero crossing. If you turn it on right at the start of the cycle, you get full power (with the TRIAC being on for the entire cycle). Generate the pulse just before the zero crossing, and you get almost no power (with the TRIAC being on just for a small moment).
There are different output topologies, depending on how the motor is actually connected. Many devices like sewing machines, actually use DC motors, with the TRIAC circuit being followed by a full-wave rectifier that actually feeds the motor. This might be what is involved, since then you can effectively just use a PWM to control a rough percentage of the time the TRIAC is 'on', and vary the DC drive this way.

Have a look at this application note:
<http://www.st.com/st-web-ui/static/active/jp/resource/technical/document/application_note/CD00003829.pdf>

This shows the two commonest TRIAC topologies (and an IGBT one). The ST6210 involved here might well be the easiest way to go (don't re-invent the wheel....). If you want complex control, just feed this with a DC voltage synthesised from the PIC PWM. Big advantage is that this handles all the AC sync etc., for you. Smile
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Dec 11, 2015 5:01 am     Reply with quote

Thanks for your supporting Smile
About this circuit, I want to know clearly about a signal, is it a PWM signal or not?
Because it have a delay between string of pulse.
Really I want to know about characteristics of this signal.
Pls ref video I check it.
Thanks you.
https://youtu.be/5Mbo8kJIaL4
_________________
Begin Begin Begin !!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Dec 11, 2015 10:06 am     Reply with quote

It's not a PWM really. It is string of trigger pulses for the TRIAC, with the string being turned on for a while (to have the output 'on' for most of the time), then off for a while. The pulse width doesn't change, and the way it is done, will give noticeable buzzing of the motor, unless the motor is DC. In which case the output will be integrated to give the DC for the motor.
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Thu Dec 17, 2015 7:55 pm     Reply with quote

Ttelmah wrote:
It's not a PWM really. It is string of trigger pulses for the TRIAC, with the string being turned on for a while (to have the output 'on' for most of the time), then off for a while. The pulse width doesn't change, and the way it is done, will give noticeable buzzing of the motor, unless the motor is DC. In which case the output will be integrated to give the DC for the motor.

Thanks for your answers Smile
Yes, you true. I'm checked again and it's a DC motor. The first time I careless when think a AC motor when saw it supply by AC power direct.
About my plan, I choosed pic16F684 to program, but when i process with ADC, it take me more ROM, because i use a float variable to processing.
Now can I processing ADC without float variable, I also tried processed with step ADC but its still a float result.
Code:
   setup_adc_ports(sAN3);   
   setup_adc(ADC_CLOCK_DIV_8);     
   set_adc_channel(3); 
   delay_us(100);
   volt_adc= read_adc();
   volt-in= volt_adc*0.0045;


processing code:

Code:
    if( (volt_in>=1.7) && (volt_in<=1.9) )              {  pos_width=11396; neg_width=11802; loop=1; pulse_delay=0;}
...
....
many condition statement like as above made code take a more ROM
...

Pls help me to minimum a code Smile
Thanks you.
_________________
Begin Begin Begin !!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Dec 18, 2015 1:49 am     Reply with quote

There are a lot of threads here showing integer ways of doing things like this.

It is though down to how you 'think'.

You are solving to get a 'voltage', in 'volts', so for something like 2.5 volts, 'of course' the result has to be a float. However change your code, so instead you work in mV, and then 2.5v, then becomes a nice integer number (2500). Your multiplication, instead of being *0.0045, becomes *4.5, which solves more in integer, as *4 plus *1/2.
There is also something wrong, you seem to be trying to use volt-in as a variable - presumably volt_in....

Code:

   int16 mvolt_in, volt_adc;

   setup_adc_ports(sAN3);   
   setup_adc(ADC_CLOCK_DIV_8); 
   
   set_adc_channel(3);
   delay_us(100);
   volt_adc= read_adc();
   mvolt_in = volt_adc*4;
   mvolt_in += volt_adc/2;


This then gives *4.5, involving only an integer multiplication by 4, and an integer division by 2. Both done by just simple rotations.

Start to think in terms of 'counts', 'mV', and similar integer values, instead of 'volts' etc...

Have a look at this thread:
<http://www.ccsinfo.com/forum/viewtopic.php?t=54661>

Which gives an output which displays as N.NNN, yet works in integers all the way!.
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Dec 18, 2015 9:38 pm     Reply with quote

Thanks for your answers Smile
About this problem, I change to read a step ADC for read a voltage.
But now i have a problem when not enough ROM to write a program, I amazing when CCS build a code take a more ROM or my program not optimized.
I'm using PIC16F684 and CCS C ver 5.044
Here is code which I build take a 85% ROM, it not finish code.

Code:

#include <16F684.h>
#device ADC=10

#FUSES PUT                      //Power Up Timer
#FUSES PROTECT                  //Code protected from reads
#FUSES NOCPD                      //Data EEPROM Code Protected
#FUSES NOBROWNOUT               //No brownout reset
#FUSES MCLR
#FUSES NOWDT
#FUSES NOIESO
#FUSES NOFCMEN
#FUSES INTRC_IO

#use delay(internal=8000000)

#define led_dbg PIN_A2
#define pulse   PIN_C0

//!#define mode1  input(PIN_C2)
//!#define mode2  input(PIN_C3)
//!#define mode3  input(PIN_C4)
//!#define mode4  input(PIN_C5)
//!// ngoai tru 4 mode se roi vao mode 0

unsigned int16 volt_adc=0;
unsigned int16 pos_width=0, neg_width=0;
unsigned int8 loop=0;
unsigned int32 pulse_delay=0;
//!unsigned int16 pulse_delay1=0, pulse_delay2=0;
unsigned int8 tick_t0=0;
unsigned int1 check_adc=0;
unsigned int8 mode=0;
//--------------------------------------------------------------------------------------------------------------------------
#int_timer0
void ngat_timer0(void)
{
      set_timer0(0);
      tick_t0++;                 
      if(tick_t0==10)
      {
         tick_t0=0;
         check_adc=1;
      }
}

//--------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------
void out_pulse( void)
{
   unsigned int8 i_loop;
   for( i_loop=1; i_loop<=loop; i_loop++)
   {
      output_high(pulse);
      delay_us(pos_width);
      output_low(pulse);
      delay_us(neg_width);
   }
   if(pulse_delay !=0)
   {
      if(pulse_delay>65535)
      {
         delay_us(pulse_delay-65535);
         delay_us(65535);
      }
      else
         delay_us(pulse_delay);
     
   }

}
//--------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------
void main()
{
   setup_oscillator(OSC_8MHZ | OSC_INTRC); 
   delay_ms(500);   
   
   set_tris_a(0x10);
   set_tris_c(0x3c);
   
   setup_adc_ports(sAN3|VSS_VDD);   
   setup_adc(ADC_CLOCK_INTERNAL);     
   set_adc_channel(3); 
   delay_us(100);    //you need this before the first reading
   volt_adc= read_adc();
   
   set_timer0(0);                                                               // setup timer0: 30ms-- tao tre chong bam counter: 5ms F_cystal=40MHZ   
   setup_timer_0 (RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);   
   enable_interrupts(int_timer0);
   enable_interrupts(global);
 
   
   while(TRUE)
   {
         //----------------------------------------------------------------------------------------------------------
         if(input(PIN_C2)==0) mode=1;
         else if(input(PIN_C3)==0) mode=2;
         else if(input(PIN_C4)==0) mode=3;
         else if(input(PIN_C5)==0) mode=4;
         else mode=0;
         //----------------------------------------------------------------------------------------------------------
         if(check_adc==1)
         {
            volt_adc= read_adc();
            check_adc=0;
            tick_t0=0;
         }
         // ---------------------------------------------------------------------------------------------------------
         if( mode==0)
         {
            pulse_delay=0;
            loop=1;
         }
         else if(mode==1)
         { 
            pos_width=2510;
            neg_width=3374;
           
            if(volt_adc>=0 && volt_adc<=151) {  loop=2; pulse_delay=89581;}
            else if(volt_adc>884) {  loop=15; pulse_delay=7205;}
           
         }
         else if(mode==2) {  pos_width=2187; neg_width=3059;}
         else if(mode==3) {  pos_width=7111; neg_width=8000;}
         else if(mode==4) { }
         








         // ---------------------------------------------------------------------------------------------------------
         if( (volt_adc>=0) && (volt_adc<=40) )               
         { 
            if(mode==2)  {}
            else if(mode==3)  {}
            else if(mode==4)  {}
            else               {  pos_width=11197; neg_width=11557;}
           
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>40 && volt_adc<=43)             
         { 
            if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}         
            else              {  pos_width=10800; neg_width=11209;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>43 && volt_adc<=59)             
         { 
            if(mode==2) {}   
            else if(mode==3) {}
            else if(mode==4) {}             
            else              {  pos_width=10796; neg_width=11000;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>59 && volt_adc<=78)             
         { 
            if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}           
            else              {  pos_width=10596; neg_width=10809;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>78 && volt_adc<=110)           
         { 
            if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}         
            else              {  pos_width=10202; neg_width=10606;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>110 && volt_adc<=151)           
         { 
            if(mode==2)      {}
            else if(mode==3) {}
            else if(mode==4) {}               
            else              {  pos_width=9995;  neg_width=10208;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>151 && volt_adc<=210)           
         { 
            if( mode==1)    { loop=3; pulse_delay=83697;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else              {  pos_width=9395;  neg_width=9608;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>210 && volt_adc<=267)           
         { 
            if( mode==1)    { loop=4; pulse_delay=77813;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}         
            else              {  pos_width=8795;  neg_width=9008;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>267 && volt_adc<=327)           
         { 
            if( mode==1)    { loop=5; pulse_delay=71929;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else              {  pos_width=8195;  neg_width=8608;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>327 && volt_adc<=379)           
         { 
            if( mode==1)    { loop=6; pulse_delay=66045;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else              {  pos_width=7595;  neg_width=8001;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>379 && volt_adc<=430)           
         { 
            if( mode==1)    { loop=7; pulse_delay=60161;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else              {  pos_width=6994;  neg_width=7602;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>430 && volt_adc<=481)           
         { 
            if( mode==1)    { loop=8; pulse_delay=54277;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else              {  pos_width=6401;  neg_width=7001;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>481 && volt_adc<=547)           
         { 
            if( mode==1)    { loop=9; pulse_delay=48393;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else              {  pos_width=5994;  neg_width=6407;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>547 && volt_adc<=599)           
         { 
            if( mode==1)    { loop=9; pulse_delay=42509;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else              {  pos_width=5394;  neg_width=5807;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>599 && volt_adc<=657)           
         { 
            if( mode==1)    { loop=10; pulse_delay=36625;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else              {  pos_width=4994;  neg_width=5207;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>657 && volt_adc<=716)           
         { 
            if( mode==1)    { loop=11; pulse_delay=30741;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else                       {  pos_width=4394;  neg_width=4607;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>716 && volt_adc<=766)           
         { 
            if( mode==1)    { loop=12; pulse_delay=24857;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}         
            else              {  pos_width=3594;  neg_width=4007;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>766 && volt_adc<=833)           
         { 
            if( mode==1)    { loop=13; pulse_delay=18973;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}         
            else              {  pos_width=3194;  neg_width=3607;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>833 && volt_adc<=884)           
         { 
            if( mode==1)    { loop=14; pulse_delay=13089;}
            else if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}         
            else                       {  pos_width=2594;  neg_width=3007;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>884 && volt_adc<=917)           
         { 
            if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}         
            else                       {  pos_width=2394;  neg_width=2607;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>917 && volt_adc<=952)           
         { 
            if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else                       {  pos_width=1993;  neg_width=2406;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>952 && volt_adc<=968)           
         { 
            if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else                       {  pos_width=1606;  neg_width=2200;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>968 && volt_adc<=980)           
         { 
            if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}         
            else                       {  pos_width=1593;  neg_width=2000;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>980 && volt_adc<=991)           
         { 
            if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else                       {  pos_width=1400;  neg_width=2000;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>991 && volt_adc<=1004)         
         { 
            if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else                       {  pos_width=1400;  neg_width=1806;}
         }
         //---------------------------------------------------------------------------------------------
         else if ( volt_adc>1004)                           
         { 
            if(mode==2) {}
            else if(mode==3) {}
            else if(mode==4) {}             
            else                       {  pos_width=1202;  neg_width=1607;}
         }
         out_pulse();
       
   }

}

_________________
Begin Begin Begin !!!


Last edited by tienchuan on Mon Dec 21, 2015 3:22 am; edited 1 time in total
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
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