|
|
View previous topic :: View next topic |
Author |
Message |
kcj
Joined: 05 Oct 2011 Posts: 33
|
Problems with PWM using PIC18F25k22 |
Posted: Wed Feb 08, 2012 10:12 am |
|
|
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: 19518
|
|
Posted: Wed Feb 08, 2012 10:56 am |
|
|
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
|
|
|
kcj
Joined: 05 Oct 2011 Posts: 33
|
|
Posted: Wed Feb 08, 2012 5:58 pm |
|
|
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. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
kcj
Joined: 05 Oct 2011 Posts: 33
|
|
Posted: Thu Feb 09, 2012 8:19 am |
|
|
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
|
|
Posted: Thu Feb 09, 2012 10:54 am |
|
|
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
|
|
Posted: Thu Feb 09, 2012 1:21 pm |
|
|
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
|
|
Posted: Thu Feb 09, 2012 4:26 pm |
|
|
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
|
|
Posted: Thu Feb 09, 2012 4:56 pm |
|
|
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
|
|
Posted: Thu Feb 09, 2012 5:11 pm |
|
|
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
|
|
Posted: Thu Feb 09, 2012 5:34 pm |
|
|
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
|
Problem too with 18f45k22 |
Posted: Wed May 09, 2012 10:57 pm |
|
|
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
|
|
Posted: Thu May 10, 2012 1:43 pm |
|
|
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
|
Thanks but.... |
Posted: Thu May 10, 2012 7:02 pm |
|
|
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. |
|
|
|
|
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
|