Autor Tema: Comunicación serial PIC 18F4550  (Leído 5994 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado abel135

  • PIC10
  • *
  • Mensajes: 42
Comunicación serial PIC 18F4550
« en: 19 de Noviembre de 2013, 12:06:09 »
Buenos días;

Tengo problemas para la comunicación serial con un pic 18F4550, no hay manera de recibir comunicación, (sin comunicación serial si que funciona perfectamente), alguien me puede apoyar y pasarme un programa sencillo para probar la comunicación serial con este pic? Algo fácil como por ejemplo que yo le envíe una a y me devuelva el número 1.

Nada más para ver como se comunica para luego desarrollar más el programa. Ya que no he tenido suerte. Uso un cristal de cuarzo de 4 MHz.

Muchas gracias amigos!

Saludos cordiales

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Comunicación serial PIC 18F4550
« Respuesta #1 en: 19 de Noviembre de 2013, 13:24:59 »
  Sería mejor que tú nos muestres tu código incluyendo los bits de configuración. También un esquema de tu conexionado. Y por supuesto informarnos con que compilador estás trabajando.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado abel135

  • PIC10
  • *
  • Mensajes: 42
Re: Comunicación serial PIC 18F4550
« Respuesta #2 en: 19 de Noviembre de 2013, 16:58:32 »
Muy buenas tardes;

Estoy usando el PIC C Compiler para programar.

El código es el siguiente, es un poco lioso, por eso digo que si tenéis un programa sencillo para probarlo sería suficiente.

Muchas gracias.  :-/ :-) ((:-)) ;-) :g) :mrgreen: :P :lol: 8) :shock: :o :oops: :)

El micro funciona bien, lo único que no funciona es la comunicación serial.

Código:

#include <18F4550.h>//////////////////////////////////Empiezan las declaraciones
#include <kbd_lib.c>
#use delay(clock=4000000)
#use standard_io(b)

#bit Verde1=0X07.0
#bit Rojo1=0X07.1
#bit Verde2=0X07.2
#bit Rojo2=0X07.3
#bit Arribapluma1=0X07.4
#bit Abajopluma1=0X07.5
#bit Tx=0X07.6
#bit Rx=0x07.7


#bit D0=0XF83.0 // LAZO 1
#bit D1=0XF83.1 // SENSOR1
#bit D2=0XF83.2 // SENSOR2
#bit D3=0XF83.3 // SENSOR3
#bit D4=0XF83.4 // LAZO 2
#bit Arribapluma2=0XF83.5
#bit Abajopluma2=0XF83.6
#bit Parpadeo=0XF83.7

#byte port_a=0XF80
#byte port_b=0XF81 // Este te dice que el nombre port_b es la dirección, así escribiendo port_b ya accedes a el.
#byte port_c=0XF82
#byte port_d=0XF83 // Declaración port d como antes.
#byte port_e=0XF84

#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)// Comunicacion serial|

#byte tris_a=0XF92 // Te dice las direcciones del tris a, b, c y d, para configuarar como entradas y salidas.
#byte tris_b=0XF93
#byte tris_c=0XF94
#byte tris_d=0XF95

char estado_sensores='0';//La combinación de los sensores activos nos da un caracter el cual se usa como identificación, con la z nos devuelve el codigo.
char Comando=' '; //Es la tecla pulsada en concreto, depende de la tecla pulsada enviará información o activara otra cosa.
char BanderaS1='0';
char BanderaS11='0';
char BanderaS2='0';
char BanderaS22='0';
char BanderaS3='0';
char BanderaS33='0';
char BanderaL1='0';
char BanderaL2='0';
char Sensor1='0';
char Sensor2='0';
char Sensor3='0';
char Lazo1='0';
char Lazo2='0';
char Contador_eje1char='0';
char Contador_eje3char='0';
char po=' ';

int Contador_eje1=0;
int Contador_eje3=0;
int Est_act1=0;
int Est_ant1=0;
int Est_act2=0;
int Est_ant2=0;
int salir=0;
//int pluma_abierta1=0;
//int semaforo_verde=1;

//////////////////////////////////////////////////////////////Fin declaraciones

#int_rda ////////////////////////////////////////////// Empieza interrupción rda

