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 and frequency generator

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



Joined: 07 May 2011
Posts: 40
Location: Bulgaria

View user's profile Send private message

Pwm and frequency generator
PostPosted: Fri Mar 28, 2014 8:43 am     Reply with quote

I am trying to make a variable duty and variable frequency generator.
I use two pots connected to AN0 and AN1 adc channels.
Duty cycle should vary from 1% to 99% and the frequency - from 400Hz to around 2KHz.
I tryed following software method but the frequency range is not enough. Give me an idea how to increase the frequncy range without affecting the duty cycle.
My compiler version is 4.120.

Code:
#include <18F4550.h>
#device *=16
#fuses HSPLL,PLL5,CPUDIV1,NOWDT,MCLR,USBDIV,VREGEN,NOLVP
#use delay(clock=48000000)

#define PWM_OUT PIN_C1

#define TIMER0_PRELOAD 149
#define LOOPCNT fr

int16 fr=0,width=0;

#INT_TIMER0 
void tick_interrupt(void)
{
static int16 loop = LOOPCNT;
static int16 pulse;
 
set_timer0(get_timer0()+TIMER0_PRELOAD);
 
 if(--loop==0)
 {
  loop=LOOPCNT;
  pulse=width;
 }
  if(pulse)
  {   
   output_high(PWM_OUT);
   pulse--;
  }
  else output_low(PWM_OUT);
}

void main()
{
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1 | RTCC_8_BIT);
set_timer0(TIMER0_PRELOAD);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
setup_adc(ADC_CLOCK_DIV_64);
setup_adc_ports(AN0_TO_AN1);

while(true)

 set_adc_channel(0); 
 delay_us(25);
 fr=read_adc();
 
 if(fr>1022) fr=1023;
 if(fr<50) fr=50;
 
 set_adc_channel(1); 
 delay_us(25);
 width=read_adc();
 
 if(width<1) width=1;
 if(width>150) width=150;
 
}
}
alfaec



Joined: 26 Jul 2012
Posts: 5
Location: pistoia

View user's profile Send private message Send e-mail

PostPosted: Fri Mar 28, 2014 10:46 am     Reply with quote

Hi

I don't know if you can help you.

I'm using this interrupt timer routine where i modify the value of "pwm_tm" variable
in main.

Code:

#define PWM_TIMER    500     // duty cycle
#define PWM_OUT      PIN_C1

int1     pwm_so
int16    pwm_tm

#int_timer1
void pwm_clock(void) {
   
   if (pwm_so) {
      // OFF
      output_high(PWM_OUT);
      set_timer1(0xffff - (PWM_TIMER - pwm_tm));
   }
   else {
      // ON
      output_low(PWM_OUT);
      set_timer1(0xffff - pwm_tm);
   }
   pwm_so = ~pwm_so;
}

_________________
_______________________
Alessio Fabbri
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Fri Mar 28, 2014 11:38 am     Reply with quote

Quote:

1% to 99%


with what sort of resolution per step of PWM duty cycle change??

1% ?" 10 25% , .1% ????

what you want to do is a tall order ESPECIALLY with the 4550 as it is!

if i were trying to do such a thing - i believe i would use a 16F1509
with a maximally fast clock - for its NCO function - and use the nco
OUTput to drive two out of three modules interconnected in an 82C54 -
to get a phase locked , precise digital 'one shot'- for high resolution PWM control.

in short more circuitry and less PIC in the solution......
alfaec



Joined: 26 Jul 2012
Posts: 5
Location: pistoia

View user's profile Send private message Send e-mail

PostPosted: Sat Mar 29, 2014 2:16 am     Reply with quote

Hi asmboy

The frequency, using Timer0 as 16bit Timer, can vary from 6 MHz theoretically (1 bit resolution timer) to 91 Hz (2^16 preset timer).
Realistically, using 16 bit timer, you could vary from 23,4 kHz ( 2^8 preset timer to 183 Hz (2^15 bit preset timer), so the execution time of the interrupt does not affect the frequency.
The accuracy is very high.

I think that your pic has sufficient performance to do the job required.

Your problem is that you are using two pots that have an 8 bit resolution, so you cannot achieve the desired performance.
_________________
_______________________
Alessio Fabbri
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Mar 29, 2014 8:07 pm     Reply with quote

the OP's code setup for timer0 as 8 bit ,
will rollover every 21.3 uSecs -
or 256 I-cycles of the pic. the .LST file clearly shows in the area of the int handler that the INT steals even more cycles from the foreground.

based on the above-
it is difficult to see how this is going to allow the part of the program in MAIN() to be anything but severely impaired -jitter wise.
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