Comunicación serial entre 2 micros PIC

Hola !

Estoy haciendo un driver para un motor a pasos unipolar. Uso 2 micros, uno emulando al PLC (ahi le dices que velocidad quieres, tipo, direccion y cantidad de pasos. El otro recibe los datos y hace la secuencia de giro del motor.
Tengo el problema de que... no pasa nada. El primer micro funciona perfecto, envia los datos bien y muestra todo en la pantalla LCD. Estoy seguro de que el error esta en la llegada de los datos al segundo micro. Lo sé porque puse un if con para el valor que envio, y PORTB deberia cambiar de estado pero no lo hace. Sé que si cambia entre bucles while, porque ya habia puesto un 'PORTB=0xXX' entre ellos y lo hacia.
No se como hacerlo correctamente, ya que he intentado muchas formas distintas.

La cantidad de pasos la envio al primer micro mediante serial con la computadora.

RA1 de ambos micros están unidos y van a un push.

Uso dos PIC18f4550 y compilador mikroc. Adjunto los códigos.

CODIGO TRANSMISOR (uC 1)
Código:
while(1)
{
i=0;

        Lcd_Cmd(_LCD_CLEAR);
        Lcd_Out(1,1,"Driver Stepper");
        Delay_ms(3000);
        Lcd_Cmd(_LCD_CLEAR);

        while((PORTA.RA1)==0)                        //Velocidad
        {
                if((PORTE.RE0)==1)
                {vel++; Delay_ms(500); Lcd_Cmd(_LCD_CLEAR);}
                if((PORTE.RE1)==1)
                {vel--; Delay_ms(500); Lcd_Cmd(_LCD_CLEAR);}

                memset(Vel1, \'\\0\', 10);
                sprintf(Vel1,"%d",vel);
                strcpy(Vel2,Vel1);

                Lcd_Out(1,4,"Velocidad:");
                Lcd_Out(2,5,Vel2);
                Lcd_Out(2,7," p/seg");
        }
        UART1_Write(vel);
        Delay_ms(500);
        Lcd_Cmd(_LCD_CLEAR);
        //UART1_Write(0xFF);

        while((PORTA.RA1)==0)                        //Direccion
        {
                if((PORTE.RE2)==1)
                {
                switch(dir)
                {
                case 1: dir=0; break;
                case 0: dir=1; break;
                }
                Delay_ms(500);
                Lcd_Cmd(_LCD_CLEAR);
                }
                sprintf(Dir1,"%d",dir);
                memset(Dir2, \'\\0\', 10);

                if(dir==1){strcpy(Dir2,"Reloj");}
                if(dir==0){strcpy(Dir2,"Contra");}

                Lcd_Out(1,4,"Direccion:");
                Lcd_Out(2,5,Dir2);
        }
        UART1_Write(dir);
        Delay_ms(500);
        Lcd_Cmd(_LCD_CLEAR);
        //UART1_Write(0xFF);

        while((PORTA.RA1)==0)                        //Tipo de paso
        {
                if((PORTA.RA2)==1)
                {
                tipo+=1;
                if(tipo>3){tipo=1;}
                memset(T,\'\\0\',10);
                sprintf(T,"%d",tipo);
                strcpy(Tipo1,T);
                              switch(tipo)
                              {
                              case 1: strcpy(NMW,"Normal");break;
                              case 2: strcpy(NMW,"Medio");break;
                              case 3: strcpy(NMW,"Wave");break;
                              }
                Delay_ms(500);
                Lcd_Cmd(_LCD_CLEAR);
                }
                Lcd_Out(1,1," Tipo de paso:  ");
                Lcd_Out(2,5,NMW);
        }
        UART1_Write(tipo);
        Delay_ms(500);
        Lcd_Cmd(_LCD_CLEAR);
        //UART1_Write(0xFF);

        while((PORTA.RA1)==0)                        //Cantidad de pasos
        {
                if (UART1_Data_Ready())                         // If data is received,
                {
                   UART1_Read_Text(&uart_rd, "OK", 255);    // reads text until \'OK\' is found
                   strcpy(tum,&uart_rd);
                   paaso=atoi(tum);
                   Lcd_Cmd(_LCD_CLEAR);
                }

                Lcd_Out(1,1,"     Pasos:     ");
                Lcd_Out(2,7,tum);
        }
        UART1_Write(paaso);
        Delay_ms(500);
        Lcd_Cmd(_LCD_CLEAR);
        //UART1_Write(0xFF);

        while((PORTA.RA1)==0)
        {
                Lcd_Out(1,1,"Al finalizar");
                Lcd_Out(2,1,"Presiona RA1");
        }
  }


CODIGO RECEPTOR (uC 2)
Código:
while(1)
{
Delay_ms(500);

while((PORTA.RA1)==0)                         //Recibe Velocidad
        {
              if (UART1_Data_Ready())                      // If data is received,
              {
              recibe=UART1_Read();  // reads UART
              vel=recibe;
              }
        }
        recibe=0;
        Delay_ms(500);
        if(vel==2){PORTB=0x90;}
        
while((PORTA.RA1)==0)                         //Recibe direccion
        {
              if (UART1_Data_Ready())                      // If data is received,
              {
              recibe=UART1_Read();  // reads UART
              dir=recibe;
              }
        }
        recibe=0;
        Delay_ms(500);
        if(dir==1){PORTB=0x60;}
        
while((PORTA.RA1)==0)                                 //Recibe tipo de paso
        {
              if (UART1_Data_Ready())                      // If data is received,
              {
              recibe=UART1_Read();  // reads UART
              T=recibe;
              }
        }
        recibe=0;
        Delay_ms(500);
        if(T==3){PORTB=0x30;}

while((PORTA.RA1)==0)                                //Recibe pasos
        {
              if (UART1_Data_Ready())                      // If data is received,
              {
              recibe=UART1_Read();  // reads UART
              pasos=recibe;
              }
        }
        recibe=0;
        flg2=0;
        Delay_ms(500);
        if(pasos==40){PORTB=0x90;}
...
 
Última edición:
es que no debes poner retardos
es decir atoras el micro todos unos 500ms es decir medio segundo desperdiciado

entonces cuando recivas el dato pues ¿cuando lo recibira pues se atora?

yo diria que quitaras esos delays

y si pudireas poner el uart por interrupcion es decir cuando llegue un dato que interrumpa el micro lo prosece y continue con lo que estaba haciendo
 
Gracias por responder

Puse los retardos por el rebote del push, y porque si se dejara presionado mucho tiempo, saltaria los otros while debido a que uso el mismo push para salir de cada uno. Hay otra forma de evitar eso?

En cuanto a las interrupciones, nunca las he usado. Investigare un poco para aplicarlas y ver como me va.
 
Aparte de enviar los datos completos en una cadena específica para que los proceses todos juntos y además, la variable "recibe" en tú código es innecesaria, en lugar de enviar a recibe y borrarlo a cada momento mejor transfiere directamente a tus variables (vel, dir, T y paso)
 
Me refiero a que envíes los datos uno tras el otro, así evitas esa espera enorme e innecesaria, si lo haces por interrupciones usas un contador y esperas los bytes necesarios que mandan la información, ya cuando recibes todos los procesas juntos en lugar para que las instrucciones se ejecuten rápidamente en lugar de tardar se 1,5s en recibir los 3 datos.
 
Buenas tardes, les hago un consulta porque ya hace varios dias que estoy con este problema y no puedo solucionar, realizo la comunicacion serial entre los pic y envio un valor entero para luego mostrarlo en el otro pic con un display, el dato que yo quiero que se muestre en el otro pic no muestra el mismo valor, pero si en el hyperterminal, en este punto no me estoy dando cuenta del error o el mal uso de sprint por ejemplo, les dejo los codigos y una captura de proteus, desde ya muchas gracias por ayuda.
Pic utilizados: 16f883
Compilardor: Mplab xc8

C:
TX
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#define _XTAL_FREQ 20000000
#include "Usart.h"


void main(void)
{
int b = 16;
char q[20];

/*Inicializacion de comunicacion USART*/ 
Usart_int();

    do
    {
    sprintf(q,"%d",b);
    Usart_sent_string(q);
    
    }while(1);   
}
#ifndef USART_H
#define    USART_H
 
void Usart_int();//función para iniciar el USART PIC asíncron, 8 bits, 9600 baudios
unsigned char Usart_read();//función para la recepción de caracteres
void Usart_sent_character(unsigned char);//función para la transmisión de caracteres
void Usart_sent_string(char*);//función para la transmisión de cadenas de caracteres
 
/*
Inicialización del módulo USART PIC modo asíncrono
en una función, a 8bits,a 9600 baudios */
void Usart_int(){
     TRISCbits.TRISC7=1;//pin RX como una entrada digital
     TRISCbits.TRISC6=0;//pin TX como una salida digital
     TXSTAbits.CSRC = 0;//modo asincronico
     TXSTAbits.TX9 = 0;//selecion modo de transimicion 8bit.
     TXSTAbits.TXEN = 1;//se habilita la transimcion
     TXSTAbits.SYNC = 0;//la transmicion sera asincronica
     TXSTAbits.SENDB = 0;//no habilito el control por hardware
     TXSTAbits.BRGH = 1;//modo de transmicion de alta velocidad
     TXSTAbits.TRMT = 1;//se lo pondrá a 1 porque se está iniciando y tendría que estar vacío.
     TXSTAbits.TX9D = 0;//el bit de paridad en la transmisión a 8 bits no influye y se lo pondrá a 0.
     RCSTAbits.SPEN = 1;//se pondrá a 1 para habilitar el uso del módulo USART PIC.
     RCSTAbits.RX9 = 0;//la recepción para que sea a 8 bits.
     RCSTAbits.SREN = 0;//modo asincronico
     RCSTAbits.CREN = 1;//se habilita la recepcion
     RCSTAbits.ADDEN = 0;//recepción será a 8 bit.
     RCSTAbits.FERR = 0;//este bit trabaja automáticamente cuando se pone a 1 indica que se ha recibido un dato no válido.
     RCSTAbits.OERR = 0;//este bit trabaja automáticamente cuando se pone a 1 indica que se ha producido un error por sobreescritura de algún dato recibido
     RCSTAbits.RX9D = 0;////el bit de paridad en la transmisión a 8 bits no influye y se lo pondrá a 0.
     SPBRG = 129;//para una velocidad de 2400baudios con un oscilador de 20Mhz*/
} 
 
/*
Recepción de datos del módulo USART PIC modo asíncrono
*/
unsigned char Usart_read()
{
    if(PIR1bits.RCIF==1)//si el bit5 del registro PIR1 se ha puesto a 1
    {
    return RCREG;//devuelve el dato almacenado en el registro RCREG
    }
}
 
/*
Transmisión de datos del módulo USART PIC modo asíncrono
*/
void Usart_sent_character(unsigned char chtr)
{
    while(TXSTAbits.TRMT==0);// mientras el registro TSR esté lleno espera
    TXREG = chtr;//cuando el el registro TSR está vacio se envia el caracter
}
 
 
/*
Transmisión de cadenas de caracteres con el módulo USART PIC modo asíncrono
*/
void Usart_sent_string(char* cadena)//cadena de caracteres de tipo char
{
    while(*cadena !=0x00)//mientras el último valor de la cadena sea diferente de el caracter nulo
    {                   
    Usart_sent_character(*cadena);//transmite los caracteres de cadena
    cadena++;//incrementa la ubicación de los caracteres en cadena para enviar el siguiente caracter de cadena
    }
}     
#endif    /* USART_H */

RX

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#define _XTAL_FREQ 20000000
#include "Lcd_20x4.h"
#include "Usart.h"



void main(void)
{
ANSELH = 0x00; 
unsigned char dato;
char q[20];

/*Inicializacion de comunicacion USART*/ 
Usart_int();

/*Inicializacion del LCD*/
Lcd_int();

do
{
dato = Usart_read();

sprintf(q,"Resultado:%d",dato);
Lcd_gotoxy(1,1);
Lcd_printf(q);
}while(1);
      
}
#ifndef LCD20x4
#define    LCD20x4
        
#define PIN_RS    PORTBbits.RB0
#define TRISBRS   TRISBbits.TRISB0

#define PIN_EN    PORTBbits.RB1
#define TRISBEN   TRISBbits.TRISB1

#define LCD_D4    PORTBbits.RB4
#define LCD_D4_T  TRISBbits.TRISB4

#define LCD_D5    PORTBbits.RB5
#define LCD_D5_T  TRISBbits.TRISB5

#define LCD_D6    PORTBbits.RB6
#define LCD_D6_T  TRISBbits.TRISB6

#define LCD_D7    PORTBbits.RB7
#define LCD_D7_T  TRISBbits.TRISB7
 
/*Declaracion de funciones*/

void Lcd_int();
void Lcd_control_cmd(char);
void Lcd_port(char);
void Lcd_write_data_port(char);
void Lcd_printf(char*);
void Lcd_clear();
void Lcd_printf_String(char*);
void Lcd_gotoxy(char , char);

/*Funciones*/

void Lcd_int() //configuracion para inicializar el LCD
{
    PIN_RS = 0;
    PIN_EN = 0;
    TRISBRS = 0;
    TRISBEN = 0;
    LCD_D4 = 0; 
    LCD_D4_T = 0;

    LCD_D5 = 0; 
    LCD_D5_T = 0;

    LCD_D6 = 0;   
    LCD_D6_T = 0;

    LCD_D7 = 0;
    LCD_D7_T = 0;
  
    
    Lcd_port(0x00);
    __delay_ms(20);
    Lcd_control_cmd(0x03);
    __delay_ms(5);
    Lcd_control_cmd(0x03);
    __delay_ms(11);
    Lcd_control_cmd(0x03);
 
    Lcd_control_cmd(0x02);
    Lcd_control_cmd(0x02);
    Lcd_control_cmd(0x08);
    Lcd_control_cmd(0x00);
    Lcd_control_cmd(0x0C);
    Lcd_control_cmd(0x00);
    Lcd_control_cmd(0x06);
    
}

void Lcd_control_cmd(char data) //pines de control para LCD
{
  PIN_RS = 0;             
  Lcd_port(data);
  PIN_EN  = 1;             
  __delay_ms(4);
  PIN_EN  = 0;     
}

void Lcd_port(char data) //
{
    if(data & 1)
    {   
        LCD_D4 = 1;
    }   
    else
    {   
        LCD_D4 = 0;
    }   

    if(data & 2)
    {   
        LCD_D5 = 1;
    }   
    else
    {   
        LCD_D5 = 0;
    }   
    if(data & 4)
    {   
        LCD_D6 = 1;
    }   
    else
    {   
        LCD_D6 = 0;
    }
    if(data & 8)
    {   
        LCD_D7 = 1;
    }   
    else
    {   
        LCD_D7 = 0;
    }   
}


void Lcd_write_data_port(char data)//Modo de 4 bits LCD
{
    char var;
    char y;
   var = (data & 0x0F);
   y = (data & 0xF0);
   PIN_RS = 1;             
   Lcd_port(y>>4);           
   PIN_EN = 1;
   __delay_us(40);
   PIN_EN = 0;
   Lcd_port(var);
   PIN_EN = 1;
   __delay_us(40);
   PIN_EN = 0;
  
}

void Lcd_printf(char *data)//Funcion para imprir lo que queremos ver en el LCD
{
    while (*data) // Mientras no sea Null
    {
        Lcd_write_data_port(*data); // Envio el dato al LCD
        data++; // Incrementa el buffer de dato
    }
}
void Lcd_gotoxy(char x, char y)//Funcion de la posicion de posicion en el LCD
{
    char temp;
    char dato1;
    char dato2;
    if(y == 1)
    {
      temp = 0x80 + x - 1;
        dato1 = temp >> 4;
        dato2 = temp & 0x0F;
        Lcd_control_cmd(dato1);
        Lcd_control_cmd(dato2);
    }
     if(y == 2)
    {
        temp = 0xC0 + x - 1;
        dato1 = temp >> 4;
        dato2 = temp & 0x0F;
        Lcd_control_cmd(dato1);
        Lcd_control_cmd(dato2);
    }
    if(y == 3)
    {
        temp = 0x94 + x - 1;
        dato1 = temp >> 4;
        dato2 = temp & 0x0F;
        Lcd_control_cmd(dato1);
        Lcd_control_cmd(dato2);
    }
    if(y == 4)
    {
        temp = 0xD4 + x - 1;
        dato1 = temp >> 4;
        dato2 = temp & 0x0F;
        Lcd_control_cmd(dato1);
        Lcd_control_cmd(dato2);
    }
}
        

void Lcd_clear()//Funcion para limpiar pantalla
{
    Lcd_control_cmd(0);
    Lcd_control_cmd(1);
}
    
 void Lcd_printf_String(char *data)//Funcion imprime string
{
    int i;
    for(i=0;data[i]!='\0';i++)
      Lcd_write_data_port(data[i]);
}
 
 /*
 * Guardar caracteres especiales. en la CGRAM
 */
void lcd_put_caracter(char adress, char caracter[]) {
    int i;
    Lcd_control_cmd(0x40 + (adress * 8));
    for (i = 0; i < 8; i++) {
        Lcd_write_data_port(caracter[i]);
    }
}

void Lcd_Shift_Right()
{
    Lcd_control_cmd(0);
    Lcd_control_cmd(1);   
    Lcd_control_cmd(0x0C);
}

void Lcd_Shift_Left()
{
    Lcd_control_cmd(0);
    Lcd_control_cmd(1);
    Lcd_control_cmd(0x08);
}

#endif   
#ifndef USART_H
#define    USART_H
 
void Usart_int();//función para iniciar el USART PIC asíncron, 8 bits, 9600 baudios
unsigned char Usart_read();//función para la recepción de caracteres
void Usart_sent_character(unsigned char);//función para la transmisión de caracteres
void Usart_sent_string(char*);//función para la transmisión de cadenas de caracteres
 
/*
Inicialización del módulo USART PIC modo asíncrono
en una función, a 8bits,a 9600 baudios */
void Usart_int(){
     TRISCbits.TRISC7=1;//pin RX como una entrada digital
     TRISCbits.TRISC6=0;//pin TX como una salida digital
     TXSTAbits.CSRC = 0;//modo asincronico
     TXSTAbits.TX9 = 0;//selecion modo de transimicion 8bit.
     TXSTAbits.TXEN = 1;//se habilita la transimcion
     TXSTAbits.SYNC = 0;//la transmicion sera asincronica
     TXSTAbits.SENDB = 0;//no habilito el control por hardware
     TXSTAbits.BRGH = 1;//modo de transmicion de alta velocidad
     TXSTAbits.TRMT = 1;//se lo pondrá a 1 porque se está iniciando y tendría que estar vacío.
     TXSTAbits.TX9D = 0;//el bit de paridad en la transmisión a 8 bits no influye y se lo pondrá a 0.
     RCSTAbits.SPEN = 1;//se pondrá a 1 para habilitar el uso del módulo USART PIC.
     RCSTAbits.RX9 = 0;//la recepción para que sea a 8 bits.
     RCSTAbits.SREN = 0;//modo asincronico
     RCSTAbits.CREN = 1;//se habilita la recepcion
     RCSTAbits.ADDEN = 0;//recepción será a 8 bit.
     RCSTAbits.FERR = 0;//este bit trabaja automáticamente cuando se pone a 1 indica que se ha recibido un dato no válido.
     RCSTAbits.OERR = 0;//este bit trabaja automáticamente cuando se pone a 1 indica que se ha producido un error por sobreescritura de algún dato recibido
     RCSTAbits.RX9D = 0;////el bit de paridad en la transmisión a 8 bits no influye y se lo pondrá a 0.
     SPBRG = 129;//para una velocidad de 2400baudios con un oscilador de 20Mhz*/
} 
 
/*
Recepción de datos del módulo USART PIC modo asíncrono
*/
unsigned char Usart_read()
{
    if(PIR1bits.RCIF==1)//si el bit5 del registro PIR1 se ha puesto a 1
    {
    return RCREG;//devuelve el dato almacenado en el registro RCREG
    }
}
 
/*
Transmisión de datos del módulo USART PIC modo asíncrono
*/
void Usart_sent_character(unsigned char chtr)
{
    while(TXSTAbits.TRMT==0);// mientras el registro TSR esté lleno espera
    TXREG = chtr;//cuando el el registro TSR está vacio se envia el caracter
}
 
 
/*
Transmisión de cadenas de caracteres con el módulo USART PIC modo asíncrono
*/
void Usart_sent_string(char* cadena)//cadena de caracteres de tipo char
{
    while(*cadena !=0x00)//mientras el último valor de la cadena sea diferente de el caracter nulo
    {                   
    Usart_sent_character(*cadena);//transmite los caracteres de cadena
    cadena++;//incrementa la ubicación de los caracteres en cadena para enviar el siguiente caracter de cadena
    }
}     
#endif    /* USART_H */
Proteus.jpg
 
Sería mejor que subas el proyecto dentro de un archivo comprimido. (Incluyendo la simulación)
Pegar los códigos juntos no es conveniente, tal vez por ahí se perdió el archivo "Usart.h" :unsure:
 
Buenas tardes, ahi relice una modificaciones en la parte donde envio el dato, hacia algo innecesario, el problema que tengo ahora es que mando el un dato entero que en este caso es el numero 16 pero en el display me lo va cambiando por el numero 0 el primer valor.
Adjunto los archivos y la simulacion.
 

Adjuntos

  • comunicacion.rar
    238.1 KB · Visitas: 8
El problema está en la librería para la pantalla.
Puede ser que estén mal los tiempos o algo mal en alguna subrutina, ya que a la rutina "void Lcd_printf(char *data)" sí le llegan los datos correctos, pero finaliza colocando un cero al número con formato.
En modo de depuración se puede comprobar que el número 16 sí llega a escribirse, pero al salir es cuando coloca el cero.

Snap3.jpg

Habrá que revisar las rutinas de la librería Lcd_20x4.h para encontrar qué produce el problema.
 
Gracias por la ayuda mañana con mas tiempo voy a revisar bien la librería, realicé una prueba rapida solo utilice el pic del Rx declare un variable con un entero(no utilce nada de las funciones de usart), y en este caso el numero me lo muestra sin clavar el cero.
 
Pues sí, de hecho el problema surge cuando el dato es procesado constantemente.
Adjunto el mismo tipo de programa pero con PIC C Compiler de CCS
Funciona sin problemas y se escriben pocas líneas de código.
Aparte, el funcionamiento está basado en la interrupción por recepción USART.
 

Adjuntos

  • 16F883 USART.rar
    32.9 KB · Visitas: 4
Bueno en la lubreria de Usart tenia el conflicto. Gracias por tada la ayuda que me diste.
Esta es la funcion original
Recepción de datos del módulo USART PIC modo asíncrono
*/
unsigned char Usart_read()
{
if(PIR1bits.RCIF==1)//si el bit5 del registro PIR1 se ha puesto a 1
{
return RCREG;//devuelve el dato almacenado en el registro RCREG
}
}

La funcion corregida

/*Recepción de datos del módulo USART PIC modo asíncrono*/
unsigned char Usart_read()
{
if(PIR1bits.RCIF==1)//si el bit5 del registro PIR1 se ha puesto a 1
{
RCREG;// dato almacenado en el registro RCREG
}
return(RCREG);
}
 
Te realizo una nueva consulta, no se me ocurre el caso que quiero por ejemplo mandar 3 datos(seguimos con enteros) y que pueda mostrar en el lcd cada dato en una linea nueva del lcd.
 
Podría ser con un búfer circular y guardas en un arreglo.
Como yo programo con PIC C Compiler uso la instrucción gets(array) que me devuelve todos los bytes recibidos en un arreglo.
 
Buenas tardes, estuve ausente por falta de tiempo en el trabajo, me podrias(si se puede) dar un ejemplo que haces en PIC C Compiler lo de un búfer circular, para poder adaparlo con lo mio.
Gracias
 
De hacerlo en PIC C sería como hacerlo en XC8, la ventaja es que en PIC C se usa gets(Array); y carga toda la cadena en un arreglo.
Básicamente se hace un bucle incrementando una variable hasta x número que conforme a su valor se irán guardando los datos en su respectivo vector, o hasta que se encuentre cierto carácter comodín, que no es muy conveniente porque si se manda un dato que lo contenga se puede salir del bucle sin cargar todos los datos.
Por algún lado del Foro subí un programa que usa un búfer circular pero no me acuerdo dónde quedó y en mi PC tampoco. :rolleyes:
 
Atrás
Arriba