TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: cheapekt en 05 de Noviembre de 2008, 10:36:41

Título: problema interrupcion rda.
Publicado por: cheapekt en 05 de Noviembre de 2008, 10:36:41
Buenas a todos,
He cogido un código de la página "rincón del ccs"
es el siguiente.
Código: [Seleccionar]
#include   <16f877.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPUT                    //No Power Up Timer
#FUSES PROTECT                  //Code protected from reads
#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
#FUSES NODEBUG                  //No Debug mode for ICD
#use delay(clock=20000000)
#use standard_io(c)
#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5,errors)
char Keypress=' ';

#int_rda
void serial_isr() {

  Keypress=0x00;
  if(kbhit()){
    Keypress=getc();
    if(Keypress!=0x00){
      putchar(keypress);
      keypress=0x00;
      printf("hola amigo");
    }
  }
}


void main() {

  enable_interrupts(global);
  enable_interrupts(int_rda);

  printf("\r\n\Listen on RS232 (Int)\r\n");

  do {


  } while (TRUE);
}

En teoria cuando recibe cualquier carácter en el PC tendria que llegar el mensaje "hola amigo", pero sin embargo no me llega este mensaje al PC,
¿alguien me puede explicar porque motivo no lo envia?
Muchas gracias un saludo!
Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 05 de Noviembre de 2008, 14:00:18
Hola.

Prueba de la siguiente manera y me cuentas:

Código: C#
  1. #include <16f877.h>
  2. #FUSES NOWDT //No Watch Dog Timer
  3. #FUSES HS //High speed Osc (> 4mhz)
  4. #FUSES NOPUT //No Power Up Timer
  5. #FUSES PROTECT //Code protected from reads
  6. #FUSES NOBROWNOUT //No brownout reset
  7. #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  8. #FUSES NOCPD //No EE protection
  9. #FUSES NOWRT //Program memory not write protected
  10. #FUSES NODEBUG //No Debug mode for ICD
  11. #use delay(clock=20000000)
  12. #use standard_io(c)
  13. #use rs232(baud=9600,parity=N,bits=8,xmit=PIN_C6,rcv=PIN_C7)
  14. char Keypress=' ';
  15.  
  16. #int_rda
  17. void serial_isr()
  18. {
  19.         Keypress=0x00;
  20.         if(kbhit())
  21.         {
  22.                 Keypress=getc();
  23.                 if(Keypress!=0x00)
  24.                 {
  25.                         putchar(keypress);
  26.                         keypress=0x00;
  27.                         printf("hola amigo");
  28.                 }
  29.         }
  30. }
  31.  
  32.  
  33. void main()
  34. {
  35. enable_interrupts(global);
  36. enable_interrupts(int_rda);
  37.  
  38. printf("\r\n\Listen on RS232 (Int)\r\n");
  39.  
  40. do {} while (TRUE);
  41. }

Saludos
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 05 de Noviembre de 2008, 16:29:05
gracias por tu ayuda MLO_
 He probado tu codigo, y no me enviaba nada, luego he cambiado la sentencia
#use rs232(baud=9600,parity=N,bits=8,xmit=PIN_C6,rcv=PIN_C7)  por
#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5)
 y me imprime pero tansolo lo que está en el main ("\r\n\Listen on RS232 (Int)\r\n")

No hace caso a la interrupcion lanzada desde el PC, ¿alguien me peude ayudar?
No logro realizar interrupciones  int_rda,

Gracias!!! espero que alguna alma caritativa logre ayudarme, un saludo!
Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 05 de Noviembre de 2008, 17:36:02
Hola.

Me parece extrano porque a mi si me funciono con el codigo que te envie!!!!  :?