void serial_isr() {

    comando=0X00;
    if(kbhit()){//////////////Cuando recibe un caracter empieza la interrupción.

    Comando=getc();/////////El caracter ecrito se guarda en la variable comando.
    switch(Comando){

      case 'z'://///Si comando es 'z' envia por RS232 el estado de los sensores.
     
      puts("");
      putc(estado_sensores);
      putc(';');

      break;

      case 'a':    //Si comando es 'a' envia por RS232 el estado de las banderas
                   //+ el número de ejes que han pasado por el sensor 1 y 3.
     
      puts("");
      putc(Lazo1);
      putc(po);
      putc(Lazo2);
      putc(po);
      putc(Sensor1);
      putc(po);
      putc(Sensor2);
      putc(po);
      putc(Sensor3);
      putc(po);
      putc(BanderaL1);
      putc(po);
      putc(BanderaL2);
      putc(po);
      putc(BanderaS1);
      putc(po);
      putc(BanderaS2);
      putc(po);
      putc(BanderaS3);
      putc(po);
      putc(Contador_eje1char);
      putc(po);
      putc(Contador_eje3char);
      putc(';');

      break;

      case 'b':////////////// Si comando es 'b' enciende el semaforo "verde".
      verde1=1;
      break;

      case 'c':///////////////// Si comando es 'c' apaga el semaforo "verde".
      verde1=0;
      break;

      case 'd'://///////////// Si comando es 'd' enciende el semaforo "rojo".
      rojo1=1;
      break;

      case 'e':////////////////// Si comando es 'e' apaga el semaforo "rojo".
      rojo1=0;
      break;

      case 'f':////////////// Si comando es 'f' Sube pluma1.
      verde2=1;
      break;

      case 'g':///////////////// Si comando es 'g' Baja pluma1.
      verde2=0;
      break;
     
      case 'h':////////////// Si comando es 'h' Sube pluma2.
      rojo2=1;
      break;

      case 'i':///////////////// Si comando es 'i' Baja pluma2.
      rojo2=0;
      break;

      case 'j'://////////////// Si comando es 'j' pone a 0 la bandera Sensor1 1.
      BanderaL1='0';
      break;

      case 'k':///////////////// Si comando es 'k' pone a 0 la bandera Sensor 2.
      BanderaL2='0';
      break;

      case 'l':///////////////// Si comando es 'l' pone a 0 la bandera Sensor 3.
      BanderaS1='0';
      break;
     
      case 'm':///////////////// Si comando es 'l' pone a 0 la bandera Sensor 3.
      BanderaS2='0';
      break;

      case 'n':///////////////// Si comando es 'l' pone a 0 la bandera Sensor 3.
      BanderaS3='0';
      break;
     
      case 'o':///////////////// Si comando es 'm' pone a 0 el contador de eje1.
      Contador_eje1char='0';
      Contador_eje1=0;
      break;

      case 'p':///////////////// Si comando es 'n' pone a 0 el contador de eje3.
      Contador_eje3char='0';
      Contador_eje3=0;
      break;

      case 'q':///////// Si comando es 'o' pone el semaforo rojo en inter-
               ///////// mitente, retardos de medio segundo para salir pulsar 'p'.

         while(salir==0){
           
            verde1=0;
            verde2=0;
            rojo1=0;
            rojo2=0;
            delay_ms(500);        //Espero 500ms.
            rojo1=1;
            rojo2=1;
            delay_ms(500);        //Espero 500ms.
            if(kbhit()){
            Comando=getchar();
            if(comando=='r'){salir=1;}// Para salir del estado pulsar 'p'
            }
           
            }
         rojo1=0;
         rojo2=0;
         salir=0;
      break;
     
      case 's':////////Este comando permite un reset desde el software.
     
      RESET_CPU();
     
      case 't'://////////////// Si comando es 'j' pone a 0 la bandera Sensor1 1.
      Arribapluma1=1;
      break;

      case 'u':///////////////// Si comando es 'k' pone a 0 la bandera Sensor 2.
      Arribapluma1=0;
      break;
     
      case 'v'://////////////// Si comando es 'j' pone a 0 la bandera Sensor1 1.
      Abajopluma1=1;
      break;

      case 'w':///////////////// Si comando es 'k' pone a 0 la bandera Sensor 2.
      Abajopluma1=0;
      break;

      case 'x'://////////////// Si comando es 'j' pone a 0 la bandera Sensor1 1.
      Arribapluma2=1;
      break;

      case 'y':///////////////// Si comando es 'k' pone a 0 la bandera Sensor 2.
      Arribapluma2=0;
      break;
     
      case '1'://////////////// Si comando es 'j' pone a 0 la bandera Sensor1 1.
      Abajopluma2=1;
      break;

      case '2':///////////////// Si comando es 'k' pone a 0 la bandera Sensor 2.
      Abajopluma2=0;
      break;
     
   }
   }
}
/////////////////////////////////////////////////////// Termina interrupción rda

