View previous topic :: View next topic |
Author |
Message |
koenbielen
Joined: 23 Apr 2009 Posts: 42
|
SOLVED pwm problem pic18f27k40 |
Posted: Wed Jul 11, 2018 2:59 am |
|
|
Hi
My PWM output does not seem to work.
I checked with an oscilloscope.
COMPILER : 5.078
PIC : 18F27K40
If someone knows what I'm doing wrong... well help is appreciated.
Code: |
#include <18F27K40.h>
#device adc=10
#DEVICE HIGH_INTS=TRUE
#use delay(int=64000000)
#FUSES NOWDT
#FUSES WDT32768
#FUSES NOEXTOSC
#FUSES RSTOSC_HFINTRC_64MHZ
#FUSES NOPROTECT
#FUSES NOBROWNOUT
#FUSES NODEBUG
#FUSES NOPUT
#FUSES NOCPD
#FUSES STVREN
#FUSES NOWRTD
#FUSES NOEBTR
#FUSES NOEBTRB
#FUSES NOWRTC
#FUSES NOWRTB
#FUSES FCMEN
#FUSES NOXINST
#FUSES NOMCLR
#PIN_SELECT CCP1OUT=PIN_C2
#include <string.h>
#include <STDLIB.h>
#INCLUDE <math.h>
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
//------------------------------------------------------------------------------
void main (void)
{
setup_oscillator (OSC_HFINTRC_64MHZ);
//-----------------------------------------------------------------------------------------------------------------------------------------------------
set_tris_a (0x07);//0000 0111
set_tris_c (0x81);//
set_tris_e(0xFF);//
port_b_pullups(0b00000000);
set_tris_b (0b10111101);//
//-----------------------------------------------------------------------------------------------------------------------------------------------------
setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1);
setup_timer_2(T2_CLK_INTERNAL | T2_DIV_BY_1,240,16); //
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_OFF);
setup_adc_ports(NO_ANALOGS);
set_pwm1_duty(70);
while(1)
{
}
}
//------------------------------------------------------------------------------
|
the code above works now
probably hardware issue. used different pcb and it works
Last edited by koenbielen on Thu Jul 12, 2018 9:02 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Jul 11, 2018 5:41 am |
|
|
While I don't use that PIC, some 'general' comments.
Have you got the simple '1Hz LED' program to run, at the correct speed ? This should be your first program so as to confirm the hardware is good and that the compiler codes OK, programmer downloads properly. If you can use C2, then you KNOW it's not grounded as the LED flashes..
I would delete the #includes for the 3 'math's. You're NOT using them and while nothing will be coded in, visually it cleans up the code.
Also I would not be using fast_io() now. wait until you've test the program and decide IF you REALLY need the small speed improvement fast_io() offers. When you use fast_io you MUST be 100% correct about pin directions. It's easy to change the use of a pin and forget to change the tris() part.
Often there are lots of internal peripherals that can be attached to a pin, be sure to disable those you don't need.
There's a sticky at the top of the board about pin_select, be sure to read it.
Is C2 a valid pin for PWM output ? An errata in the compiler may allow it to compile without error but physically the PIC won't be connected.
Again, I don't use that PIC, haven't read the 600+ pages of the datasheet, just offering 'things to try'.
hmm..pin isn't grounded by any chance ??
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 11, 2018 3:23 pm |
|
|
The following program works. It was compiled with CCS vs. 5.078, using
MPLAB v8.92 as the IDE, and programmed with MPLAB IPE v4.15.
It was tested on an 18F47K40 (same family as your PIC) on a older
PicDem2-plus board. The PIC is running at 5v. I tested both duty cycles
shown in the program below, and verified the pulse duration with a scope.
Code: |
#include <18F47K40.h>
#fuses NOEXTOSC, NOWDT, BROWNOUT, PUT
#use delay(internal=64M)
#PIN_SELECT CCP1OUT=PIN_C2
//------------------------------------------------------------------------------
void main (void)
{
setup_timer_2(T2_CLK_INTERNAL | T2_DIV_BY_1, 240, 16);
setup_ccp1(CCP_PWM);
//set_pwm1_duty(90); // Approximately 9.5% duty cycle
set_pwm1_duty(480); // 50% duty cycle
while(TRUE);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Thu Jul 12, 2018 2:18 am |
|
|
Slightly surprised?....
I'd have expected the following:
Code: |
void main (void)
{
setup_timer_2(T2_CLK_INTERNAL | T2_DIV_BY_1, 240, 16);
setup_ccp1(CCP_PWM);
//set_pwm1_duty(90); // Approximately 9.5% duty cycle
//Surely this would give about 38% duty cycle....
//Because you have not used 'L' to say the value being
//passed is a 'long', the system should treat this as the upper
//8bits of a 10bit value, so give an effective period of 360???.
set_pwm1_duty(480); // 50% duty cycle
//This should work, since it is over 255. :)
while(TRUE);
}
|
Unless CCS has changed something in the compiler version you are running, I'd have expected the smaller duty to not behave as you report.
Perhaps you just saw it was a shorter pulse, and didn't actually check the pulse width?.
If it does give the pulse reported,, it says something slightly 'odd' is going on. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 12, 2018 2:47 am |
|
|
CCS always treats it as if it's got an 'L' for this PIC.
It loads the high and low registers the same way, L or no L:
Code: | .................... set_pwm1_duty(90); // Approximately 9.5% duty cycle
00072: CLRF CCPR1H
00074: MOVLW 5A
00076: MOVWF CCPR1L
.................... set_pwm1_duty(90L); // Approximately 9.5% duty cycle
00078: CLRF CCPR1H
0007A: MOVWF CCPR1L
. |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Thu Jul 12, 2018 3:10 am |
|
|
Interesting. I presume it is the chips that don't have the two separate bits in another register for the low duty cycle. A 'caveat' for everyone switching from an older PIC.... |
|
|
|