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

Write_EEPROM and RDA interrupt conflict.

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



Joined: 08 Sep 2003
Posts: 8

View user's profile Send private message

Write_EEPROM and RDA interrupt conflict.
PostPosted: Mon Jan 24, 2005 2:19 pm     Reply with quote

My problem is an unexplainable disabling of the serial interrupt.
Using a 18F452, PCH 3.152
I have a host computer polling one register in EEPROM. The PIC receives this poll, and replies with the register value. The register value changes, repending on an Input Logic level. I think that I hit a snag, when the poll ocurrs as the input pin changes state.
At that time, I no longer get the serial interrupt.
I added LEDs to the code, so I could see. The program enters, and leaves the ISR, but, once a conflict ocurrs, the serial interrupt is disabled.

The attached code still conflicts. I have thinned it out, to try to find the problem.
Any thoughts ?

Thanks
Cam
Code:

////////////////////////////////////////////////////////////////////////////
////                          TMB_452-13Jan05.C                          ////
////   Thinned out, to find why Serial Interrupt is being Disabled.   ////
////////////////////////////////////////////////////////////////////////////

#include "18F452.H"

////   Definitions         ////
#DEFINE DIGIN1 PIN_D1      //PIN FOR DIGITAL INPUT 1 
#DEFINE FULL_RESET PIN_B1   //RESET RELAY, OUTPUT PIN
#use standard_io(C)
#DEFINE DIG_MASK 0XF4   //DIGITAL ALARM DISABLE MASK

short   check_alarm=0;      //used to set how long between alarm checks.
INT   DIG_AMIOK;            //BIT BY BIT (FOR 6 BITS) DIGITAL "AM I OK?"
INT   LAST_DIG=0xFF;         //THIS IS THE LAST ALARMS I HAD.
long   silent_time;      //used for a "long idle time" reset.
long   int_count=0;         // Number of interrupts left before a second has elapsed
int   SECONDS=0;            //a running real time counter.  starts at 0 on reset, counts forever.
short from_host=0;         //set in Serial ISR, while Host is sending
int   byte_count=0;         //counter for received numbers
int   RMC_data_in[8];         //Array for data received from Host.

#byte porta=5         //These lines define the Ports.
#byte portb=6
#byte portc=7
#byte portd=8
#byte porte=9
////   End of Definitions   ////

#fuses HS,NOPROTECT,NOWDT,PUT,NOLVP   //WDT disabled for testing, NEEDS re-enabled
#use delay(clock=4000000)      //USING A 4MHz CRYSTAL
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=n)   

////////////////////////////////////////////////////////////
////   THE NEXT LINES ARE THE Rx Data INTERRUPT ROUTINE.   ////
#int_rda
VOID serial_isr()
   {
   if(kbhit())               //is there a serial byte ready ?
      {
      output_high(pin_d5);            //turn on a LED for testing
      RMC_data_in[byte_count]=getc();   //save data to the array
      Silent_Time=0;               //reset silent time counter
      if(++byte_count>=6)            //ARRAY NOW HAS THE 6 BYTE MODBUS COMMAND (use >=, to catch a runaway)
         {byte_count=0;            // Buffer full, RESET IT
         from_host=1;            //set flag, to check the string
         }//end if byte_count==6
      output_low(pin_d5);            //turn off the LED
      }
   }
////   END OF INTERRUPT SERVICE ROUTINE      ////

////////////////////////////////////////////////////////////
VOID main()                //
{
output_low(full_reset);         //don't do it.....
int_count=1;         //Initialize to roll over next time through.
set_timer0(0);
setup_timer_0( RTCC_INTERNAL|rtcc_8_bit|rtcc_div_2);
SETUP_WDT(WDT_OFF);               //DISABLED FOR TESTING
ENABLE_INTERRUPTS(INT_RDA);         //RDA (Serial Receive Data).
enable_interrupts(global);

////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
DO
{
if(--int_count==0)         //has one second gone by ?
   {
   if(++SECONDS==60)      //start again after one minute.
      SECONDS=0;
   int_count=10000;         //Trial and error, 500-low,1000-low,5000-low,10000
   CHECK_ALARM=1;         //check alarms every second
   }//end of --int count==0

if(check_alarm)      //has one second gone by?
   {////   Check the Digital Input Pin.
   DIG_AMIOK=0xFF;         //INITIALISE, ASSUMING NO ALARMS
   IF(!INPUT(DIGIN1))            //CLECK EACH DIGITAL INPUT, ONE AT A TIME.
      {
      BIT_CLEAR(DIG_AMIOK,1);            //This is for real, CLEAR THE ALARM BIT.
      }
   Else BIT_SET(DIG_AMIOK,1);      //No alarm on input 1.   

   Check_Alarm=0;   //reset flag
   }//end of check_alarm

if((dig_amiok!=LAST_DIG))   //check for change of state in alarms
   {
   Write_EEPROM(0XD8,DIG_AMIOK);            //FORCE A SAVE
   LAST_DIG=DIG_AMIOK;
   }

//////////////////////////////////////////////////////////////////////////////////////////

if(from_host)   //from_host is a flag, set in the serial interrupt routine.
            //by now, the array RMC_Data_In[] holds the 6 byte ModBus string.
   {
   output_high(pin_d6);      //turn on a LED for testing
   if(RMC_data_in[1]==3)      //is this a "Read Register Function"?
      {
      if(RMC_data_in[2]==0)   //"TRUE" EEPROM Area      
         {
         putc(0x55);            //repeat site address
         putc(0x03);            //repeat command (0x03)
         putc(0x02);            //number of bytes to follow
         putc(0x00);            //Low Byte Filler
         putc(read_eeprom(RMC_Data_In[3]));   //actual data from eeprom.
         }//End of TRUE EEPROM Reads
      }//End of all "READS"
   output_low(pin_d6);            //turn off the LED
   from_host=0;            //re-set flag.
   }//END OF IF FROM_HOST...
/////////////////////////////////////////////////////////////////////////////////////
////   not much happening...
   if(++silent_time>1000)            //count, while waiting for another Serial Byte
      {
      silent_time=0;               //reset silent serial time timer
      byte_count=0;               //reset byte counter.  Clears a Runt.
      }//end of silent_time>1000
}WHILE (TRUE);            //"DO" IT ALL AGAIN.
}               //end of Main.

PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jan 24, 2005 2:34 pm     Reply with quote

Without examining your code in detail, I can think of a number
of reasons for this:

1. You could be getting several incoming characters in a short time.
The eeprom write takes several milliseconds. You're not servicing
the interrupt during that time, so an overrun occurs. You don't
have the ERRORS directive in your #use rs232 statement, so the
USART receiver locks up.

2. In some versions of the compiler, CCS didn't handle disabling/
enabling interrupts properly during writes to eeprom.
Nandus2000



Joined: 17 Sep 2008
Posts: 10

View user's profile Send private message

Write_EEPROM and RDA interrupt conflict
PostPosted: Wed Jul 08, 2009 4:54 am     Reply with quote

Hi,
I've used #use rs232 statement in my code.
But still I've similar issue because I'm not able to serve RS232 RDA interrupt as program is busy in write_eeprom library function.

I'm using Compiler: CCS version 4.076.

Does anybody know that this conflict has been resolved in the latest version 4.093 at the moment?

Awating your prompt reply.
Thanks!!
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