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 support@ccsinfo.com

Problems with PWM using PIC18F25k22
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kcj



Joined: 05 Oct 2011
Posts: 33

View user's profile Send private message

Problems with PWM using PIC18F25k22
PostPosted: Wed Feb 08, 2012 10:12 am     Reply with quote

Hi All,

Pic18F25k22 has 5 CCP available. After reading the datasheet and lots of posts on this website, i used the following code to set up CCP1 and CCP2.
Code:

#include <18f25k22.h>
#fuses HS,NOBROWNOUT,NOWDT,PUT,STVREN,NOFCMEN,NOMCLR,NOXINST,NOPLLEN,CCP2C1           
#use delay(clock=20M)
//CCP2C1   CCP2 input/output multiplexed with RC1

 void main()
{

set_tris_c(0x00);

setup_timer_2(T2_DIV_BY_16,250,1);   //1.2kHz

setup_ccp1(CCP_PWM);   
setup_ccp2(CCP_PWM);

set_pwm1_duty(512);                  //50% Duty
set_pwm2_duty(512);                  //50% Duty

}


PINS RC1 (CCP1) and RC2 (CCP2) were tested by turning an LED on and off for 1 second. So they are not the problem.

when i use this code there is no change on the pins, both pins are 0v.

Any suggestions how to fix the problem.
Compiler Version 4.114
thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Wed Feb 08, 2012 10:56 am     Reply with quote

Two things. First 512, _will not_ give 50% duty cycle. It'll only give 50% if the PR2 value for timer2, is 256. Since you have this set to 250, you need 500 for 50% duty cycle.
Second, if having problems with pins not working, always look at 'what else' is potentially on the pin(s). Secondary oscillator, overrides C1, whatever TRIS is set to. This needs to be disabled. Similarly the CTMU unit needs to be explicitly disabled on C2.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 08, 2012 3:41 pm     Reply with quote

Read this thread about 10-bit PWM mode, and how to fix your program:
http://www.ccsinfo.com/forum/viewtopic.php?t=45495

Read this thread about what happens if you let your program run off the
end of main(), and how to fix it:
http://www.ccsinfo.com/forum/viewtopic.php?t=34429
kcj



Joined: 05 Oct 2011
Posts: 33

View user's profile Send private message

PostPosted: Wed Feb 08, 2012 5:58 pm     Reply with quote

Hi TteImah,

i could not find a built in function to disable the secondary oscillator but i have being learning to use the datasheet a bit more and it says to use the TXCON register setting bit TXSOSCEN to 0 to disable the secondary oscillator circuit. pge 172.

I have never done this before so i was thinking of using code

Code:

#byte TXCON = unsure where to get address of register;
#bit TXCONBIT3=TXCON 0.3;

TXCONBIT3=0; //used in code to disable secondary oscillator

I am unsure where to find registry addresses for PICS

Hi PCM, i read the post and changed the duty value to 10Bit by adding an L and put the code inside a while loop.
Code:

#include <18f25k22.h>
#fuses HS,NOBROWNOUT,NOWDT,PUT,STVREN,NOFCMEN,NOMCLR,NOXINST,NOPLLEN,CCP2C1           
#use delay(clock=20M)
//CCP2C1   CCP2 input/output multiplexed with RC1

//#byte TXCON = unsure where to get address of register;
//#bit TXCONBIT3=TXCON 0.3;

 void main()
{
{
set_tris_c(0x00);

setup_timer_2(T2_DIV_BY_16,250,1);   //1.2kHz

setup_ccp1(CCP_PWM);   
setup_ccp2(CCP_PWM);

set_pwm1_duty(500L);                  //50% Duty
set_pwm2_duty(500L);                  //50% Duty

while(1);
}
}

But it made no difference. Question
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 08, 2012 7:31 pm     Reply with quote

This question is answered in the forum archives:
http://www.ccsinfo.com/forum/viewtopic.php?t=44166
kcj



Joined: 05 Oct 2011
Posts: 33

View user's profile Send private message

PostPosted: Thu Feb 09, 2012 8:19 am     Reply with quote

Hi PCM,

yes that did solve the problem and CCP1 works fine but when i add CCP2, both CCP1 and CCP2 stop and have 0v at the pins
Code:


#include <18F25k22.h>
#fuses HS,NOBROWNOUT,NOWDT,PUT,STVREN,NOFCMEN,NOMCLR,NOXINST,NOPLLEN,CCP2C1 
#use delay(clock=20M)

#byte T2CON = 0xFBA
#byte PR2 = 0xFBB

#define setup_timer_2(prescaler, PR2val, postscaler) \
if(prescaler)   \
  {             \
   PR2 = PR2val;  \
   T2CON =  prescaler | ((postscaler -1) << 3);  \
  }             \
else            \
  T2CON = 0;

//======================================
void main(void)
{
setup_timer_2(T2_DIV_BY_1, 255, 1);
setup_ccp1(CCP_PWM); 
set_pwm1_duty(120);

setup_ccp2(CCP_PWM);
set_pwm2_duty(150);

while(1);
}


