|
|
View previous topic :: View next topic |
Author |
Message |
hqv
Joined: 21 Sep 2005 Posts: 9
|
problem with int_rda |
Posted: Tue Nov 29, 2005 2:34 pm |
|
|
hello everybody:
i have a problem related to the interrupts rda.
In my project I consider a pic which trasmit toward the pc (usart hardware) and toward another pic by an usart (software). all functions well except the interruption rda, if command data since the pc to pic, the pic does not detect them and therefore does not enter to the interruption.
what can i do?
it's important for me.
hqv
forgive my English |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 29, 2005 3:58 pm |
|
|
Post a very short program that shows the problem. Make sure to post
all #include, #use, and #fuses statements. |
|
|
hqv
Joined: 21 Sep 2005 Posts: 9
|
that is my problem |
Posted: Tue Nov 29, 2005 8:50 pm |
|
|
hi everyboady:
the program that record in the pic is simple,is the following one:
Code: |
#include <16F877.h>
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7,stream=pcs)
#use rs232(baud=9600,xmit=PIN_D6, rcv=PIN_D7,stream=pic2)
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT
#include <lcd2.c>
int buffer,next_in=0;
int estado=0;
#int_ext
void encendido(void)
{
switch(estado)
{
case(0):
{
estado=1; //se cambia a estado ENCENDIDO
lcd_putc('\f'); //se borra display
lcd_gotoxy(6,1); //6 donde esta la S
lcd_putc("Sistema");
lcd_gotoxy(4,2);
lcd_putc("Ence_ndido");
enable_interrupts(int_rb); //habilita int_rb
enable_interrupts(int_rda); //habilita int_rda
break;
}
case(1):
{
estado=0; //se cambia a estado APAGADO
lcd_putc('\f'); //borra LCD
lcd_gotoxy(6,1);
lcd_putc("Sistema");
lcd_gotoxy(6,2);
lcd_putc("Apagado");
disable_interrupts(int_rb); //deshabilita int_rb
disable_interrupts(int_rda); //deshabilita int_rda
break;
}
}//fin switch
}//Fin interrupci�n ext encendido
#INT_RDA
void recepcion(void)
{
int t;
output_high(pin_a5);
delay_ms(1000);
buffer[next_in]=getc();
output_low(pin_a5);
}//fin interrupcion Transmision/Recepcion
void main(void)
{
set_tris_a(0x00);
setup_adc_ports(no_analogs);
output_a(0x00);
fprintf(pcs,"inicio Main\r\n");
enable_interrupts(int_ext);
ext_int_edge(l_to_h);
enable_interrupts(int_rda);
enable_interrupts(global);
while(1)
{
switch(estado)
{
case(0):
{
output_high(pin_a0);
delay_ms(100);
output_low(pin_a0);
delay_ms(100);
break;
}
case(1):
{
output_high(pin_a1);
delay_ms(100);
output_low(pin_a1);
delay_ms(100);
break;
}
}//fin switch
}//fin while
}//fin main
|
the problem is the following one:
when the active the interruption ext the first thing that causes is to enter to the int_rda and then does not enter more to the interruption.
when I defuse the int_ext all functions well
i don't know That can be? which is the bad part?
i need help
thanks for reponding pcm programmer |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 29, 2005 10:24 pm |
|
|
Make the changes shown in bold, below:
Quote: |
#include <16F877.h>
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C6, rcv=PIN_C7, ERRORS, stream=pcs)
#use rs232(baud=9600,xmit=PIN_D6, rcv=PIN_D7,stream=pic2)
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT, NOLVP |
Also, it's a bad programming method to put a large delay inside an
interrupt function -- especially in the #int_rda function. It prevents
the function from receiving RS232 characters.
Quote: | #INT_RDA
void recepcion(void)
{
int t;
output_high(pin_a5);
delay_ms(1000);
buffer[next_in]=getc();
output_low(pin_a5);
}//fin interrupcion Transmision/Recepcion |
There are other design problems with your code, but the problems
listed above should be fixed first. |
|
|
Brian S
Joined: 06 Sep 2005 Posts: 13
|
|
Posted: Tue Nov 29, 2005 10:37 pm |
|
|
If you are using Port B pins, add NOLVP to the "fuses" list.
Otherwise, activity on programming pins will cause trouble. |
|
|
hqv
Joined: 21 Sep 2005 Posts: 9
|
|
Posted: Wed Nov 30, 2005 12:48 pm |
|
|
pcm programmer :
I made the changes that you suggested myself, but it doesn't work.
my program only does the following:
always blinks the led in pin a0 in the state =0, waiting for int_ext for change the state (state=1) where always blinks the led in the pin a1.
when the program is in the state 0 ,it doesn't have no problem with for receiver datas from pc, but when the interrupts_ext is activated, it is here where is the problem. it enters the interrupts_ext and enters the interrupts_rda too, with that the interrupts_rda doesn't work more.
i send the datas from pc and the pic doesn't work more.
Quote: |
#INT_RDA
void recepcion(void)
{
int t;
output_high(pin_a5);
delay_ms(1000);
buffer[next_in]=getc();
output_low(pin_a5);
}//fin interrupcion Transmision/Recepcion
|
delay is only for see if enter the interrupts_rda, nothing else.
thanks for the answers.
and you forgive me for my english
thanks again
hqv |
|
|
hqv
Joined: 21 Sep 2005 Posts: 9
|
|
Posted: Wed Nov 30, 2005 1:28 pm |
|
|
hello again:
the problem isn't the interrupts ext or rda else the librery lcd.c.
i use de lcd 16*2 in my project therefor i use the driver include with the compiler ccs.
i made a lot of test until discovery wich is the real problem.
when bag the instruccion lcd_init the two interruptions work well, but when i wrote that intruccion in my code begins the problems.
really i need help
hqv |
|
|
hqv
Joined: 21 Sep 2005 Posts: 9
|
|
Posted: Wed Nov 30, 2005 1:32 pm |
|
|
i use pines's control :
pin_d0,d1 and d2
and pines's data
Rc0,c1,c2,c3 and c4.
the driver is the following one:
Code: |
////////////////////////////////////////////////////////////////////////////
//// LCD.C ////
//// Driver for common LCD modules ////
//// ////
//// lcd_init() Must be called before any other function. ////
//// ////
//// lcd_putc(c) Will display c on the next position of the LCD. ////
//// The following have special meaning: ////
//// \f Clear display ////
//// \n Go to start of second line ////
//// \b Move back one position ////
//// ////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
//// ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
//// ////
////////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,1997 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
////////////////////////////////////////////////////////////////////////////
// As defined in the following structure the pin connection is as follows:
// D0 enable
// D1 rs
// D2 rw
// C0 D4
// C1 D5
// C2 D6
// C3 D7
//
//
// ESTRUCTURA CONTROL LCD PUERTO E
struct lcd_pin_map
{
boolean enable; // D0 ENABLE
boolean rs; // D1 RS
boolean rw; // D2 RW
boolean unused; // NADA
} lcd_control;
//ESTRUCTURA DATOS LCD PUERTO C
struct lcd_pines_datos
{
int datos:4; // C0 a C3 datos LCD
} lcd_datos;
#byte lcd_control = 8 //puerto D control(0x08)
#byte lcd_datos = 7 //puerto C datos (0x07)
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
STRUCT lcd_pin_map const LCD_WRITE = {0,0,0,0}; // For write mode all pins are out
STRUCT lcd_pin_map const LCD_READ = {1,1,1,1};
byte lcd_read_byte()
{
byte low,high;
set_tris_d(LCD_WRITE);
set_tris_c(LCD_READ); //C0 a C3 entradas
lcd_control.rw = 1;
delay_cycles(1);
lcd_control.enable = 1;
delay_cycles(1);
high = lcd_datos.datos;
lcd_control.enable = 0;
delay_cycles(1);
lcd_control.enable = 1;
delay_us(1);
low = lcd_datos.datos;
lcd_control.enable = 0;
set_tris_c(LCD_WRITE); //C0 a C3 salidas
return( (high<<4) | low);
}
void lcd_send_nibble( byte n )
{
lcd_datos.datos = n;
delay_cycles(1);
lcd_control.enable = 1;
delay_us(2);
lcd_control.enable = 0;
}
void lcd_send_byte( byte address, byte n )
{
lcd_control.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd_control.rs = address;
delay_cycles(1);
lcd_control.rw = 0;
delay_cycles(1);
lcd_control.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init()
{
byte i;
set_tris_d(LCD_WRITE); //D0,D1 y D2 salidas al control del LCD
set_tris_c(LCD_READ); //C0 a C3 entradas
lcd_control.rs = 0;
lcd_control.rw = 0;
lcd_control.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
}
void lcd_gotoxy( byte x, byte y)
{
byte 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;
}
}
char lcd_getc( byte x, byte y)
{
char value;
lcd_gotoxy(x,y);
lcd_control.rs=1;
value = lcd_read_byte();
lcd_control.rs=0;
return(value);
}
|
thanks
hqv |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 30, 2005 3:49 pm |
|
|
Don't do large delays inside any interrupt function.
1. Don't do delay_ms().
2. Don't call LCD functions (These take a lot of time).
Just set a flag variable inside the interrupt function, to show that
the interrupt happened. Then in main(), you should check that flag
in a while(1) loop. If the flag is true, then do some action. Also
clear the flag. |
|
|
|
|
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
|