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

Reg: INT_RDA and INT_EXT Problem

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



Joined: 15 Jan 2009
Posts: 60

View user's profile Send private message Visit poster's website

Reg: INT_RDA and INT_EXT Problem
PostPosted: Mon Aug 01, 2011 7:49 am     Reply with quote

Hi,

I am using pic16f877a microcontroller. Some the INT_EXT is working well. But INT_RDA is not working some times.

Here is my code, please tell me the possible causes and solutions.

Code:

#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)


#include "lcd_Driver.c"
//#include "Keypad_Driver.c"

#define message_end 26

int1 flag = 0;
int1 off_flag = 1;
int i ;

char number_off[20] = {0};
char number[10] = {0};
int count_off = 0;
char first_data;
int1 char_off_flag = 0;
int1 flag_serial = 0;

char phone_number[10] = {'9','7','9','1','5','9','2','2','3','7'};



#int_EXT
void  EXT_isr(void)
{
   flag = 1;
}

#int_RDA
void  RDA_isr(void)
{
   first_data = getc();
 // printf(lcd_putc,"%c",first_data);

  if(first_data == '+' && char_off_flag == 0)
  {
      count_off = 0;
      //printf(lcd_putc,"\nhai");
      char_off_flag = 1;
  }

  else if(char_off_flag == 1)
  {
      number_off[count_off] = first_data;
      count_off++;
     

      if(count_off == 20)
      {
       
         count_off = 0;
                 
     
            if(read_eeprom(0) == number_off[10] &&
            read_eeprom(1) == number_off[11] &&
            read_eeprom(2) == number_off[12] &&
            read_eeprom(3) == number_off[13] &&
            read_eeprom(4) == number_off[14] &&
            read_eeprom(5) == number_off[15] &&
            read_eeprom(6) == number_off[16] &&
            read_eeprom(7) == number_off[17] &&
            read_eeprom(8) == number_off[18] &&
            read_eeprom(9) == number_off[19])

            {
                printf("ATH\n\r");
                output_low(pin_b6);
                output_low(pin_b5);
                flag = 0;
                printf("at+cmgf=1\n\r");
                printf("AT+CMGS=");
                putc('"');
                for(i = 0; i < 10; i++)
                {
                    printf("%c",read_eeprom(i));
                }
                putc('"');
                printf("\n\r");
                printf("SYSTEM IN OFF CONDITION");
                printf(lcd_putc,"\rsystem off");
                putc(message_end);
                disable_interrupts(INT_EXT);
               
                char_off_flag = 0;
                disable_interrupts(INT_RDA);
                disable_interrupts(GLOBAL);
            }
      }
   }
}


int main()
{
   int count = 0;
   int i;
   char phone_digit[10];

   set_tris_b(0x8F);
   output_high(pin_b7);
   output_low(pin_b6);
   output_low(pin_b5);
   set_tris_c(0xc0);


   //kbd_init();
   lcd_init();

   delay_ms(2000);
   
   printf("at\n\r");
   printf("at+clip=1\n\r");

   printf(lcd_putc,"WELCOME");
   delay_ms(1000);

   
   for(count = 0; count < 10; count++)
   {
      write_eeprom(count, phone_number[count]);
   }
   
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   


   while(1)
   {
      if(flag == 1)
      {
         output_high(pin_b6);
         output_high(pin_b5);
         printf("AT\n\r");
         printf("ATD+");
         printf("91");
         for(i = 0; i < 10; i++)
         {
               printf("%c",read_eeprom(i));
         }
         printf(";\n\r");
         delay_ms(15000);
         printf("ATH\n\r");
         delay_ms(10000);
         flag = 0;
         
        // printf("ATD+");
        // printf("91");
        // for(i = 10; i < 20; i++)
        // {
        //       printf("%c",read_eeprom(i));
        // }
         //printf(";\n\r");
        // delay_ms(15000);
        output_low(pin_b6);
        output_low(pin_b5);
       
      }

   }
       
 // TODO: USER CODE!!

}



LCD driver

#define LCD_DB4   PIN_C0
#define LCD_DB5   PIN_C1
#define LCD_DB6   PIN_C2
#define LCD_DB7   PIN_C3

#define LCD_E     PIN_A2
#define LCD_RS    PIN_A0
#define LCD_RW    PIN_A1

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW   1

//========================================

#define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line


int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
 0xc,                    // Display on
 1,                      // Clear display
 6                       // Increment cursor
 };


//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2));
 output_bit(LCD_DB6, !!(nibble & 4));
 output_bit(LCD_DB7, !!(nibble & 8));

 delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;

output_high(LCD_E);
delay_cycles(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);

output_low(LCD_E);

return(retval);
}
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);

 delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);

    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_LCD_RW
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;

if(y != 1)
   address = lcd_line_two;
else
   address=0;

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      delay_ms(2);
      break;

    case '\n':
       lcd_gotoxy(1,2);
       break;

    case '\b':
       lcd_send_byte(0,0x10);
       break;

    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);

return(value);
}
#endif


Please tell me the possible causes and the solution.

Thanks in advance.
_________________
embedding innovation in engineers
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Mon Aug 01, 2011 8:22 am     Reply with quote

You are doing _far_ too much in the interrupt.
Look at ex_sisr, for an example of how to handle the serial receive.
Think about it for a moment. INT_RDA, could trigger every 1.04mSec. A print like:
printf("SYSTEM IN OFF CONDITION");
Will take 23 times this long to execute.....

General rule with interrupts, is _keep the handler short_. Just handle the actual 'event' that has triggered the interrupt, and get out. Do the slow work in the main code.
The serial receive interrupt, should just receive the character that is waiting. Nothing else.

Best Wishes
evaradharaj



Joined: 15 Jan 2009
Posts: 60

View user's profile Send private message Visit poster's website

Reg: interrupt
PostPosted: Mon Aug 01, 2011 9:40 am     Reply with quote

Thanks Ttelmah for your quick reply . I will get back to you after i do check in real time hardware.
_________________
embedding innovation in engineers
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