Any suggestions?

I want to use all five CCP, is there an alternative 28pin PIC18 that you know that works well and doesnt have any bugs with CCP. i would consider changing.

Thanks
kcj



Joined: 05 Oct 2011
Posts: 33

View user's profile Send private message

PostPosted: Thu Feb 09, 2012 10:54 am     Reply with quote

Hi,

I have being testing the other PWM, all work fine using the following code but if i set up CCP2 then all of the CCP stop working and pins are 0v.
Code:

#include <18F25k22.h>
#fuses HS,NOBROWNOUT,NOWDT,PUT,STVREN,NOFCMEN,NOMCLR,NOXINST,NOPLLEN
#use delay(clock=20M)
#fuses CCP2C1   //CCP2 input/output multiplexed with RC1

#byte T2CON = 0xFBA
#byte PR2 = 0xFBB
#byte OSCCON2 = 0xFD2

#define setup_timer_2(prescaler, PR2val, postscaler) \
if(prescaler)   \
  {             \
   PR2 = PR2val;  \
   T2CON =  prescaler | ((postscaler -1) << 3);  \
  }             \
else            \
  T2CON = 0;

//======================================
void main(void)
{
//bit_clear(OSCCON2.3);
setup_timer_2(T2_DIV_BY_1, 255, 1);

setup_ccp1(CCP_PWM); 
set_pwm1_duty(120);
//setup_ccp2(CCP_PWM);
//set_pwm2_duty(150);
setup_ccp3(CCP_PWM);
set_pwm3_duty(150);
setup_ccp4(CCP_PWM);
set_pwm4_duty(150);
setup_ccp5(CCP_PWM);
set_pwm5_duty(150);

while(1);
}


I seems very strange, PIN CCP2 does have the secondary oscillator. From the datasheet. Bit 3 in OSSCON2 disables it. I tried bit_clear(OSCCON2.3); in the code but it did not work. From the datasheet it has a NOTE beside it, that says
Note 1: The SOSCGO bit is only reset on a POR Reset.

I am not sure what that means. Also i thought by using #fuses CCP2C1 would enable CCP2. on pin C1.

Any suggestions welcome.
Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 09, 2012 1:21 pm     Reply with quote

You can see the problem by looking at the .LST file (in Symbolic mode).
It's clearing the T2CON register. One work-around solution is to move
the line for setup_timer_2() so it's after the setup lines for CCP2.
kcj



Joined: 05 Oct 2011
Posts: 33

View user's profile Send private message

PostPosted: Thu Feb 09, 2012 4:26 pm     Reply with quote

Yes, that did work, Thanks for your help. I had a look at the .lst file. My first time looking at one. From what i have read, the .lst file is the assembly code the compiler uses to execute the program. i extracted this section
Code:

.................... setup_timer_2(T2_DIV_BY_1, 255, 1); 
0024:  MOVLW  FF
0026:  MOVWF  FBB
0028:  MOVLW  04
002A:  MOVWF  FBA
.................... 
.................... 
.................... setup_ccp1(CCP_PWM);   
002C:  BCF    F94.2
002E:  BCF    F8B.2
0030:  MOVLW  0C
0032:  MOVWF  FBD
0034:  CLRF   FBE
0036:  CLRF   FBF
0038:  MOVLW  01
003A:  MOVWF  FB9
.................... set_pwm1_duty(120); 
003C:  MOVLW  78
003E:  MOVWF  FBE
.................... 
.................... setup_ccp2(CCP_PWM);
0040:  BCF    F94.1
0042:  BCF    F8B.1
0044:  MOVLW  0C
0046:  MOVWF  F66
0048:  CLRF   FB9
004A:  CLRF   FBA
004C:  MOVLW  01
004E:  MOVWF  FB9
.................... set_pwm2_duty(150);
0050:  MOVLW  96
0052:  MOVWF  F67

When CCP2 is executed after setup timer, then i did the same when executed before
Code:

.................... setup_ccp2(CCP_PWM);
0024:  BCF    F94.1
0026:  BCF    F8B.1
0028:  MOVLW  0C
002A:  MOVWF  F66
002C:  CLRF   FB9
002E:  CLRF   FBA
0030:  MOVLW  01
0032:  MOVWF  FB9
.................... set_pwm2_duty(150);
0034:  MOVLW  96
0036:  MOVWF  F67
.................... setup_timer_2(T2_DIV_BY_1, 255, 1); 
0038:  MOVLW  FF
003A:  MOVWF  FBB
003C:  MOVLW  04
003E:  MOVWF  FBA
.................... 
.................... 
.................... setup_ccp1(CCP_PWM);   
0040:  BCF    F94.2
0042:  BCF    F8B.2
0044:  MOVLW  0C
0046:  MOVWF  FBD
0048:  CLRF   FBE
004A:  CLRF   FBF
004C:  MOVLW  01
004E:  MOVWF  FB9
.................... set_pwm1_duty(120); 
0050:  MOVLW  78
0052:  MOVWF  FBE


