|
|
View previous topic :: View next topic |
Author |
Message |
pisti66
Joined: 03 Jun 2011 Posts: 7
|
PWM doesn't works on pic18f1330 |
Posted: Fri Jun 03, 2011 4:37 am |
|
|
Hi There,
I want to use the PWM outputs of the pic18f1330 to drive a RGB lighting.
I think the electrical switching is OK, because I can turn on/off the leds, when the output pins are configured for output pins. There is an 47k pullup resistor on MCLR pin. The colours will be adjusted by potentiometers. The problem is that PWM doesn't works.
Please help me. Where is the stupid bug?
Here is the source:
Code: | #include <18F1330.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOPWMPIN //PWM outputs disabled upon Reset
#FUSES NOMCLR
#FUSES XINST
#FUSES FLTAA5
#use delay(int=8000000)
#ZERO_RAM
#use fast_io(A)
#define heartbeat PIN_A7
#define RIN PIN_A0
#define GIN PIN_A1
#define BIN PIN_A4
#define ROUT PIN_B0
#define GOUT PIN_B4
#define BOUT PIN_B6
#define POWER_PWM_PERIOD 1999 // 1 KHz pwm freq with 8 MHz osc.
int32 ncount;
void main()
{
int i;
set_tris_a(0b00110011);
output_low(ROUT);
output_low(GOUT);
output_low(BOUT);
for(i=0;i<6;i++){
output_toggle(ROUT);
output_toggle(GOUT);
output_toggle(BOUT);
delay_ms(300);
}
setup_adc_ports(AN0_AN1_AN2,VSS_VDD);
setup_comparator(NC_NC_NC);// This device COMP currently not supported by the PICWizard
setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_OFF);
// Setup the 4 Power PWM channels as ordinary pwm channels.
setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);
// Mode = Free Run
// Postscale = 1 (1-16) Timebase output postscaler
// TimeBase = 0 (0-65355) Initial value of PWM Timebase
// Period = 2000 (0-4095) Max value of PWM TimeBase
// Compare = 0 (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time
setup_power_pwm(PWM_FREE_RUN | PWM_CLOCK_DIV_4, 1, 0, POWER_PWM_PERIOD, 0, 1,0);
set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .1)); // 10%
set_power_pwm2_duty((int16)((POWER_PWM_PERIOD *4) * .4)); // 40%
set_power_pwm4_duty((int16)((POWER_PWM_PERIOD *4) * .6)); // 60%
ncount=0;
output_low(heartbeat);
while(true){
ncount++;
if(ncount>=50000){
output_toggle(heartbeat);
ncount=0;
}
}
}
|
Regards, |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Fri Jun 03, 2011 5:27 am |
|
|
I don't have that PIC but
some observations..
47K pullup not required as you've set NOMCLR in the fuses..
get rid of the use_fast_io()...
get rid of the set_tris_a()....
these should only be used by seasoned, experienced programmers to save you a LOT of grief as to why 'something' isn't working 'right'.
((int16)((POWER_PWM_PERIOD *4) * .1)); // 10%
try doing the 'math' and print it out to see if the numbers are correct
simple test..insert 3 different 'hard' numbers and see how the LEDs perform.. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 03, 2011 12:31 pm |
|
|
Quote: | #include <18F1330.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOPWMPIN //PWM outputs disabled upon Reset
#FUSES NOMCLR
#FUSES XINST
#FUSES FLTAA5 |
Enabling XINST will definitely make your program go crazy. The extended
instruction set is not supported by CCS. Remove that line, change it to
NOXINST. |
|
|
pisti66
Joined: 03 Jun 2011 Posts: 7
|
|
Posted: Fri Jun 03, 2011 12:33 pm |
|
|
Hi,
I tried with fixed numbers, but it doesn't worked.
I need a working example on this pic.
Regards. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
pisti66
Joined: 03 Jun 2011 Posts: 7
|
|
Posted: Fri Jun 03, 2011 1:51 pm |
|
|
Hi,
I use the version 4.120.
I changed the fuse to NOXINST, but there is no improvement.
Regards |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri Jun 03, 2011 3:24 pm |
|
|
Are you testing on an actual chip, or with a simulator?.
Found MPLAB did not simulate this part properly....
I'd set the PWMPIN fuse (ensures that the port is setup for PWM on boot), but have used the power PWM OK on recent compilers (just did a project with 4.118, and it ran fine). There were configuration problems with some compilers in the past.
Just tried with fractionally modified code:
Code: |
#device adc=8
#FUSES NOWDT, WDT128, INTRC_IO, NOFCMEN, NOIESO, BROWNOUT_NOSL, BORV27, PWMPIN, NOMCLR, NOXINST
#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_A3,rcv=PIN_A2,bits=8,stream=PORT1)
#define POWER_PWM_PERIOD 2000 // 1 KHz pwm freq with 8 MHz osc.
void main()
{
setup_adc_ports(AN0_AN1_AN2,VSS_VDD);
setup_comparator(NC_NC_NC);
setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON,PWM_ODD_ON);
setup_power_pwm(PWM_FREE_RUN | PWM_CLOCK_DIV_4, 1, 1, POWER_PWM_PERIOD-1, 0, 1, 0);
set_power_pwm0_duty((int16)((POWER_PWM_PERIOD*4) * .1)); // 10%
set_power_pwm2_duty((int16)((POWER_PWM_PERIOD*4) * .4)); // 40%
set_power_pwm4_duty((int16)((POWER_PWM_PERIOD*4) * .6)); // 60%
do {
} while(TRUE);
}
|
and it happily generates three pulses on the pins correctly.
Remember for your period calculations, that 100%, comes at the timer period+1.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 03, 2011 3:33 pm |
|
|
This program will give PWM output on pins B1, B5 and B7 (PWM1, PWM3,
and PWM5). This was tested in hardware with vs. 4.120.
Edit: I just noticed Ttelmah was posting his reply while I was composing
mine. I'll leave mine up anyway.
Code: |
#include <18F1330.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT
#use delay(clock=8M)
#define POWER_PWM_PERIOD 1999 // 1 KHz pwm freq with 8 MHz osc.
//=======================================
void main()
{
// Setup the 4 Power PWM channels as ordinary pwm channels.
setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);
// Mode = Free Run
// Postscale = 1 (1-16) Timebase output postscaler
// TimeBase = 0 (0-65355) Initial value of PWM Timebase
// Period = 2000 (0-4095) Max value of PWM TimeBase
// Compare = 0 (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time
setup_power_pwm(PWM_FREE_RUN, 1, 0, POWER_PWM_PERIOD, 0, 1,0);
set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .1)); // 10%
set_power_pwm2_duty((int16)((POWER_PWM_PERIOD *4) * .4)); // 40%
set_power_pwm4_duty((int16)((POWER_PWM_PERIOD *4) * .6)); // 60%
while(1);
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sat Jun 04, 2011 2:25 am |
|
|
Two minds with the same thought!....
Best Wishes |
|
|
pisti66
Joined: 03 Jun 2011 Posts: 7
|
|
Posted: Sat Jun 04, 2011 2:25 am |
|
|
Hi,
Many thanks boys. It works with minor changes.
I changed the "PWM_ODD_ON" to "PWM_BOTH_ON", and it works.
The problem was the terminology.
The PWM0 is odd for me, because it is the first in the list.
Regards. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sat Jun 04, 2011 4:05 am |
|
|
Something wrong elsewhere.
Both PCM Programmers test, and mine, used the 'ODD_ON' setting, which does what it says (enables only the odd outputs, and not the complementary outputs), and works.
Are you sure you were looking on the right pins?. Remember with 'both on', you have six output pins generating signals. With 'odd on', only three have signals on three of the pins.
Best Wishes |
|
|
|
|
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
|