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

Problems INT_EXT or WDT ?

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



Joined: 25 Mar 2011
Posts: 7

View user's profile Send private message

Problems INT_EXT or WDT ?
PostPosted: Tue Apr 05, 2011 7:49 am     Reply with quote

Hi, I have implemented an application with a PIC18F452 on CCS. When the PIC receive an interrupt for RB0, the PIC performs a process. Everything works fine but the problem occurs after a time that the PIC has been energized. I do not understand why the PIC is frozen, is it something to do with the WDT? This error is related to the WDT?
temtronic



Joined: 01 Jul 2010
Posts: 9163
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Apr 05, 2011 8:06 am     Reply with quote

Show us a small program that has the problem, please include compiler version and PIC type.
Alejandro



Joined: 25 Mar 2011
Posts: 7

View user's profile Send private message

PostPosted: Tue Apr 05, 2011 9:52 am     Reply with quote

I am use the CCS 4.074.

Here is my code:

Code:
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)// RS232 Estándar

#include <241025multi.h>

#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

//***********************************************************************************
//*                        DECLARACION DE INCLUDES                        *
//***********************************************************************************
#include <string.h>
#include <STDLIB.H>
#include <MATH.H>
#include <Flash_leds.h>

//***********************************************************************************
//*                        DECLARACION DE REGISTROS                     *
//***********************************************************************************
#byte reg_TXREG  =  0xFAD               // Buffer de TX del UART
#byte reg_RCREG  =  0xFAE
#byte port_b     = 0x0F81               //declaracion del puerto b

//***********************************************************************************
//*                        DECLARACION DE DEFINES                        *
//***********************************************************************************
#define ON              output_high
#define OFF             output_low
#define BUFFER_SIZE 550

//***********************************************************************************
//*                        DECLARACION DE VARIABLES                     *
//***********************************************************************************
int xbuff=0x00;                     
int16 Indice_Buff=0x00;
char Buffer_Modulo1[lenbuff];                // Buffer
char flagcommand = 0;                    
char Flag_Modulo2 = 0;                    
char flag = 0;
int UART_Modo;
int16 j;
int p;
int32 q;
int32 r;
int t;
int16 Data_TX;
int Buffer_Cont;
int16 k;
int8 buffer[BUFFER_SIZE];
int16 next_in = 0;
int16 next_out = 0;
int8 n = 0;
int8 Buffer_Modulo2 = 0;
int16 Cont_Data_Modulo2;
int16 Pag_SMS;

int Mensaje_Modulo1 = 0;
int Modulo2_OK;
char Data_Modulo2[538] ;
char Buffer_Pag_Modulo1[9];
int32 Pag_MSB_Modulo1;
char Pagina_Modulo1[4];
int8 bufferx[4];
int Buffer_Pag_Modulo2[2];
int32 Pag_Modulo1;
int32 Pag_Modulo2;
int32 Cont_Pag_Modulo2;
char Ping_ON = 0;
char PAG_ON = 0;
int   Conta_Comas;
char Valor[2];
int Nro_Mensajes;
char Variable;
int i;
int Hay_mas_Mensajes;

//***********************************************************************************
//*                              #priority                           *
//*      Configura la prioridad de las interrupciones del proceso               *
//***********************************************************************************

#priority INT_EXT,INT_RDA

//***********************************************************************************
//*                              #INT_RDA                           *
//***********************************************************************************

#INT_RDA
void serial_isr() {                       
    unsigned int t, p;

   p = getc();

    switch (UART_Modo) {

        case  1: Add_Buffer_Moudlo1(p);                   
                 break;

        case  2: Flag_Modulo3 = 1;
             buffer[next_in]= p;                  
                t=next_in;
                next_in=(next_in+1) % BUFFER_SIZE;
                if(next_in==next_out)
                 next_in=t;                       
                 break;
       }
}

//***********************************************************************************
//*                              INT_RB0                              *
//*      Monitorea alguna Interrupcion por cambio de estado del RB0               *
//***********************************************************************************

#INT_EXT
void IntRB0()
{
   Mensaje_Modulo1 = 1;   
}

//***********************************************************************************
//*                              bkbhit                              *
//*      Llena el buffer del recepcion con los datos del GPS                     *
//***********************************************************************************