I am quite curious now and was interested to know how the compiler cleared T2CON before the setup CCP2 line was executes from the code in lst file in the first compile.
Comparing the above i cannot see the difference or am i completely wrong. lol

Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 09, 2012 4:56 pm     Reply with quote

In MPLAB, go to the Project menu, then Build Options, and then set it for
Symbolic Format in the List file section. Then re-compile and look at the
.LST file again. Then you'll see it.
kcj



Joined: 05 Oct 2011
Posts: 33

View user's profile Send private message

PostPosted: Thu Feb 09, 2012 5:11 pm     Reply with quote

Ah thats a shame, i use CCS PIC C compiler. I have not got MPLAB setup, but maybe i should as it is very interesting to know how to solve future problems.
Thanks for the help.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 09, 2012 5:34 pm     Reply with quote

I don't have the CCS IDE, but almost certainly "Symbolic Format" is an
option for the .LST file. Just look around the menus in the IDE until you
find it.
mcr1981



Joined: 27 Oct 2010
Posts: 28

View user's profile Send private message

Problem too with 18f45k22
PostPosted: Wed May 09, 2012 10:57 pm     Reply with quote

Hello.


Been reading this post and still can't figure it out.

I want to generate two 1KHz with 10% and 50% duty waves from the CCP1 and CCP2 modules. I was using version 4.114 and now i use 4.130 (they added the options to write to the CCPTMRSx registers for the PWM Timers).

I'm sure that this has a very simple solution, but after 3 hours looking for it (google + RTFDS) I'm going to resort to the forum.

I just can't generate a wave with CCP2, not even in simulation (MPLAB 8.84). There's seems to be no output at RC1.


Here's my code:

Code:

#include "18F45k22.h"
#include "PIC18F45k22.h"

#fuses   NOPLLEN, NOMCLR, INTRC_IO
#fuses   CCP2C1

#use delay (clock=4M)



int16 ciclo1=100,ciclo2=500;

   void PWM1()
   {
   setup_ccp1(CCP_PWM|CCP_USE_TIMER1_AND_TIMER2);
   setup_timer_2(T2_DIV_BY_4,249,1);
   set_pwm1_duty(ciclo1);
   }
   
   void PWM2()
   {
   setup_ccp2(CCP_PWM|CCP_USE_TIMER3_AND_TIMER4);
   setup_timer_4(T4_DIV_BY_4,249,1);
   set_pwm2_duty(ciclo2);
   }



void main()
{
   SETUP_OSCILLATOR(OSC_INTRC|OSC_PLL_OFF|OSC_4MHZ);

   PWM1();
   PWM2();
   
      while(1)
      {
      }
}


Thanks in advance.
kcj



Joined: 05 Oct 2011
Posts: 33

View user's profile Send private message

PostPosted: Thu May 10, 2012 1:43 pm     Reply with quote

HI MCR 1981,

I am no coding expert but i did pick up a few tips doing my project, i think to set up a PWM, you need to set up timer 2, it determines the PWM frequency,

using the formula
Period = ( Tosc *4) *( TMR2 Prescaler value)*(PR2+1)

code: setup_timer_2(T2_DIV_BY_2,249,1); //1000Hz

Then set up each CCP using the PWM using the commands in the device header file
Code : setup_CCP1 (PWM)

Then set up the duty cycle with

Code: set_pwm1_duty(125); //50% duty cycle

calculated by 50% of 249 setup in timer2 = 125

I think this is correct to the best of my knowledge. So for your program it would be
Code:

#include <18F45k22.h>
#fuses   NOPLLEN, NOMCLR, INTRC_IO
#fuses   CCP2C1
#use delay (clock=4M)
 
int ciclo1=25;
int ciclo2=126;

   void PWM1()
   {
   setup_ccp1(CCP_PWM);     // Configure CCP1 as a PWM
   set_pwm1_duty(ciclo1);   // sets up duty cycle pwm1
   }
   
   void PWM2()
   {
   setup_ccp2(CCP_PWM);     // Configure CCP2 as a PWM
   set_pwm2_duty(ciclo2);   // sets up duty cycle pwm2
   }

void main()
{
    setup_timer_2(T2_DIV_BY_2,249,1);  //1000Hz
    PWM1();
    PWM2();

    while(1);     
}


Good luck
mcr1981



Joined: 27 Oct 2010
Posts: 28

View user's profile Send private message

Thanks but....
PostPosted: Thu May 10, 2012 7:02 pm     Reply with quote

Thanks for your info.

You're right, if you want just one frequency then Timer2 will suffice, but my intention is to have different frequencies (that's why I use T2 and T4).

My problem is that i can't seem to get an output in CCP2, not in simulation or in practice.


By the way, you're right with the 125 on %duty, but you would only use an 8 bit resolution PWM.

I'll keep trying.
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  Next
Page 1 of 2

 
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