void main(){ //////////////////////////////////////// Empieza programa principal

tris_a=0XFF;//Declaramos los puertos como entrada o salida, 0 salida, 1 entrada.
tris_b=0XF0;
tris_c=0X80;
tris_d=0X1F;

port_a=0X00;
port_b=0X00;
port_c=0X00;
port_d=0X00;
port_e=0X00;

char mitecla=0;
kbd_init();

printf("HELLOOOOOOOOOOOOOO");
printf("\r\n\Eperando ordenes (Int)\r\n");

//////Empieza bucle do para saber como están sensores y cuantos ejes han pasado.

   do{
     
      //LED indicador que funciona el PIC
      Parpadeo=1;
     
      //Para el teclado///////////////////////////////////////////////////////
      mitecla=kbd_getc();
     
      if(mitecla!=0){
         putc(mitecla);
         putc(';');
      }
      ////////////////////////////////////////////////////////////////////////
   
      // Empieza a contar los ejes, siempre que pase de no detectar a detectar,
      // al contrario no cuenta el eje Para borrar el conteo pulsar m y n. Tam-
      // bién actualiza las banderas. Una bandera se activa si ya a pasado al-
      // menos una vez por el eje correspondiente, para borrarlas exisen los co-
      // mandos 'j','k' y 'l'. Si el camión se pasa de 9 ejes sale una 'e' de
      // error.
     
   Est_ant1=Est_act1;
   Est_act1=input(PIN_D1);


      if(input(PIN_D1)&&(Est_ant1!=Est_act1)){

      BanderaS1='1';
      BanderaS11='1';
      Contador_eje1=Contador_eje1+1;


         if(Contador_eje1==0){

            Contador_eje1char='0';

         }

         else if(Contador_eje1==1){

            Contador_eje1char='1';

         }

         else if(Contador_eje1==2){

            Contador_eje1char='2';

         }
         else if(Contador_eje1==3){

            Contador_eje1char='3';

         }
         else if(Contador_eje1==4){

            Contador_eje1char='4';

         }
         else if(Contador_eje1==5){

            Contador_eje1char='5';

         }
         else if(Contador_eje1==6){

            Contador_eje1char='6';

         }
         else if(Contador_eje1==7){

            Contador_eje1char='7';

         }
         else if(Contador_eje1==8){

            Contador_eje1char='8';

         }
         else if(Contador_eje1==9){

            Contador_eje1char='9';

         }
         else if(Contador_eje1>9){
         
            Contador_eje1char='e';
         
         }


      }
     
      if(input(PIN_D2)){

      BanderaS2='1';
      BanderaS22='1';

      }

      Est_ant2=Est_act2;
      Est_act2=input(PIN_D3);

      if(input(PIN_D3)&&(Est_ant2!=Est_act2)){

      BanderaS3='1';
      BanderaS33='1';
      Contador_eje3=Contador_eje3+1;


         if (Contador_eje3==0){

            Contador_eje3char='0';

         }

         else if(Contador_eje3==1){

            Contador_eje3char='1';

         }

         else if(Contador_eje3==2){

            Contador_eje3char='2';

         }
         else if(Contador_eje3==3){

            Contador_eje3char='3';

         }
         else if(Contador_eje3==4){

            Contador_eje3char='4';

         }
         else if(Contador_eje3==5){

            Contador_eje3char='5';

         }
         else if(Contador_eje3==6){

            Contador_eje3char='6';

         }
         else if(Contador_eje3==7){

            Contador_eje3char='7';

         }
         else if(Contador_eje3==8){

            Contador_eje3char='8';

         }
         else if(Contador_eje3==9){

            Contador_eje3char='9';

         }
         
         else if(Contador_eje3>9){
         
            Contador_eje3char='e';
         
         }

      }
     
      if(input(PIN_D0)){

      Lazo1='1';
      BanderaL1='1';

      }
     
      if(input(PIN_D1)){
     
      Sensor1='1';
           
      }
     
      if(input(PIN_D2)){
     
      Sensor2='1';
     
      }
     
      if(input(PIN_D3)){
     
      Sensor3='1';
     
      }
     
      if(input(PIN_D4)){

      Lazo2='1';
      BanderaL2='1';

      }
     
      if(!input(PIN_D0)){
     
      Lazo1='0';
     
      }
     
      if(!input(PIN_D1)){
     
      Sensor1='0';
     
      }
     
      if(!input(PIN_D2)){
     
      Sensor2='0';
     
      }
     
      if(!input(PIN_D3)){
     
      Sensor3='0';
     
      }
     
      if(!input(PIN_D4)){
     
      Lazo2='0';
     
      }
/////Fin del programa de contar ejes.
/////Empieza la modificación de la variable estado_sensores según estado lasers.

      if(!input(PIN_D1)&&!input(PIN_D2)&&!input(PIN_D3)){

         estado_sensores='0';

      }
      else if(input(PIN_D1)&&!input(PIN_D2)&&!input(PIN_D3)){

         estado_sensores='1';

      }
      else if(!input(PIN_D1)&&input(PIN_D2)&&!input(PIN_D3)){

         estado_sensores='2';

      }

      else if(input(PIN_D1)&&input(PIN_D2)&&!input(PIN_D3)){

         estado_sensores='3';

      }

      else if(!input(PIN_D1)&&!input(PIN_D2)&&input(PIN_D3)){

         estado_sensores='4';

      }

      else if(input(PIN_D1)&&!input(PIN_D2)&&input(PIN_D3)){

         estado_sensores='5';

      }

      else if(!input(PIN_D1)&&input(PIN_D2)&&input(PIN_D3)){

         estado_sensores='6';

      }

      else if(input(PIN_D1)&&input(PIN_D2)&&input(PIN_D3)){

         estado_sensores='7';

      }
     
     
     
enable_interrupts(GLOBAL);//habilito interrupción global
enable_interrupts(int_rda); //habilito interrupción interna
   }

while(true);

}//////////////////////////////////////////////////////////////Termina bucle do.
/////////////////////////////////////////////////////Termina programa principal.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Comunicación serial PIC 18F4550
« Respuesta #3 en: 19 de Noviembre de 2013, 18:04:43 »
  Mas allá de utilizar la sentencia "use delay" también debes configurar los fuses del PIC ya que no necesariamente el núcleo del PIC trabajará a los 4 MHz del cristal.

  Además de ello, para la utilización del puerto serie en CCS creo que debes utilizar la sentencia "use rs232" o "use uart". Consúltalo en el manual del compilador.

  Te recomiendo tener a mano el datasheet del PIC utilizado, para poder ver todas sus prestaciones.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado tecnicosj

  • PIC10
  • *
  • Mensajes: 1
