|
|
View previous topic :: View next topic |
Author |
Message |
Joan
Joined: 29 May 2004 Posts: 41 Location: Barcelona, Spain
|
12F683 with #INT_RA (PWM not working ) |
Posted: Fri Jan 30, 2009 12:40 pm |
|
|
Hi all,
I've writed this code and the problem is that PWM is disabled when executing first time #INT_RA. I've done a lot of test but without luck. Any idea ?
Code: |
/////////////////////////////////////////////////////////////////////////
///
/// Fuses: MCLR,PUT,NOPUT,RC,EC,RC_IO,INTRC_IO,BROWNOUT,NOBROWNOUT
///
/////////////////////////////////////////////////////////////////////////
/************************************************************/
/* P R E P R O C E S S O R */
/************************************************************/
#include <12F683.h>
/************************************************************/
/* A D C */
/************************************************************/
#device ADC=10
/************************************************************/
/* F U S E S */
/************************************************************/
#fuses INTRC_IO, NOWDT, NOMCLR, NOPUT, BROWNOUT
/************************************************************/
/* O S C I L A T O R & D E L A Y */
/************************************************************/
#use delay(clock=1000000)
/************************************************************/
/* S E T U P R S - 2 3 2 */
/************************************************************/
// NONE
/************************************************************/
/* S E T U P I 2 C */
/************************************************************/
#use i2c(master, SDA=PIN_A0, SCL=PIN_A1, SLOW)
/************************************************************/
/* I N C L U D E S */
/************************************************************/
//
/************************************************************/
/* D E F I N I T I O N S */
/************************************************************/
#ROM 0x7FF = {0x3400}
#byte CCPR1L = 0x13
#byte CCP1CON = 0x15
#define GP0 PIN_A0
#define GP1 PIN_A1
#define GP2 PIN_A2
#define GP3 PIN_A3
#define GP4 PIN_A4
#define GP5 PIN_A5
#define VALUE 95
/************************************************************/
/* G L O B A L V A R I A B L E S */
/************************************************************/
long PWM;
/************************************************************/
/* F U N C T I O N S */
/************************************************************/
void setup()
{
setup_oscillator(OSC_1MHZ);
setup_adc_ports( NO_ANALOGS ); // Disable analog inputs
setup_adc( ADC_OFF ); // Disable A2D
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,255,16); // 60Hz PWM frequency
setup_ccp1(CCP_PWM);
setup_comparator(NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RA3);
enable_interrupts(GLOBAL);
}
/******************************************************************/
/* I N T E R R U P T V E C T O R S */
/******************************************************************/
#INT_RA
void int_ra_isr(void)
{
char A;
disable_interrupts(GLOBAL);
A = input_a(); // Clear mismatch condition
clear_interrupt(INT_RA3);
enable_interrupts(GLOBAL);
}
/******************************************************************/
/* M A I N P R O G R A M */
/******************************************************************/
void main(void)
{
delay_ms (1000);
setup ();
while(TRUE)
{
set_pwm1_duty(VALUE);
}
} |
_________________ I Came. I Saw. I Won. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 30, 2009 12:51 pm |
|
|
Quote: | #INT_RA
void int_ra_isr(void)
{
char A;
disable_interrupts(GLOBAL);
A = input_a(); // Clear mismatch condition
clear_interrupt(INT_RA3);
enable_interrupts(GLOBAL);
} |
Delete the lines shown in bold. The PIC and the compiler handle doing
this. You should not do it. Especially, don't enable global interrupts
inside an isr. There is other code (unseen in the source program) that
is executed to get in and out of the isr. If you enable global interrupts
inside the isr, you risk getting an interrupt in the middle of the code that
handles restoring the machine state back to the foreground code.
Since nested interrupts are not supported, this will cause the program
to crash. Never use the lines shown in bold.
Also, the compiler handles clearing the interrupt, as well. Delete that
line too. |
|
|
Joan
Joined: 29 May 2004 Posts: 41 Location: Barcelona, Spain
|
|
Posted: Fri Jan 30, 2009 3:18 pm |
|
|
Hi PCM Programmer,
I deleted listed lines like below:
Code: | #INT_RA
void int_ra_isr(void)
{
char A;
A = input_a(); // Clear mismatch condition
clear_interrupt(INT_RA3);
} |
But still doesn't works. It is like any interrupt was disabled.
Compiler version is 4.078
Thanks. _________________ I Came. I Saw. I Won. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 30, 2009 4:02 pm |
|
|
The problem is that you're reading the whole of Port A. In standard i/o
mode, the compiler inserts code to set Port A to be all inputs when it
executes the input_a() function. This prevents the use of the CCP1 pin
for PWM output (Pin A2). One solution is to only read pin A3 (not the
entire port) to clear the mismatch condition. Do this with input(PIN_A3)
instead of using input_a().
Try this code for the isr:
Code: | #INT_RA
void int_ra_isr(void)
{
char A;
A = input(PIN_A3); // Clear mismatch condition
} |
Quote: | #INT_RA
void int_ra_isr(void)
{
char A;
A = input(PIN_A3); // Clear mismatch condition
clear_interrupt(INT_RA3);
} |
Also, you don't need to put in the line of code to clear the interrupt.
The compiler does it for you. Delete the line shown in bold.
Quote: | #ROM 0x7FF = {0x3400} |
This line is not needed for the 12F683. Delete it. |
|
|
Ttelmah Guest
|
|
Posted: Fri Jan 30, 2009 4:05 pm |
|
|
Whoa a second.
At the start you are saying that the PWM gets disabled when a serial character is received, while now you are saying that "It is like any interrupt was disabled". The code now does nothing when the character is received. You read it, but don't change anything in the operation of the program, so there would be no reaction at all "like any interrupt was disabled".
Now some further comments on your code. You don't need:
clear_interrupt(INT_RA3);
The compiler does this automatically, unless you use the 'noclear' syntax, when declaring the interrupt.
PCM, is slightly 'mis-stating' things when he talks about the compiler automatically disabling interrupts, and re-enabling them, it is the PIC _hardware_ that does this. The hardware disables the global interrupt, when the interrupt handler is called, and then re-enables it _after the return from interrupt is executed_. This ensures that interrupts can't occur inside one another. The only compiler action, is to use a special 'return from interrupts' instruction, at the end of the handler.
As written, your code sits doing nothing, except re-loading the pwm duty cycle, which is 'pointless' the cycle stays set, until it is changed...
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 30, 2009 4:07 pm |
|
|
No, I said the PIC (i.e., the hardware) and the compiler (software) do it:
Quote: | The PIC and the compiler handle doing this. |
|
|
|
Joan
Joined: 29 May 2004 Posts: 41 Location: Barcelona, Spain
|
|
Posted: Fri Jan 30, 2009 5:53 pm |
|
|
Hi PCM Programmer and Ttelmah,
with your help, the code work fine. Thanks you very much for your help, I really appreciate it !
I post the whole code if anyone wants to check for some app.
Thanks again for your help.
Joan
Code: | /////////////////////////////////////////////////////////////////////////
///
/// Fuses: MCLR,PUT,NOPUT,RC,EC,RC_IO,INTRC_IO,BROWNOUT,NOBROWNOUT
///
/////////////////////////////////////////////////////////////////////////
/************************************************************/
/* P R E P R O C E S S O R */
/************************************************************/
#include <12F683.h>
/************************************************************/
/* A D C */
/************************************************************/
#device ADC=10
/************************************************************/
/* F U S E S */
/************************************************************/
#fuses INTRC_IO, NOWDT, NOMCLR, NOPUT, BROWNOUT
/************************************************************/
/* O S C I L A T O R & D E L A Y */
/************************************************************/
#use delay(clock=1000000)
/************************************************************/
/* S E T U P R S - 2 3 2 */
/************************************************************/
// NONE
/************************************************************/
/* S E T U P I 2 C */
/************************************************************/
#use i2c(master, SDA=PIN_A0, SCL=PIN_A1, SLOW)
/************************************************************/
/* I N C L U D E S */
/************************************************************/
//
/************************************************************/
/* D E F I N I T I O N S */
/************************************************************/
#byte CCPR1L = 0x13
#byte CCP1CON = 0x15
#define GP0 PIN_A0
#define GP1 PIN_A1
#define GP2 PIN_A2
#define GP3 PIN_A3
#define GP4 PIN_A4
#define GP5 PIN_A5
#define VALUE 95
/************************************************************/
/* G L O B A L V A R I A B L E S */
/************************************************************/
long PWM;
/************************************************************/
/* F U N C T I O N S */
/************************************************************/
void setup()
{
setup_oscillator(OSC_1MHZ);
setup_adc_ports( NO_ANALOGS ); // Disable analog inputs
setup_adc( ADC_OFF ); // Disable A2D
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,255,16); // 60Hz PWM frequency
setup_ccp1(CCP_PWM);
setup_comparator(NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RA3);
enable_interrupts(GLOBAL);
}
/******************************************************************/
/* I N T E R R U P T V E C T O R S */
/******************************************************************/
#INT_RA
void int_ra_isr(void)
{
char A;
// Put here your code for ISR
A = input(PIN_A3); ; // Clear mismatch condition
}
/******************************************************************/
/* M A I N P R O G R A M */
/******************************************************************/
void main(void)
{
delay_ms (1000);
setup ();
while(TRUE)
{
set_pwm1_duty(VALUE);
}
}
|
_________________ I Came. I Saw. I Won. |
|
|
|
|
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
|