View previous topic :: View next topic |
Author |
Message |
NivNavick
Joined: 01 Nov 2010 Posts: 47
|
Pic18F46K22 PWM |
Posted: Thu Jan 27, 2011 12:17 pm |
|
|
I bought Pic18F46K22 last week and tries to run a pwm on it.
My pwm software that I wrote, worked perfectly on the PIC18F4520 but after couple of days it's stopped. I run the software on the Pic18F46K22 and nothing happened.
Code: |
//Main.c File
#include <MainDefines.h>
int x=0;
/*#int_EXT
void int_isr()
{
output_d(0);
delay_ms(1000);
}*/
void main()
{
SET_TRIS_D(0x00);
SET_TRIS_B(0x3F);
SET_TRIS_C(0x00);
SET_TRIS_A(0x3f);
/*
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_2(T2_DIV_BY_16,129,1);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_4 );
//setup_timer_2(T2_DIV_BY_16,248,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
//setup_vref(FALSE);
//enable_interrupts(INT_TIMER1);
enable_interrupts(INT_EXT);
//enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
*/
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4); //prescale 1:4 overflow 52.4 ms
setup_timer_2(T2_DIV_BY_16,249,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_timer_4(T4_DIV_BY_16,129,1);
setup_comparator(NC_NC_NC_NC);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_EXT);
output_d(0);
output_c(0);
while(1)
{
output_bit(pin_c0,1);
}
}
|
Code: |
//MainDefines.h Files
#ifndef _DEVICE_18F46K22_
#define _DEVICE_18F46K22_
#ifndef _18F46K22_H
#include <18F46K22.h>
#endif
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES XINST
#use delay(clock=20000000)
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#endif
#ifndef MainDefines_H
#define MainDefines_H
//#define ir_in PIN_A5
#define us_trigger PIN_A5
#define us_right pin_A3
#define us_front PIN_C6
#define us_left PIN_C4
#define us_back PIN_A4
#define cmp PIN_C2
#include <Hardware.h>
#include <AtomicFunctions.h>
#endif
|
What's wrong with the code?
Thanks
Last edited by NivNavick on Thu Jan 27, 2011 2:47 pm; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 27, 2011 1:41 pm |
|
|
I don't know what you mean by "pwm". You have commented out the
setup_ccp1() and setup_ccp2() statements. Do you want to toggle a pin ?
Is that what you mean by "pwm" ?
Your program is too large. Remove 90% of the code in main(). It's not
needed to show the problem. If you don't need interrupts, then remove
all interrupt code. Post a small program that we can easily understand
and test. Tell us the pin that you want the pwm signal to be on.
Also tell us your CCS compiler version. |
|
![](templates/subSilver/images/spacer.gif) |
NivNavick
Joined: 01 Nov 2010 Posts: 47
|
|
Posted: Thu Jan 27, 2011 2:45 pm |
|
|
I want to toggle pins C2 and C1 (the data sheet says that they are PWM pins) but they are not working as well.
I use CCS COMPILER 4.114
I did a mistake by commented out the setups (the program that are on the PIC have those setups, still the same behavior, nothing happened and the pin give me 0). |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 27, 2011 3:26 pm |
|
|
Quote: |
#FUSES LVP
#FUSES XINST
|
These fuses are wrong. Use NOLVP and NOXINST in all your programs.
See this thread for a sample PWM program for the 18F46K22 for vs. 4.114:
http://www.ccsinfo.com/forum/viewtopic.php?t=44166&start=1
Notice how short the program is. |
|
![](templates/subSilver/images/spacer.gif) |
NivNavick
Joined: 01 Nov 2010 Posts: 47
|
|
Posted: Thu Jan 27, 2011 11:42 pm |
|
|
thank you very much!!!!!!
It should works right? ![Very Happy](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
NivNavick
Joined: 01 Nov 2010 Posts: 47
|
|
Posted: Fri Jan 28, 2011 4:57 am |
|
|
When i'm adding CCP2 (PIN_C1)
both CCPS are not working
Code: |
#include <18F45K22.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=2000000)
#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)
{
int pwm_value;
SETUP_ADC(ADC_CLOCK_INTERNAL);
SETUP_ADC_PORTS(sAN0);
setup_timer_2(T2_DIV_BY_1, 255, 1);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
while(1)
{
pwm_value = READ_ADC();
OUTPUT_D(pwm_value);
set_pwm1_duty(pwm_value);
set_pwm2_duty(pwm_value);
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19363
|
|
Posted: Fri Jan 28, 2011 10:40 am |
|
|
If nothing else, add some delay into the loop.
You can't just keep sending values to the PWM. The value update on the _next_ cycle of the PWM. Given the PWM, only updates every 256 instruction times, add at least a few hundred uSec delay to the loop somewhere. As it currently stands you are giving no time for the ADC capacitor to recharge, and outputting the value several dozen times between each possible update of the PWM.
If you want to synchronise to the PWM, then clear the timer2 interrupt flag, and wait for this to set again (just test the flag bit, no need to involve an interrupt), then read the ADC and write the new value.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
NivNavick
Joined: 01 Nov 2010 Posts: 47
|
|
Posted: Fri Jan 28, 2011 1:25 pm |
|
|
When I'm adding CCP2 setup it's cancels all the .
It should repair the CCP2 problem?
---.
Can you take a look at the fuses I posted above and please tell
me why CCP3 (PIN_B5) aren't working, (I mean that it's always sends 1(5v) and I can't reset the above pin)?
Maybe one of the fuses refers to Port B and cancel the access to
the pins?
I think the problem could #FUZES NOLVP because it is he NO LOW VOLTAGE on B5 meaning high voltage,could it be the problem with CCP3?
Thanks!!! |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 28, 2011 4:19 pm |
|
|
To make CCP2 work with vs. 4.114 with the 18F45K22 (or 18F46K22)
you need to use the substitute routine "my_setup_ccp2()" shown below.
That's because setup_ccp2() is buggy in vs. 4.114 for this series of PICs.
Code: |
#include <18F45K22.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#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;
#byte CCP2CON = 0xF66
#byte PWM2CON = 0xF65
#byte ECCP2AS = 0xF64
#byte PSTR2CON = 0xF63
void my_setup_ccp2(int32 mode)
{
output_low(PIN_C1); // This assumes "standard i/o" mode is used
CCP2CON = make8(mode, 0);
PWM2CON = 0;
ECCP2AS = make8(mode, 2);
if(make8(mode, 3) == 0x00) // If no steering pin was specified, use P1A
PSTR2CON = 1;
}
//======================================
void main(void)
{
setup_timer_2(T2_DIV_BY_1, 255, 1);
setup_ccp1(CCP_PWM);
my_setup_ccp2(CCP_PWM);
set_pwm1_duty(64);
set_pwm2_duty(128);
while(1);
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
NivNavick
Joined: 01 Nov 2010 Posts: 47
|
|
Posted: Fri Jan 28, 2011 4:43 pm |
|
|
NivNavick wrote: | When I'm adding CCP2 setup it's cancels all the .
It should repair the CCP2 problem?
---.
Can you take a look at the fuses I posted above and please tell
me why CCP3 (PIN_B5) aren't working, (I mean that it's always sends 1(5v) and I can't reset the above pin)?
Maybe one of the fuses refers to Port B and cancel the access to
the pins?
I think the problem could #FUZES NOLVP because it is he NO LOW VOLTAGE on B5 meaning high voltage,could it be the problem with CCP3?
Thanks!!! |
thank you very much!!!!!!!!!!!!
Do you know how to fix CCP3 ? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 28, 2011 4:56 pm |
|
|
Well, probably. But why do I have to do all the work ? Why don't you try. |
|
![](templates/subSilver/images/spacer.gif) |
NivNavick
Joined: 01 Nov 2010 Posts: 47
|
|
Posted: Sat Jan 29, 2011 1:39 am |
|
|
PCM programmer wrote: | Well, probably. But why do I have to do all the work ? Why don't you try. |
I tried and my thought are that the NOLVP is the problem, but I'm not sure,
do you think it's the problem too? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19363
|
|
Posted: Sat Jan 29, 2011 5:01 am |
|
|
No.
NOLVP, is _required_, if you are going to use the LVP programming pins for anything _but_ programming. If LVP is enabled, these pins become 'unusable', which matches what you are seeing. LVP, should _only_ be enabled if you are using a low voltage programmer that uses these pins (99.9% of programmers don't). One (faint) possibility would be, that you _are_ using such a programmer, and it's software automatically turns off the NOLVP setting, making the pins unusable.....
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
NivNavick
Joined: 01 Nov 2010 Posts: 47
|
|
Posted: Sun Jan 30, 2011 1:11 am |
|
|
Code: | #fuses INTRC_IO//,NOLVP |
when the above fuse is in my program the clock are messed up
and if I delete the fuse the clock value which was 20MH is fine
I mean with delay_ms(1); it's look like 1 sec
what is the problem? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19363
|
|
Posted: Sun Jan 30, 2011 3:26 am |
|
|
Your timings are not going to work, because you are using an impossible combination. The internal RC oscillator, _does not offer 20MHz as an available speed_.
You _must_ start by reading the data sheet, and only using options supported by the chip you are using.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
|