|
|
View previous topic :: View next topic |
Author |
Message |
evaradharaj
Joined: 15 Jan 2009 Posts: 60
|
Reg: INT_RDA and INT_EXT Problem |
Posted: Mon Aug 01, 2011 7:49 am |
|
|
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: 19499
|
|
Posted: Mon Aug 01, 2011 8:22 am |
|
|
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
|
Reg: interrupt |
Posted: Mon Aug 01, 2011 9:40 am |
|
|
Thanks Ttelmah for your quick reply . I will get back to you after i do check in real time hardware. _________________ embedding innovation in engineers |
|
|
|
|
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
|