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

4 KHz PWM without CCP module - help

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



Joined: 08 May 2008
Posts: 3

View user's profile Send private message

4 KHz PWM without CCP module - help
PostPosted: Mon Jun 16, 2008 12:07 pm     Reply with quote

I am a beginner with pic, i am trying to make a device that generate a 4 KHz PWM with variable duty cycle (controlled via a potentiometer) using a device that does not have hardware pwm inside.
I wrote this code, it works but the duty cycle changes only by 4 steps. I guess it cannot withstands all the instructions in the main program. Does anybody can suggest a simple routine for generate the pwm even with a lower resolution, with 4 khz frequency?
Thanks to all!
Code:

#include <12f675.h>
#DEVICE ADC=8
#use delay(clock=4000000)

#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT,  NOCPD, NOMCLR


int8 duty;

void main()
{
setup_adc(ADC_CLOCK_INTERNAL);              //enables the a/d module and sets the clock to internal adc clock
setup_adc_ports(sAN0);                //sets all the adc pins to analog

set_adc_channel(0);       
delay_us(10);
OUTPUT_LOW  ( PIN_A2 );
OUTPUT_LOW  ( PIN_A3 );


setup_timer_0 ( RTCC_INTERNAL | RTCC_8_BIT | RTCC_DIV_1 );
enable_interrupts ( INT_RTCC );             
enable_interrupts ( GLOBAL );               
set_timer0 ( 0 );                           



while(1)
   {
   
      duty=read_adc();
     
     
   if (duty<=5)         //bicolor led
      {
      duty=0;
      OUTPUT_HIGH ( PIN_A2 );
      OUTPUT_LOW  ( PIN_A3 );
      }
   if (duty>=250)      //bicolor led
      {
      duty=255;
      OUTPUT_LOW  ( PIN_A2 );
      OUTPUT_HIGH ( PIN_A3 );
      }
   
   if ((duty!=255)&&(duty!=0))
      {
      OUTPUT_LOW  ( PIN_A2 );
      OUTPUT_LOW ( PIN_A3 );
      }
   
   if ((get_timer0()<=duty)&&(duty!=0))   // pwm
      {
      OUTPUT_HIGH ( PIN_A1 );
      }
   
   else
      {
      OUTPUT_LOW ( PIN_A1 );
      }
   
   }
   
}


/*****************************************************************************************************/
#INT_RTCC
void TIMER_INTERRUPT ( void )
   {
   set_timer0 ( 0 );
   
   }
   

_________________
Paul
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Mon Jun 16, 2008 5:33 pm     Reply with quote

OK, here's an idea, not complete but perhaps it's a starting point.

With a 4MHz oscillator, you're executing 1 instruction per microsecond. That gives you 250 instructions (or 256 if you're willing to be inaccurate) per 1/4000 seconds. It's way too slow to do much with interrupts, so don't use them.

Start the timer but don't enable interrupts.

Set up the ADC for left-justified output, and start a loop like this:
Code:

  while (1)
  {
    if (tmr0 < adresh)                // Counter high enough to turn off the output?
   {
      OUTPUT_LOW  ( PIN_A2 );     // Yes
      OUTPUT_HIGH ( PIN_A3 );
    }
    else
   {
      OUTPUT_HIGH ( PIN_A2 );     // No
      OUTPUT_LOW ( PIN_A3 );
    }

    if (!bit_test(adcon0, 1))         // Last ADC reading done?
      bit_set(adcon0, 1);             // Yes, start a new one
  }


This is very much rough-and-ready code, and in particular you won't see an output that's always 0 for a zero ADC reading, but it should show a reasonable change in duty cycle. The key point is that the counter runs whether it triggers an interrupt or not, and you can use its value to compare with the desired duty cycle, and set the output accordingly. Actually I said "triggers an interrupt", and it will always trigger the interrupt flag, but your program doesn't need to respond to that flag or even look at it. Note also that the ADC output is used directly as the desired duty cycle, in the interests of saving time.

I hope this is sane, even if it's not exactly correct!
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