(http://img374.imageshack.us/img374/5803/serialht3.png)

Te adjunto el codigo, el .hex y el archivo del proteus.

Saludos
Título: Re: problema interrupcion rda.
Publicado por: RedPic en 05 de Noviembre de 2008, 17:38:46
Puede ser un problema de hard, porque esos programas me han funcionado desde el primer día, y solo con #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7).  :shock:
Título: Re: problema interrupcion rda.
Publicado por: Giovanny en 05 de Noviembre de 2008, 17:52:24
si estas usando max 232 o similar, revisalo, me ha pasado que solo medio chip sirve y el otro medio no..  prueba y nos cuentas.
igual que redpic lo he probado con #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7).  solamente y trabaja bien.
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 05 de Noviembre de 2008, 18:35:23
Vale muchas gracias amigos revisare el hardware y os comentare que tal me ha ido.. muy amables

UN saludo!!!
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 06 de Noviembre de 2008, 09:55:04
Una pregunta.
¿Qué significan exactametne estos warning?

if(c='H'){   Assignament inside relational expression...... ¿no es correcta la expresión?

Después em salen 3 warning mas que dicen
Interrupts disabled during call to prevent re-entrancy: (@I2C_WRITE_1)
Interrupts disabled during call to prevent re-entrancy: (@delay_ms1)
Interrupts disabled during call to prevent re-entrancy: (@PUTCHAR_BIU_1)

Estos 3 warning me señalan la llave que cierra el programa

Creo que por eso no me funciona mi programa, o quizas puede ser un motivo.

He comprobado el hardware y creo que esta correcto.
Cuando la patilla C5 esta a nivel bajo las patillas de habilitacion del max485 están a nivel bajo las 2, es decir las patillas 2 y 3 del max485 estan a nivel bajo. EN este estado el PIC tiene la patilla de transmisión (C6) a nivel alto y la patilla de recepción (C7) a nivel bajo. En este estado entonces el max485 su patilla 1(recepción) se pone a nivel bajo, y la patilla 4 (ransmisión) se pone a nivel alto.


Estoy usando rs485, y esta consigna
#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5)
hace que por defecto el pin C5 esté a un nivel bajo. Es decir estamos en el caso que he puesto anteriormente, quizas como el PIC está en este estado no deja que le lleguen datos, y tengo que modificar el software. Estoy un poco perdido. el programa en cuestión es el siguiente. Si alguien me puede ayudar se lo agradezco enormemente.

Código: [Seleccionar]
#include <16F877.h> // Se añade la libreria del PIC a utilizar



#FUSES NOWDT,HS,NOPUT,PROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG
#use delay(clock=20000000)      //Velocidad del reloj


#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5) //enable=PIN_C5 hace que el C maneje el pin de habilitación


#define EEPROM_SDA PIN_C4   
#define EEPROM_SCL PIN_C3   

#include <24512.c> // Se añade la libreria de la EEPROM 24LC512
#include <external_eeprom.c> // Se añade la libreria para controlar una EPROM externa

//Interrupción probocada por el PC para volcar datos


#int_rda
void serial_isr(){

///////////////////////////////////////////////////////////////////////////////////
///                                                                             ///                                 
///            LECTURA DE DATOS EN LA EEPROM Y ENVIAR AL PC                     ///                             
///                                                                             ///
///////////////////////////////////////////////////////////////////////////////////
      int dato=0,dir2=0,i=0,f=0,g=0,h=0,j=0,k=0;
      float dato2=0;
      char c;
     disable_interrupts(int_rda);//Aqui deshabilito la interrupción
   
      if (kbhit()) 
 //wait until a character has been received
 
    c = getc(); 
 //read character from UART
 
      if(c='H'){
      printf(" Interrupcion ");
     
   
   dato=read_ext_eeprom(dir2); // Leemos la hora en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);

   dato=read_ext_eeprom(dir2); // Leemos los minutos en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);

   dato=read_ext_eeprom(dir2); // Leemos los segundos en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);


      delay_ms(200);
      for (f=0; f<4; f++){ // Leemos las irradiancias de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (g=0; g<4; g++){// Leemos las temperaturas ambientes en la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }     
      for (h=0; h<4; h++){// Leemos las temperaturas en la placa de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (i=0; i<4; i++){// Leemos las velocidades del viento de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (j=0;j<4;j++){// Leemos los voltios de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);   
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (k=0;k<4;k++){// Leemos las intensidades de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);   
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
   }
}
////////////////////////////////////////////////////////////////////////////////////
///                                                                              ///
///                                                                              ///   
///                           PROGRAMA PRINCIPAL                                 ///
///                                                                              ///
///                                                                              ///
////////////////////////////////////////////////////////////////////////////////////
void main(void) // Inicio del programa principal
{

///////////////////////////////////////////////////////////////////////////////////
///                              ///                                 
///            DECLARACIÓN DE LAS VARIABLES E INICIALIZACION DE ÉSTAS           ///                             
///                              ///
///////////////////////////////////////////////////////////////////////////////////
//Variables float que contienen datos de las tablas

   float irra[]    = {1, 2, 3, 6};
   float tempa[]    = {6, 3, 2, 1};
   float tempm[]    = {2, 4, 5, 6};
   float vel[]    = {2, 4, 5, 6};
   float volt[]    = {2, 4, 5, 6};
   float inte[]    = {2, 4, 5, 6};

//Variables int que contienten el valor de la fecha
   int min,sec,hr;

//Inicialización de las variables necesarias para movernos por la EEPROM
   int dir=0;

//Iniciaización variables para necesarias para moverse dentro de los datos
   int f=0,g=0,h=0,i=0,j=0,k=0;

   min=0;
   sec=0;
   hr=0;

////////////////////////////////////////////////////////////////////////////////////
///                                                                              ///                                 
///        GUARDAR DATOS EN EEPROM EXTERNA Y INICIALIZAR CONTAJE RELOJ           ///                             
///                                                                              ///
////////////////////////////////////////////////////////////////////////////////////
   
   init_ext_eeprom(); // Inicializamos EEPROM EXTERNA

   delay_ms(200);// retraso 200 milisegundos para no colapsar PIC
   
   
   //rtc_get_time(hr,min,sec); //Guardamos la hora, minuto y segundo que nos da el RTC
   write_ext_eeprom(dir,hr); // Escribimos la hora en la EEPROM
   dir=dir+1; // Incrementamos el puntero de la EEPROM

   write_ext_eeprom(dir,min); // Escribimos los minutos en la EEPROM
   dir=dir+1; // Incrementamos el puntero de la EEPROM

   write_ext_eeprom(dir,sec); // Escribimos los segundos en la EEPROM
   dir=dir+1; // Incrementamos el puntero de la EEPROM

      delay_ms(200);
      for (f=0; f<4; f++){ // Escribimos las irradiancias en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, irra[f]);
         delay_ms(200);     
         dir=dir+4;
      }
      f=0;

      for (g=0; g<4; g++){// Escribimos las temperaturas ambientes en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, tempa[g]);
         delay_ms(200);     
         dir=dir+4;
      }
      g=0;

      for (h=0; h<4; h++){// Escribimos las temperaturas en la placa en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, tempm[h]);
         delay_ms(200);     
         dir=dir+4;
      }
      h=0;

      for (i=0; i<4; i++){// Escribimos las velocidades del viento en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, vel[i]);
         delay_ms(200);
         dir=dir+4;
      }

      i=0;
      for (j=0;j<4;j++){// Escribimos los voltios en la EEPROM EXTERNA
        write_float_ext_eeprom(dir, volt[j]);
        delay_ms(200);   
         dir=dir+4;
      }
      j=0;

      for (k=0;k<4;k++){// Escribimos las intensidades en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, inte[k]);
         delay_ms(200);   
         dir=dir+4;
      }
      k=0;

            printf(" ariburri ");
            delay_ms(500);                  // espera por ejemplo 0,5 seg para enviar nuevamente el dato,
            output_HIGH(PIN_B1);        // por ejemplo conectas un led entre el pin B1 y masa y este debe prender
            delay_ms(250);                  // espera por ejemplo 0,25 seg
            output_LOW(PIN_B1);         // se apaga el led
            delay_ms(250);                  // esperas otros 0,25 seg para enviar nuevamente el dato,
                     
 
  do{
                       
                     enable_interrupts(global);
                     enable_interrupts(int_rda);
 
   }while(TRUE);

}

Cualquier error que creeis que estoy cometiendo y no lo veo por favor diganmelo, no se que hacer.

Gracias y siento las molestias y mi pesadez
Título: Re: problema interrupcion rda.
Publicado por: RedPic en 06 de Noviembre de 2008, 10:02:29
Con respecto a

if(c='H'){   Assignament inside relational expression...... ¿no es correcta la expresión?

En C = es asignación y == comparación por lo que te esta avisando de que estas asignando el valor 'H' a la variable c y que por lo tanto no estas comparando si el valor de c es igual a 'H'

A otra cosa mariposa. Con todo el respeto, cariño y consideración del mundo: Tu #int_rda es una barbaridad.  :mrgreen:

Hay un principio general que dice que "En una interrupción haz exactamente lo imprescindible para atenderla, el resto debe hacerse fuera de ella"

Y tu interrupción #int_rda, que se dispara cada vez que recibe un carácter, recoge el primero recibido y se pone a escribir la USART, a leer la EEPROM, a hacer cálculos, bucles, print-efes y solo le falta que la mandes a por tabaco.

Te recomiendo encarecidamente que reestructures tu código para que la interrupción reciba lo que la interrumpe y haga todo el resto en el main().

En el foro hay decenas de ejemplos de cómo hacer esto de forma sencilla a la par que elegante. Voy a mirar por ahí y después te pongo unos ejemplos, o dale caña al buscador de Foro que para eso lo pagamos. ja, ja, ja  :D :D :D

Título: Re: problema interrupcion rda.
Publicado por: RedPic en 06 de Noviembre de 2008, 10:14:26
Fíjate en este simplísimo ejemplo que colgué en el hilo Teoría y praxis de las com serie TTL : 3.- Comandos de un solo carácter (http://www.todopic.com.ar/foros/index.php?topic=23222.msg186164#msg186164)
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 06 de Noviembre de 2008, 10:15:33
Muchisimas gracias sr. RedPic, ya tengo un problema resuelto. Ahora el programa no imprime por defecto en el PC el contenido de la EEPROM, pero
Ahora la interrupción no salta en ningún momento. Ya que estoy enviando la letra "H" al pic, pero este ni se inmuta, entonces en ningún momento vuelca la información de la EEPROM en el PC,

Gracias de neuvo
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 06 de Noviembre de 2008, 10:16:47
Perdón he contestado sin leer lo posterior,... me lo miro y le informo un saludo!
Título: Re: problema interrupcion rda.
Publicado por: RedPic en 06 de Noviembre de 2008, 11:11:56
Ahgggggg Ay, que me dá un soponcio ... ja, ja, ja  :D :D :D

El ver trozo de tu código te juro que hasta duele ... ja, ja, ja  :D :D :D

Esta forma de habilitar las interrupciones es la primera vez que la veo y te aseguro que si lo ven Brian W. Kernighan y Dennis M. Ritchie (los creadores del C) les dá también un soponcio, pero no te preocupes que todo tiene arreglo en esta vida (menos eso que ni nombramos, por si acaso)  :P
Código: C#
  1. do{
  2.  
  3.     enable_interrupts(global);
  4.     enable_interrupts(int_rda);
  5.  
  6.    }while(TRUE);

Venga, vamos a ir ordenando las cosas poco a poco y verás como al final todo sale perfecto.  :mrgreen:

Si todo tu programa se ejecuta en dos partes:

una únicamente una vez al resetear el PIC que es todo el trozo dentro del main() antes de do{}While(TRUE);

y otra solo cuando se recibe cierto carácter por la USART

entonces deberíamos tener una estructura de este tipo:

Código: C#
  1. // FUSES DEFINES e INCLUDES
  2.  
  3. // VARIABLES GLOBALES
  4. Char rec;
  5.  
  6. // INTERRUPCION
  7. #int_rda
  8. void rda_handler(void){
  9.   if(Kbhit()){
  10.     rec=getc();
  11.   }
  12. }
  13.  
  14. // MAIN
  15. void main(void){
  16.  
  17.   // TODO LO NECESARIO PARA PONER EN MARCHA EL PIC o TU PROGRAMA
  18.  
  19.  
  20.   // HABILITO INTERRUPCIONES
  21.   enable_interrupts(int_rda);
  22.   enable_interrupts(global);
  23.   // BUCLE INFINITO
  24.   do{
  25.  
  26.     // DETECTO NECESIDAD DE HACER ALGO Y LO HAGO
  27.     if(rec=='H'){
  28.       rec='\0'; // Para no volver a entrar has recibir un nuevo 'H'
  29.  
  30.        // AQUI HAGO TODO LO QUE ANTES HACÍA DENTRO DE LA INTERRUPCIÓN
  31.  
  32.     }
  33.  
  34.   }while(TRUE);
  35.  
  36. }

¿Me he explicado medio bien?  o ...  :mrgreen:

Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 06 de Noviembre de 2008, 11:56:17
Hola.

Pongo mi cuota aprendida en el manejo del RS485  :mrgreen: (Gracias a RedPic y Nocturno)

Cuando simule el sistema en el proteus (con el codigo aqui posteado inicialmente) aparecio el siguiente warning
Logic contentions detected on net #00029 (el mismo que me aparecio en mi caso y que evidencio la falla en el RX - MASTER, pero en mi caso debido al mal manejo en la impedancia de los transmisores de los modulos PIC SLAVE)

Siguiendo mas a fondo el warn, me lleva a la linea de Rx del microcontrolador y encuentro la siguiente informacion:
Two or more outputs of the same strength attempt to drive the net into opposing logic state

(http://img233.imageshack.us/img233/3693/falla485an0.png)

Es decir, al inicializar la rutina del serial (#use rs232) con el pin de habilitacion, existe un conflicto entre el estado logico inicial del Virtual COM y el Rx del PIC, lo que hace que no funcione correctamente, ademas en la compilacion del programa en C aparece el warning : Interrupts disabled during call to prevent re-entrancy:  (@PUTCHAR_BIU_1)

Al quitar la parte de enable=pin_c5 los warning en proteus y de compilacion desaparecen y el sistema opera tal como deberia, respondiendo a la interrupcion.

Si vas a usar RS485, te recomiendo que no uses el pin de habilitacion del CCS y generes tu mismo las funciones de habilitacion de Rx y Tx, no es complicado hacerlo.

Saludos
Título: Re: problema interrupcion rda.
Publicado por: RedPic en 06 de Noviembre de 2008, 12:12:40
En otro hilo, creo que era tuyo MLO, también digo lo mismo.

En RS485 no uso los enable's automáticos del CCS sino que yo mismo habilito la transmisión o recepción del mismo.

Código: C++
  1. void main(void){
  2.  
  3.   // Por defecto siempre estoy a la escucha
  4.   output_low(TX_485_ENABLE);
  5.  
  6.   // Bucle Infinito
  7.   While(True){
  8.  
  9.     if(Tengo_Algo_Que_Decir){
  10.       // Habilito la transmisión ...
  11.       output_high(TX_485_ENABLE);
  12.       // ... lo digo
  13.       printf("Hello World");
  14.       // ... y Deshabilito la transmisión volviendo a su estado "natural"
  15.       output_low(TX_485_ENABLE);
  16.     }
  17.  
  18.   }
  19.  
  20. }
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 06 de Noviembre de 2008, 12:18:02
Te has explicado a la perfección RedPic ya he modificado el programa tal y como me ahs dicho y tengo 0 erores y 0 warnings. Muchas gracias por la ayuda, he ido a Teoría y praxis de las com serie TTL : 3.- Comandos de un solo carácter
como me has dicho y he estado mirando, he querido probar el primer programilla super sencillo

Código: [Seleccionar]
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <16f877.h>
///////////////////////////////////////////////////////////////////////////////////////////////////
// Fuses y ajuste de Clock
///////////////////////////////////////////////////////////////////////////////////////////////////
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT
#use delay(clock=20000000)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Canal de Comunicación : usart
///////////////////////////////////////////////////////////////////////////////////////////////////
#define TTL_TX PIN_C6
#define TTL_RX PIN_C7
#use rs232(baud=9600, xmit=TTL_TX, rcv=TTL_RX)
void main() {
  char rec;
  printf("TyP_Serie_TTL\r\n");   // Al inicio escribe para ver que emite correctamente
  do{                            // Bucle ...
     if(kbhit()){                //  Si hay algo pendiente de recibir ....
        rec=getc();              //  recibe el caracter ...
        putc(rec);               //  ... y lo escribes ...
     }                           // ... después continúa ...
  }while(TRUE);                  // ... hasta el infinito.
}

y me compila bien, pero sin embargo no imprime nada en el ordenador ni si quiera  "TyP_Serie_TTL\r\n"

después cambié #use rs232(baud=9600, xmit=TTL_TX, rcv=TTL_RX) por
#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7)  sigue sin funcionar
y finalmente cambie esto por #use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5)

y sigue sin funcionar. No me imprime nada en la pantaya, ¿quizás es porque uso el rs485?

Pero sin embargo cuando cargo un programa que envia datos si que los envia, no entiendo el motivo por el cual en el programa este tan sencillo no evnia ningún dato.

Creo que el hardware está correctamente conectado.

Gracias!!!


ACABO DE LEER LO DE HABILITAR MANUALMENTE EL PROGRAMA SIN EL ENABLE PIN, ES DECIR EL PIN 5 QUE TENGO VA DIRECTAMENTE AL MAX485 (PINES 2 Y 3 PUENTEADOS), ESTO CREAun conflicto entre el pic.


Ahora hablando de el programilla sencillo que he comentado anteriormente según lo entiendo me decis que lo mas correcto sea utilizar
Código: [Seleccionar]
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <16f877.h>
///////////////////////////////////////////////////////////////////////////////////////////////////
// Fuses y ajuste de Clock
///////////////////////////////////////////////////////////////////////////////////////////////////
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT
#use delay(clock=20000000)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Canal de Comunicación : usart
///////////////////////////////////////////////////////////////////////////////////////////////////
#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7)
void main() {
  char rec;
  printf("TyP_Serie_TTL\r\n");   // Al inicio escribe para ver que emite correctamente
  do{                            // Bucle ...
     if(kbhit()){                //  Si hay algo pendiente de recibir ....
        rec=getc();              //  recibe el caracter ...
        putc(rec);               //  ... y lo escribes ...
     }                           // ... después continúa ...
  }while(TRUE);                  // ... hasta el infinito.
}
Creo que tiene que haber algo más porque utilizando este codigo no funciona.

Puede ser que tenga que modificar algo mas al utilizar el protocolo rs485?


Muchisimas gracias amigos.. estoy aprendiendo muchisimo, siento causaros molestias.

Un saludo enorme!
Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 06 de Noviembre de 2008, 13:51:48
Hola.

Lo que se me ocurre que puede estar ocurriendo es que el baud rate de la PC no coincide con el del PIC ( revisa la configuracion del soft con el que accedes al COM del PC ) o que el MAX232 que estas usando puede estar un poco danando, es decir que el problema es de Hard, ya que en las simulaciones corre perfectamente.

En mi caso, para que el PIC pudiera recibir bytes del PC, tengo que puentear el pin 1 con el pin 6 del conector DB9.

Saludos
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 07 de Noviembre de 2008, 10:27:00
Hola buenas, el archivo adjunto muestra la conexión física que tengo puesta,
Probando este código:
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <16f877.h>
///////////////////////////////////////////////////////////////////////////////////////////////////
// Fuses y ajuste de Clock
///////////////////////////////////////////////////////////////////////////////////////////////////
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT
#use delay(clock=20000000)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Canal de Comunicación : usart
///////////////////////////////////////////////////////////////////////////////////////////////////
//#define TTL_TX PIN_C6
//#define TTL_RX PIN_C7
//#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7) //enable=PIN_C5 hace que el C maneje el pin de habilitación
#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5,errors) //enable=PIN_C5 hace que el C maneje el pin de habilitación
void main() {
  char rec;
  output_high(PIN_C66);
  output_LOW(PIN_C7);
  printf("TyP_Serie_TTL\r\n");   // Al inicio escribe para ver que emite correctamente
  output_high(PIN_C7);
  output_LOW(PIN_C6);
  do{                            // Bucle ...
     if(kbhit()){                //  Si hay algo pendiente de recibir ....
        rec=getc();              //  recibe el caracter ...
         output_high(PIN_C6);
         output_LOW(PIN_C7);
        putc(rec);               //  ... y lo escribes ...
     }                           // ... después continúa ...
  }while(TRUE);                  // ... hasta el infinito.
}

El pic no envia nada.

Utilizando este código:
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <16f877.h>
///////////////////////////////////////////////////////////////////////////////////////////////////
// Fuses y ajuste de Clock
///////////////////////////////////////////////////////////////////////////////////////////////////
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT
#use delay(clock=20000000)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Canal de Comunicación : usart
///////////////////////////////////////////////////////////////////////////////////////////////////
//#define TTL_TX PIN_C6
//#define TTL_RX PIN_C7
//#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7) //enable=PIN_C5 hace que el C maneje el pin de habilitación
#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5,errors) //enable=PIN_C5 hace que el C maneje el pin de habilitación
void main() {
  char rec;
  output_high(PIN_C5);

  printf("TyP_Serie_TTL\r\n");   // Al inicio escribe para ver que emite correctamente

  output_LOW(PIN_C5);
  do{                            // Bucle ...
     if(kbhit()){                //  Si hay algo pendiente de recibir ....
        rec=getc();              //  recibe el caracter ...
         output_high(PIN_C5);
       
        putc(rec);               //  ... y lo escribes ...
     }                           // ... después continúa ...
  }while(TRUE);                  // ... hasta el infinito.
}
El PIC envia "TyP_Serie_TTL\r\n"  pero no ahce caso a la interrupción.

¿Creeis que algo tengo mal? o como bien dices MLO_  seguramente l hardware esta dañado. Hoy iré a pedir un nuevo MAX485 para ver si realmente es eso, aunque tengo mis dudas.

Un saludo y gracias a todos!!!
Título: Re: problema interrupcion rda.
Publicado por: RedPic en 07 de Noviembre de 2008, 11:46:45
Parafraseando a los Les Luthiers y su "voiglo entrare per la finestra" solo puedo decir "Temo, tiemblo, tanto". ja, ja, ja  :D :D :D

1º.- ¿Que cristal tienes? Por que en tus últimos ejemplos veo con temor que usas el fuse XT mientras que el use_delay sigue siendo de 20000000 cuando XT solo es válido para cristales de hasta 4000000, siendo el fuse HS el necesario para los cristales mayores a ese valor.  :shock:

2º.- Subes y bajas en main() los pines de TX y RX con lo que los TRIS los dejas locos ya que automáticamente el CCS ambos pines como SALIDA (no hay nada declarado en contra de este automatismo del CCS).  :shock:

3º.- En el primer ejemplo dices "el pin no envia nada" pero ¿recibe?  :shock:

4º.- En el segundo ejemplo veo que levantas o bajas "a mano" el PIN_C5 pero te has dejado en el use_rs232 el enable=PIN_C5 con lo cual sois dos manejando el mismo pin. A saber quien de los dos, tú o el CCS es el que tiene el control de dicho pin.  :shock:

5º.- Al final de tu segundo ejemplo dices que "El PIC envia "TyP_Serie_TTL\r\n"  pero no ahce caso a la interrupción" ¿Qué interrupción? Ni en ese ejemplo ni en el primero se declara, se escribe o se habilita interrupción alguna. Imagino que querras decir que "no recibe".  :shock:

6º.- En el segundo ejemplo veo que pones en alto PIN_C5 y después usas el printf para "hablar" por el RS485 y justo después lo bajas para "oir" el RS485. Inmediatamente después entras en el bucle infinito donde checas si has recibido algo y en tal caso vuelves a levantar PIN_C5 para "hablar" y usar el putc(). Pero ¿donde bajas PIN_C5 de nuevo para seguir "oyendo"?  :shock:

Por último te propongo este programa, lo copias, lo compilas sin tocar una coma y nos dices que tal te ha ido. A ver si vamos desbrozando el terreno y llegamos a alguna conclusión  :mrgreen::

Código: C#
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. #include <16f877.h>
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. // Fuses y ajuste de Clock
  5. ///////////////////////////////////////////////////////////////////////////////////////////////////
  6. #fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT
  7. #use delay(clock=20000000) // Verificar que el cristal es de 20 Mhz
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. // Canal de Comunicación : usart
  10. ///////////////////////////////////////////////////////////////////////////////////////////////////
  11.  
  12. #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
  13.  
  14.  
  15. void main() {
  16.  
  17.   char rec;
  18.  
  19.   delay_ms(1000) // esperamos
  20.  
  21.    set_tris_c(0b10000000); // Configuramos bien pines TX y RX
  22.  
  23.   output_high(PIN_C5); // Habilito transmisión
  24.   printf("TyP_Serie_TTL\r\n");   // Al inicio escribe para ver que emite correctamente
  25.   output_low(PIN_C5);  // Habilito recepción
  26.  
  27.   do{                            // Bucle ...
  28.     if(kbhit()){                //  Si hay algo pendiente de recibir ....
  29.       rec=getc();              //  recibe el carácter ...
  30.       output_high(PIN_C5); // Habilito transmisión
  31.       putc(rec);               //  ... y lo escribes ...
  32.       output_low(PIN_C5);  // Habilito recepción
  33.     }                           // ... después continúa ...
  34.   }while(TRUE);                  // ... hasta el infinito.
  35. }
 
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 10 de Noviembre de 2008, 09:54:13
Buenas, Tal y como djiste he compilado tu programa, pero sigue sin devolver ningún carácter,
he probado en poner un printf dentro de if(kbhit()){  y si que entra en la interrupción pero sin embargo no lo envia al PC.
Estoy esperando un max485 para descartar el error en el hardware, todavía no ha llegado. Por lo que el software creo que este último programa no tiene ningún error, a no ser que en el bucle al cambiarse todo el rato el pin de habilitación c5 el pic se colapse y por eso no envie.

Código: [Seleccionar]
      ///////////////////////////////////////////////////////////////////////////////////////////////////

      #include <16f877.h>

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

      // Fuses y ajuste de Clock

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

      #fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT

      #use delay(clock=20000000) // Verificar que el cristal es de 20 Mhz

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

      // Canal de Comunicación : usart

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

      #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
 
      void main() {

       char rec;

       delay_ms(1000); // esperamos

       set_tris_c(0b10000000); // Configuramos bien pines TX y RX

       output_high(PIN_C5); // Habilito transmisión

       printf("TyP_Serie_TTL\r\n");   // Al inicio escribe para ver que emite correctamente
     
       output_low(PIN_C5);  // Habilito recepción

       do{                            // Bucle ...

         if(kbhit()){                //  Si hay algo pendiente de recibir ....

           rec=getc();              //  recibe el carácter ...

           output_high(PIN_C5); // Habilito transmisión
         //printf("FUNIONA\r\n");
           putc(rec);               //  ... y lo escribes ...

           output_low(PIN_C5);  // Habilito recepción

         }                           // ... después continúa ...

       }while(TRUE);                  // ... hasta el infinito.

      }

Un saludo!
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 10 de Noviembre de 2008, 10:35:28
perdón no en la interrupción sino en el while
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 13 de Noviembre de 2008, 08:39:26
Buenas a todos,

He probado su codigo RedPic, y me envia la frase "TyP_Serie_TTL\r\n", pero sigo teniendo el problema aquí
do{                            // Bucle ...

         if(kbhit()){                //  Si hay algo pendiente de recibir ....

           rec=getc();              //  recibe el carácter ...

           output_high(PIN_C5); // Habilito transmisión
         //printf("FUNIONA\r\n");
           putc(rec);               //  ... y lo escribes ...

           output_low(PIN_C5);  // Habilito recepción

         }                           // ... después continúa ...

       }while(TRUE);                  // ... hasta el infinito.

      }


y es que por algun motivo no le llega ningún adto al pic para poder devolverlo. He cambiado el MAX485 por uno de nuevo y sigue haciendo lo mismo.  Sabe alguien cual puede ser el error?

gracias un saludo
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 13 de Noviembre de 2008, 10:02:04
No se si esta información os  puede dar algún dato por donde puede estar el error, pero en el max en las patillas de recerepción de datos y de enviar datos estan a nivel alto simultaneamente(patillas 1 y 4). Las patillas 2 y 3 que son de habilitacion están a nivel bajo.

Las patilla de habilitación del pic queda a un nivel bajo, y las patillas de enviar datos del pic c6 y c7 están a nivel alto.
Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 13 de Noviembre de 2008, 11:38:44
Hola.

Hiciste el puente entre los pines del conector DB9  como te dije anteriormente?

Otra cosa: Las conexiones entre PIC y PC deben ser las siguientes:

PIC -> MAX485 ---------------------- MAX485 -> MAX232 -> PC

Saludos.
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 13 de Noviembre de 2008, 11:46:38
Bueno yo esque mi hardware es el siguiente:

pic-> rs 485 y rs485->usb  PC

y lo curioso es que cuando envio desde el PC al PIC, los cables balanceados los miro con el osciloscopio y le llegan datos pero sin embargo el PIC no recibe nada. Y el Max485 no esta roto.
Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 13 de Noviembre de 2008, 11:57:56
Hola.

Ya, ya, Lo haces por USB. Ok.

Me imagino que en el PC estas usando CDC. Revisa las velocidades de transmision, que coincidan con las del PIC.

Saludos
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 13 de Noviembre de 2008, 13:30:47
¿a que te refieres cuando dices si uso CDC?   Configuración de Dispositivos Conectados, si bueno en el ccs pongo a la velocidad que transmito.
Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 13 de Noviembre de 2008, 20:56:24
Hola.

Me refiero a la clase de comunicacion. Hay varios tipos: HID, CDC, MSD. Me imagino que es CDC la tuya. Si es de esa manera aparece en el PC un COM virtual, en el cual hay que configurar la velocidad de transmision, el numero de bits, la paridad y esas cosas, es decir todo lo que configuras en el #use rs232 debe configurarse en el COM virtual del PC.

Saludos
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 13 de Noviembre de 2008, 21:29:57
Ahhh.... si si todo eso esta configurado de la misma forma.... en el PC se ha creado un puerto serie virtual llamado COM4, ese puerto tiene las mismas caracteristicas que las que configuro en el ccs, el problema es que el pc si que recibe datos del pic pero el pic del pc no. Y no hay motivo aparente, o por lo menos yo no lo encuentro
Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 13 de Noviembre de 2008, 23:08:38
Hola.


Ok.

Como estas controlando el pin de habilitacion del max485 que esta conectado al conversor USB_485?.
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 14 de Noviembre de 2008, 08:49:30
lo controlo con el pin C5....... la conexion fisica esta en la foto
Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 14 de Noviembre de 2008, 16:29:14
Hola.

Creo que deberian ir dos integrados MAX485. Uno solo no es suficiente ya que son dos dispositivos los que estas comunicando, uno es el PIC y otro el PC, por eso me referia a que con que estas controlando el pin de habilitacion del MAX485 que va del lado del PC, ya que el que esta del lado del micro es obvio que lo controlas con el micro.

Saludos
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 14 de Noviembre de 2008, 23:30:11
entonces k tendria k poner dos max485?¿
 y d k forma los conecto? nadie ha hecho una comunicacion nunca con un pic y un pc mediante 485?
Título: Re: problema interrupcion rda.
Publicado por: RedPic en 14 de Noviembre de 2008, 23:35:43
ja, ja, ja, ja  :D :D :D :D

El RS485, un Relé en la lejanía: Hardware y Software (http://www.todopic.com.ar/foros/index.php?topic=19057.0)


Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 14 de Noviembre de 2008, 23:53:43
 :shock:

Control para un malacate - RS485 (http://www.todopic.com.ar/foros/index.php?topic=23175.0)



Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 15 de Noviembre de 2008, 08:40:32
entonces tan solo se tiene que usar un max485..... es asi como tengo montado el circuito..... k la salida del pic se conecta con el max y de este le salen 2 hilos que los pongo en un rj-11 y de aqui lo paso al conversor rs485-usb
Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 15 de Noviembre de 2008, 16:17:44
Hola.

Como estas controlando el pin de habilitacion de Tx o Rx en el modulo RS485-USB??

Saludos
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 17 de Noviembre de 2008, 09:37:34
buenas, peudo interrumpir de otra forma el PIC, ya qu tan solo necesito un caracter para que salte la interrupción y asi el programa pueda enviar los datos al pc, podria puentear alguno de los 2 cables con algun pin del pic y hacer que saltase una interrupción y asi poder enviar los datos?
Título: Re: problema interrupcion rda.
Publicado por: MLO__ en 17 de Noviembre de 2008, 10:24:53
Hola.

Insisto en que tu problema esta en el hard y no en el soft. Con el programa que te dio RedPic es mas que suficiente para que el PIC capture los datos. Si dices que solo envia y no recibe es porque el pin de habilitacion de un MAX esta cambiando pero el del PC no cambia nunca de estado y solo se queda en recepcion.

Saludos
Título: Re: problema interrupcion rda.
Publicado por: RedPic en 17 de Noviembre de 2008, 10:52:36
Hola.

Insisto en que tu problema esta en el hard y no en el soft. Con el programa que te dio RedPic es mas que suficiente para que el PIC capture los datos. Si dices que solo envia y no recibe es porque el pin de habilitacion de un MAX esta cambiando pero el del PC no cambia nunca de estado y solo se queda en recepcion.

Saludos

Total, completa y absolutamente de acuerdo comtigo MLO. Es el PC el que no "conmuta" de modo recepción-transmisión o viceversa, o al menos eso es lo que creo mas probable.

Yo en la parte PC utilizo un ATEN IC-485SN y lo tengo que configurar con DCE y Tx-RTS Rx ON para que funcione correctamente, o sea que al igual que el PIC siempre esté a la escucha salvo cuando "habla" que conmuta a transmisión e inmediatamente después vuelve al modo de "escuchar".

(http://www.indalosecurity.com/DocTecnico/09_Conversor_RS232_a_RS485_ATEN_IC485SN_archivos/image002.jpg)
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 17 de Noviembre de 2008, 11:24:47
El hardware si que envia porque miro con el osciloscopio en los 2 cables y me salen los datos a la entradas de las patillas A y B del MAX, pero sin embargo al pic no le llegan, y el max esta en buen estado ya que es nuevo.

EN el hardware me salen estas opciones a configurar.
Título: Re: problema interrupcion rda.
Publicado por: cheapekt en 17 de Noviembre de 2008, 11:25:37
Aquí la otra foto
Título: Re: problema interrupcion rda.
Publicado por: zagoaristides en 09 de Abril de 2009, 18:23:59
Bueno creo que llegué al hilo indicado para que me ayuden. Después de renegar 4 o 5 días, me doy por vencido. Ya ni la prueba y error me funciona y tampoco la interrupción ni su madre.

Posteo adjuntos los archivos de 2 simulaciones, una con una librería que anda por el foro (http://www.todopic.com.ar/foros/index.php?topic=21300.0) y otro con la que trae CCS RS485.c

Ninguna anda, le di mil vueltas, prueba y recontraprueba pero nada. Así que tal vez sea una pavada que no veo, pero...NO LA VEO!.

Abrazo y gracias.

Título: Re:problema interrupcion rda.
Publicado por: dermandad@hotmail.com en 31 de Octubre de 2016, 22:12:16
Hola, tuve el mismo problema y era porque no tenia conectado el cable de RX del PIC al TX de mi convertidor. Estuve revisando los registros RCSTA el cual indica si hay errores de comunicación