CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

12F683 with #INT_RA (PWM not working )

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Joan



Joined: 29 May 2004
Posts: 41
Location: Barcelona, Spain

View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger

12F683 with #INT_RA (PWM not working )
PostPosted: Fri Jan 30, 2009 12:40 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 30, 2009 12:51 pm     Reply with quote

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

View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger

PostPosted: Fri Jan 30, 2009 3:18 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 30, 2009 4:02 pm     Reply with quote

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







PostPosted: Fri Jan 30, 2009 4:05 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 30, 2009 4:07 pm     Reply with quote

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

View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger

PostPosted: Fri Jan 30, 2009 5:53 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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