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

16f877a with pwm

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



Joined: 16 Jan 2008
Posts: 4
Location: Kuala Lumpur, Malaysia

View user's profile Send private message

16f877a with pwm
PostPosted: Tue Feb 05, 2008 1:11 am     Reply with quote

hi..
i need a help to recheck my programming. i need to produce output frequency at 5kHz. the problem is when i build the pic 16f877a into circuit, the led is not blinking.

Here the code:

#include <16f877a.h> // load the header file for PIC16F877A
#include <stdlib.h>
#include <math.h>

#use delay (clock=20000000) // The oscillator frequency = 20MHz,
// System clock = Fosc/4 = 5MHz, the clock time is 0.2us
#fuses HS, NOPROTECT, NOWDT, NOLVP

#byte PORTA = 5
#byte PORTB = 6

int8 A1_pressed = FALSE;

void main()
{
set_tris_a(0xff); // Set PORT A as inputs
set_tris_b(0x00); // Set PORT B as outputs
PORTB=0; // Initialize all PORT B output to 0 volt

output_low(PIN_B1); // Set CCP1 output low

setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM


while(TRUE) // sama dgn while ( 1== 1) - loop forever
{

if(A1_pressed == TRUE) // sama dgn while (0 == A4_pressed)

{
output_high(PIN_B5); // LED turn ON

setup_timer_2(T2_DIV_BY_4, 249, 1); ///////////////////////////////////////////////////
// 5 kHz //
// period = Fosc/(Fpwm*4*T2DIV)-1 //
// >> setup_timer_2(T2_DIV_BY_X,period,1); //
// //
// value = (duty_cycle% * Fosc)/(Fpwm*4*T2DIV) //
// >> set_pwm1_duty(value); //
// //
///////////////////////////////////////////////////

set_pwm1_duty(50); // 50% duty cycle on pin B1
delay_ms(2000); // delay 2 second

}

else

{
output_low(PIN_B5); // LED turns OFF
delay_ms(1500); // delay for 1.5 seconds
}
}

}
Ttelmah
Guest







PostPosted: Tue Feb 05, 2008 3:26 am     Reply with quote

First, edit your post, use the 'code' buttons, and disable HTML. As it stands, large amounts of the code are 'lost', because they are seen as HTML, and scrambled on the display.....
Second minor comment. Your duty cycle calculation is 'wrong'. With a maximum count on the timer of 249, the 50% duty cycle 'value', will be half this. 50, will only give a 20% duty cycle.
Your TRIS statements are basically 'pointless'. Because you are not specifying 'fast_io', the compiler will be automatically controlling the TRIS, so as soon as you output a byte to port B, the tris will be set to 'output'. The extra lines won't cause any problems, but aren't really doing anything...
With the code as shown, how can 'A1_pressed', _ever_ become true?. You have declared a variable, set it to false, and nowhere is it ever set true...
As such the PWM, will never turn on.

Best Wishes
timm02



Joined: 16 Jan 2008
Posts: 4
Location: Kuala Lumpur, Malaysia

View user's profile Send private message

fast_io
PostPosted: Tue Feb 05, 2008 9:29 am     Reply with quote

i do make mistake as i put 50 for pwm value, i've corrected the code by replacing it to 125 as 50% from duty cycle.

but i'm a bit confusing about fast_io. do you mean that i need not to set tris in my code?
Code:

#include <16f877a.h>
#include <stdlib.h>
#include <math.h>

#use delay (clock=20000000)
#fuses HS, NOPROTECT, NOWDT, NOLVP

#byte PORTA = 5
#byte PORTB = 6

int8 A1_pressed = TRUE;

void main()
{
 set_tris_a(0xff);
 set_tris_b(0x00);
 PORTB=0;

 output_low(PIN_B1);

 setup_ccp1(CCP_PWM);

while(TRUE)
  {

   if(A1_pressed == TRUE)
     {
       output_high(PIN_B5);                     // LED turn ON

       setup_timer_2(T2_DIV_BY_4, 249, 1);      // 5 kHz

       set_pwm1_duty(125);                      // 50% duty cycle on pin B1
         delay_ms(2000);                        // delay 2 second

     }

   else

      {
        output_low(PIN_B5);                     // LED turns OFF
        delay_ms(1500);                         // delay for 1.5 seconds
      }
  }

}
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Feb 06, 2008 2:32 am     Reply with quote

With regards to the set_tris. At the moment you do need to put this for port B because you have the line PORTB=0;

If you used the function output_b(0); instead then you do NOT need the set_tris instructions. The reason is, if you do NOT specify fast_io on your ports then when you call a CCS function to output/input to/from a port then the compiler will automatically insert set_tris instructions to set the ports acordingly. So if you had output_low(PIN_B1); the compiler will put a set_tris instruction just before this to set B1 as an output.

But if you access the ports directly then the compiler is not clever enough to work out which direction the port pin should be set to so leaves that up to you. Also, if you specify #use fast_io(B) then the compiler will NOT insert the set_tris instructions.
You would use this if you wanted to increase the speed slightly by not having the extra code before every port access, if your port directions never changed or you just needed to know exactly what was happening.

You still have not shown how the variable A1_pressed can change to be TRUE and then back to FALSE ?
Is this via an interrupt ? If so where is your interrupt handler/code.
timm02



Joined: 16 Jan 2008
Posts: 4
Location: Kuala Lumpur, Malaysia

View user's profile Send private message

PostPosted: Mon Feb 11, 2008 2:54 am     Reply with quote

I've do changes to my code, and hopefully it is right.
I've put the #use fast_io and change the variable A1_pressed to be TRUE, actually the pin A1 is on-off button.

Here is the new code:
Code:
#use fast_io(A)                           
#use fast_io(B)

int8 A1_pressed = TRUE;

void main()
{
 set_tris_A(0xFF);
 set_tris_B(0x00);
 PORTB=0;
 
 output_low(PIN_B1);                      // Set CCP1 output low

 setup_ccp1(CCP_PWM);                     // Configure CCP1 as a PWM


while(TRUE)                               
  {

   if(A1_pressed == TRUE)                 

     {
       output_high(PIN_B5);                     // LED turn ON

       setup_timer_2(T2_DIV_BY_4, 249, 1);     

       set_pwm1_duty(125);                      // 50% duty cycle on pin B1
         delay_ms(2000);                        // delay 2 second

     }

   else

      {
        output_low(PIN_B5);                     // LED turns OFF
        delay_ms(1500);                         // delay for 1.5 seconds
      }
  }

}
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