Re: Comunicación serial PIC 18F4550
« Respuesta #4 en: 03 de Diciembre de 2013, 19:05:00 »
hola...no deberías usar una función como printf o putc dentro de la rutina de interrupción. Deberías colocar una bandera y "atenderla dentro del programa principal...prueba con eso...suerte! :-/

Desconectado sparta13

  • PIC10
  • *
  • Mensajes: 7
Re: Comunicación serial PIC 18F4550
« Respuesta #5 en: 21 de Febrero de 2014, 22:16:21 »
wau abel135, yo comienzo con los micro controladores y he tenido un problema...al igual utilizo el PIC18f4550, primeramente lo que tengo que realizar es la comunicación puerto serial con cadenas como es esto, que al introducir por el teclado no se "ledon" encienda un led en el pic y si es "ledoff" se apague he intentado muchas formas y no se me parece que esta podría ser un comienzo espero puedan ayudarme:
#include <18f4550.h>
#include <string.h>                                                           
#FUSES INTHS,MCLR,PUT,NOBROWNOUT, CPUDIV1, PLL1                                 
                                                                               
#use delay(INTERNAL=4MHZ)                                                       
#use rs232 (BAUD=9600 , XMIT=PIN_c6 , RCV=PIN_c7, bits=8, parity=N, STOP=1)
#use standard_io(a)

void main ()
{
 int resultado;
 char string
 char string2

for (;;)
{
 gets (string);
 strcpy (string,"ledon");
 resultado=strcmp(string,string2);
 
 if (resultado==1)
 {
 output_high(PIN_A0);
 }
 if (resultado==0)
 {
 output_low(PIN_A0);
        }
     }
}