#define bkbhit (next_in!=next_out)

int bgetc() {
   BYTE x;

   WHILE(!bkbhit) ;
   x = buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(x);
}

//***********************************************************************************
//*                              iniBuffer_Modulo1                     *
//***********************************************************************************

void Ini_Buffer_Modulo1(void){                   
  int n;
  int count=32;
  for(n=0;n<count;n++){                       // Bucle que pone a 0 todos los
    Buffer_Modulo1[n]=0x2;                         // caracteres en el buffer
   }
  xbuff=0x00;                                 // Inicializo el índice de siguiente
}

//***********************************************************************************
//*                              addBuffer_Modulo1                     *
//*      Llena el buffer de recepcionBuffer_9601 con los caracteres recibidos del   *
//*      modem 9601                                                   *
//***********************************************************************************

char Add_Buffer_Modulo1(char c){                   
  switch(c){
      case 0x0A:                                // Enter -> Habilita Flag para procesar
       if (flag >= 3 )
              flagcommand=1;   
        else
         flag++;
       break;
    default:
      Buffer_Modulo1[xbuff++]=c;                   // Añade carácter recibido al Buffer
  }
}

.
.
.
.
.
.

//***********************************************************************************
//*                           Enable_Int_Hardware                        *
//*      Habilita todas la insterrupciones producidas por el PortB y el RTC         *
//***********************************************************************************

void Enable_Int_Hardware(){
    enable_interrupts(int_ext);            // Activar interrupcion RB0      
    ext_int_edge(H_TO_L);                  // por cambio de Alto a Bajo
    enable_interrupts(GLOBAL);               // Activa todas las Interrupciones
}

//***********************************************************************************
//*                           Disable_Int_Hardware                     *
//*      Deshabilita todas la insterrupciones producidas por el PortB y el RTC      *
//***********************************************************************************

void Disable_Int_Hardware(){
    disable_interrupts(int_ext);            // Desactivar interrupcion RB0
    disable_interrupts(GLOBAL);            // Desactiva todas las Interrupciones
}

//***********************************************************************************
//*                           Enable_Int_UART                           *
//*      Habilita todas la insterrupciones producidas por UART                  *
//***********************************************************************************

void Enable_Int_UART(){
    enable_interrupts(INT_RDA);
    enable_interrupts(GLOBAL);
    clear_interrupt(INT_RDA);
}

//***********************************************************************************
//*                           Disable_Int_UART                        *
//*      Deshabilita todas la insterrupciones producidas por UART               *
//***********************************************************************************

void Disable_Int_UART(){
    disable_interrupts(INT_RDA);
    disable_interrupts(GLOBAL);
}

//***********************************************************************************
//*                           Programa Principal                        *
//***********************************************************************************

void main(){
   
   SET_TRIS_B (0b11111111);            
   SET_TRIS_D (0b00000000);            

   output_bit( PIN_D0, 0);               
   output_bit( PIN_D1, 0);            
   Mensaje_Modulo1 =0;

   Disable_Int_Hardware();
   Disable_Int_UART();

   Wr_EEprom_Request();

   Init_Modulo1();

   enable_Int_Hardware();

   Ping_ON = 0;
   PAG_ON = 0;

while (TRUE){

   if (Mensaje_Modulo1){
      disable_Int_Hardware();

      Hay_mas_Mensajes = 0;
      do{
      Interroga_Modulo1();
      Mensaje_Modulo1 = 0;

      if (Ping_ON ){
         Modo_Moudlo1_Ping();
         Ping_ON = 0;
      }
      if (PAG_ON ){
         Interroga_Modulo2();
         Modo_Modulo3();
         PAG_ON = 0;
      }
      if (Nro_Mensajes != 0){
         Nro_Mensajes--;
         Hay_mas_Mensajes = 0;
      }   
      else {
         Hay_mas_Mensajes = 1;
         }   

      } while (Hay_mas_Mensajes == 0);

      enable_Int_Hardware();
     }            
   }
}

dyeatman



Joined: 06 Sep 2003
Posts: 1923
Location: Norman, OK

View user's profile Send private message

