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

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



Joined: 13 Apr 2008
Posts: 2

View user's profile Send private message

PWM
PostPosted: Sun Apr 13, 2008 11:13 pm     Reply with quote

Hi,

i am new to CCS and have spent some trying to get an ir tx working, all i want to do at the moment is get a 38kHz PWM at 50% duty out of a 12F683. I have done this quite easily with mikroc but strugling with PICC. can anyone point me in the right direcion?

Thanks.
umka



Joined: 28 Aug 2007
Posts: 99
Location: New Zealand

View user's profile Send private message

PostPosted: Sun Apr 13, 2008 11:28 pm     Reply with quote

have a look at the examples that come with CCS. the one named EX_PWM should explain all you need to know
Guest








PostPosted: Mon Apr 14, 2008 1:02 am     Reply with quote

I have looked thorugh that code already and tried to modify it but i have no idea why i cant get a LED to it least come when i am mucking around with values, my code is:

Code:
#include <12F683.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOCPD                    //No EE protection
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOPUT                    //No Power Up Timer
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled

#use delay(clock=4000000)


void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   //setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_comparator(NC_NC);
   //setup_vref(FALSE);
   //setup_oscillator(False);


setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 128, 1);  // The cycle time will be (1/clock)*4*t2div*(period+1)
                                      // clock=4000000 and period=127 (below)
                                      //     (1/8000000)*4*1*128 =  0.000064s or 15.625 khz
set_pwm1_duty(100);

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 14, 2008 1:08 am     Reply with quote

Look at the .LST file after you compile your program. What do you see ?
CCS places a Sleep instruction at the end of main(). Your PIC is going
into sleep (power-down) mode. PWM doesn't work in power-down mode.
Quote:

... set_pwm1_duty(100);
0036: MOVLW 64
0037: BCF STATUS.RP0
0038: MOVWF CCPR1L
0039: SLEEP


You can prevent your program from executing the Sleep instruction
by placing a continuous loop at the end of main(). Example:
Quote:
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 128, 1);
set_pwm1_duty(100);

while(1);
}
Matro
Guest







PostPosted: Mon Apr 14, 2008 1:44 am     Reply with quote

Moreover you have to parameter the timer 2 with a "long int" if you want to use whole the range from 0 to 128.
As it is currently, the range is from 0 to 128/4 = 32
Code:

setup_timer_2(T2_DIV_BY_1, 128L, 1);


Matro.
Guest








PostPosted: Mon Apr 14, 2008 1:57 am     Reply with quote

Ok great it works thanks. Also i am having difficuty understanding how the following instructions below actually work and how to get 38kHz at 50% duty?

setup_timer_2(T2_DIV_BY_1, 128, 1);
set_pwm1_duty(100);
Matro
Guest







PostPosted: Mon Apr 14, 2008 2:06 am     Reply with quote

Anonymous wrote:
Ok great it works thanks. Also i am having difficuty understanding how the following instructions below actually work and how to get 38kHz at 50% duty?

setup_timer_2(T2_DIV_BY_1, 128, 1);
set_pwm1_duty(100);

The first set the timer 2 prescaler, overflow value, and postscaler.
The frequency will depend on each of these values and on the µC frequency.
The second set the pwm value, that "corresponds" to duty.
Duty cycle has to be calculate according to the timer 2 value.

In your case :
Code:

setup_timer_2(T2_DIV_BY_1,25,1);    //timer 2 will count to 26
set_pwm1_duty(5);    //to use for 8-bit resolution ; duty = 50%
set_pwm1_duty(20L);   //to use for 10-bit resolution ; duty = 50%

As you see I mistaken in my previous post. The "L" to say "long int" shall be placed in the set_pwm1_duty() (if a 10-bit resolution is needed) and not in timer 2 setup.

Matro.
Guest








PostPosted: Mon Apr 14, 2008 3:23 am     Reply with quote

ok i think i almost have it so with the flowing example:

setup_timer_2(T2_DIV_BY_1,25,1); //timer 2 will count to 26
set_pwm1_duty(5); //to use for 8-bit resolution ; duty = 50%
set_pwm1_duty(20L); //to use for 10-bit resolution ; duty = 50%

(1/4000000)*4*1*26=26us = 38kHz

50% duty = 26us/2 = 13us ????

how did you get 5 and 20L for 50% duty?

and what would one need to change T2_DIV_BY_1 to say 4 or 16 and what is the value 1 on the end of setup_timer_2() for?

Thanks.
Matro
Guest







PostPosted: Mon Apr 14, 2008 3:41 am     Reply with quote

Anonymous wrote:
ok i think i almost have it so with the flowing example:

setup_timer_2(T2_DIV_BY_1,25,1); //timer 2 will count to 26
set_pwm1_duty(5); //to use for 8-bit resolution ; duty = 50%
set_pwm1_duty(20L); //to use for 10-bit resolution ; duty = 50%

(1/4000000)*4*1*26=26us = 38kHz

50% duty = 26us/2 = 13us ????

how did you get 5 and 20L for 50% duty?

Indeed this value seems not correct. That was the one given by PCW wizard.
A correct thing should be :
Code:

set_pwm1_duty(13); // 8-bit resolution

or
Code:

set_pwm1_duty(52L);  // 10-bit resolution


Quote:

and what would one need to change T2_DIV_BY_1 to say 4 or 16 and what is the value 1 on the end of setup_timer_2() for?

Thanks.

The T2_DIV_X value is the prescaler, so it will change the frequency, but will keep the same duty and resolution.
The last value is the postscaler of the timer.

Matro.[/code]
Guest








PostPosted: Mon Apr 14, 2008 4:25 am     Reply with quote

ok thanks i got it. One other question, i would like the LED to change brightness in the way of a sine wave i have tries the code below but the LED stays on?

Code:
long int value, x;
float i;

void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   //setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_comparator(NC_NC);
   //setup_vref(FALSE);
   //setup_oscillator(False);

while(1){
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 25, 1); 
                                     
for(i=0;i<3100;i=i++)

x=104*sin(i); 

value=abs(x);                                 
set_pwm1_duty(x);
delay_ms(2);



}}
Guest








PostPosted: Mon Apr 14, 2008 4:27 am     Reply with quote

Sorry wrong code:

Code:
long int value, x;
float i;

void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   //setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_comparator(NC_NC);
   //setup_vref(FALSE);
   //setup_oscillator(False);

while(1){
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 25, 1); 
                                     
for(i=0;i<3.18;i=i=i+0.01)

x=104*sin(i); 
                               
set_pwm1_duty(value);
delay_ms(2);



}}
Ttelmah
Guest







PostPosted: Mon Apr 14, 2008 8:01 am     Reply with quote

Two problems.
First, remember that 'sin', will return -ve values as well as +ve ones. Your conversion to a PWM width, needs to handle this as well ((sin(i) * 52) + 52).
Second, think how long this all takes. Under 1 second for the whole cycle. You need to increase your delay quite a bit, if the cycle is going to be comfortably visible.
The first is probably what is stopping the change being seen. The -ve results, will result in a 'wrap' in the arithmetic, and +ve results that will turn the LED permanently 'on' through half the cycle. Given the speed of the whole cycle, the short dimmer periods are probably just not visible.

Best Wishes
stevenkrn



Joined: 13 Apr 2008
Posts: 2

View user's profile Send private message

PostPosted: Tue Apr 15, 2008 8:53 pm     Reply with quote

Hi its me again thanks for all your help.

I have spent the last 2 frustrating days to get this to work lol. I am trying to make the jar of fire flie: http://www.instructables.com/id/Jar-of-Fireflies/ and thought it was easier than first. My code so far is:

Code:


#include <math.h>
#define RAND_MAX 50
#include <stdlib.h>long int value;
unsigned int r1;
int r;
int val;
 
void main()
{

    setup_adc_ports(sAN1|VSS_VDD);
    setup_adc(ADC_CLOCK_INTERNAL);
    set_adc_channel(1);
    setup_comparator( NC_NC_NC_NC );
    setup_timer_1(T1_DISABLED);
    setup_ccp1(CCP_PWM);
    setup_timer_2(T2_DIV_BY_1, 25, 1);


while(1){

int i=0;
float x=0;
int y=0;

r=rand();  //generate a random number each cycle

output_a(r);  //output a random number to port a

 do{
              i=i+0.01;
              delay_ms(10);
              x=50*sin(i);    // 27 is the least value that can be used ?? why not 0?
              y=abs(x);
              set_pwm1_duty(y);
 
 
 }while(i<3.14);} //3.14(pi) one cycle
 
}
}


I have 3 LEDS connected to PINA0, PIN_A4, PIN_A5 with the grounds connected to CCP1. What i am trying to do at this point is for random LED/LEDs to gradually turn on then off like a sine wave. This does happen for some bazzaar reason for eg sometimes one LED gradually turns on then turns straight off without gradually decreasing brightness, as soon as this LED turns off another takes its place and this one gradually decreases. Another problem is i made x=r*sin(i); but r cannot be less than 27?? and when r of r*sin(i) changes so does the frequency? Its got me baffled.

Please help.
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