PostPosted: Tue Apr 05, 2011 10:02 am     Reply with quote

One thing I see right off... In #INT_EXT you do not clear the interrupt for
RB0. I see later where you disable/enable the interrupt but it is still not
cleared. You would typically do this by reading the port or using the
clear_interrupt() command.
_________________
Google and Forum Search are some of your best tools!!!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19337

View user's profile Send private message

PostPosted: Tue Apr 05, 2011 10:12 am     Reply with quote

There are lots of things that could be wrong, which we can't see, and a few that 'are'.

Now, you declare your buffer to have size 'lenbuff', but the declaration for this is not shown.
Then, you use the '%' operator to get the remainder, and limit the counter to the 'BUFFER_SIZE'. Don't. This _must_ only be used with _binary_ buffer sizes (8,16,32, 64 characters etc.. Used with an odd number like 550, it results in the compiler having to perform an integer division in the interrupt. In your case, if the buffer really is 550 characters long, it'll need a int16 division, and will result in interrupts being disabled in any int16 divisions in the external code, as well as a huge amount of time being used. 550, is a really ludicrous amount of memory for a buffer, and unless you are doing something silly a much smaller size will be better.
Then you seem to have two different buffers being used.
In the Add_Buffer_Modulo1 routine, there is no sign of a test for the buffer size being reached. Without this, there is a good change, that this routine _will_ write over and destroy variables stored after it's buffer (who's size we cannot tell, because no sign of the lenbuff declaration). Probable reason for hang. However the address used here is an int8, not an int16.

Seriously, switch to the standard ex_sisr code, and use a buffer size like 128 bytes, or recode the size limit using a test like:
Code:

if (++next_in == BUFFER_SIZE) next_in=0;

and the same for the next_out counter.

There is no sign of a buffer overflow test. Again possible problems.

No, your problem is not the watchdog. In fact if you had a watchdog, it with care, might be able to allow your code to recover from the problems, _but_ you must fix the code first, otherwise it could be hiding dangerous problems...

Best Wishes
Alejandro



Joined: 25 Mar 2011
Posts: 7

View user's profile Send private message

PostPosted: Tue Apr 05, 2011 1:28 pm     Reply with quote

Hi Ttelmah, thank you by your help..

Quote:
you declare your buffer to have size 'lenbuff', but the declaration for this is not shown

I'm sorry, here is:
Code:
int const lenbuff = 32;                // Longitud de buffer

Quote:
if the buffer really is 550 characters long, it'll need a int16 division, and will result in interrupts being disabled in any int16 divisions in the external code, as well as a huge amount of time being used. 550, is a really ludicrous amount of memory for a buffer, and unless you are doing something silly a much smaller size will be better.

Unfortunately I have to use a buffer of this size, because when I interrogate the Module2 this answer me with a string of 550 ASCII characters
Quote:
Seriously, switch to the standard ex_sisr code, and use a buffer size like 128 bytes, or recode the size limit using a test like:
Code:

if (++next_in == BUFFER_SIZE) next_in=0;

Is correct this change?
Code:
case  2: Flag_Modulo3 = 1;
             buffer[next_in]= p;                  // Interrupcion producida por el MGRAFO
                t=next_in;
             if (++next_in == BUFFER_SIZE)
                   next_in=0;
                 else
                    next_in=t;                       
                 break;

and this another?

Code:
#define bkbhit (next_in!=next_out)

int bgetc() {
   BYTE x;

   WHILE(!bkbhit) ;
   x = buffer[next_out];

   if (++next_out == BUFFER_SIZE) next_out=0;
    return(x);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19337

View user's profile Send private message

PostPosted: Tue Apr 05, 2011 2:39 pm     Reply with quote

Seriously, the return message being this size, is _not_ a reason to have a buffer this large.
Assuming you are processing this message as it arrives, the buffer _only_ needs to be the size corresponding to how much behind the message the processor will get at the worst case. The only reason to buffer the whole thing, would be if there was a part at the end, that was needed before you can start processing the beginning. It is like a reader refusing to read a message arriving on a teletype until the entire message has arrived. Normally you start reading at the beginning, and will only be a few characters behind the message as it arrives.

Best Wishes
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