Autor Tema: Consulta de comunicacion usart entre dos pic - Envio de valor  (Leído 137 veces)

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

Desconectado Sebas1010

  • PIC10
  • *
  • Mensajes: 5
Consulta de comunicacion usart entre dos pic - Envio de valor
« en: 13 de Mayo de 2019, 15:34:27 »
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ódigo: [Seleccionar]


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 */


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7167
Re:Consulta de comunicacion usart entre dos pic - Envio de valor
« Respuesta #1 en: 13 de Mayo de 2019, 18:32:26 »
Si queres enviar un entero ( imagino que de 0 a 255) y que ocupa 1 byte (al menos el numero 16)... ¿Por que lo convertis en string?, deberias enviarlo asi nomas y listo.

Sino despues tenes el trabajo de pasar el string a numero de nuevo (y mas si es que lo pensas usar en otra cosa). Es aca donde tenes el problema....

Vos pasas el 16 a "16" es decir visto en hexadecimal, pasas de 0x10 a 0x31 0x36 0x00, donde 0x31 es el ASCII para '1', 0x36 el ASCII para '6', y el 0x00 no se ve... El hyperterminal lo vas a ver bien, si podes verlo en hexadecimal vas a notar lo que te digo.

Lo que te ocupaba 1 byte, paso ahora a ocupar 3 bytes. Vos recibis tu primer dato el 0x31, ahora 0x31 en decimal es 49 y 0x36 es 54 y tratas de mostrar todo tu numero con una parte.

-----------------------------------------------------------------------------------------------

Otra de las cosas que tengas mal es que no hay demoras al enviar el dato, en si esto NO ESTA MAL, pero asi como tenes un transmisor tenes un receptor, y el receptor deberia ser capaz de aceptar todos esos datos, es por esto que generalmente cuando tenes una comunicacion, lo mejor es hacerlo por interrupcion a la recepcion..

Si vos al PIC le envias 2 o mas datos y no lo sacas, tenes que reiniciar el modulo USART, porque eso quiere decir que se perdieron datos, se activa un flag de OVERRUN, y hasta que no lo deshabilites y habilites no vuelve a recibir ( cambiar lo que tiene el RXREG ) Por esto te digo que tengas en cuenta lo del tiempo. Con las interrupciones esto se simplifica bastante.
-------------------------------------------------------------------------------------------

En fin.... ¿queres solucionar tu problema?

- Al loop del transmisor ponele una demora, que envie cada 100ms por ejemplo, asi le das tiempo al receptor para mostrar en el LCD que es un proceso "lento" hasta que le tomes la mano a la interrupcion
- En el transmisor no uses sprintf, simplemente envia tu int, recordando que va desde 0 a 255, al menos para empezar, usa Usart_sent_character(b); y listo
- El receptor estaria bien.

Desconectado Sebas1010

  • PIC10
  • *
  • Mensajes: 5
Re:Consulta de comunicacion usart entre dos pic - Envio de valor
« Respuesta #2 en: 13 de Mayo de 2019, 22:57:18 »
Muchas gracias por la ayuda, realicé lo que  me dijiste, logro ver el valor 16 en el display, pero el primer número que es 1 va cambiando por 0. Por otro lado después voy a leer el tema de las interrupciones.


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7167
Re:Consulta de comunicacion usart entre dos pic - Envio de valor
« Respuesta #3 en: 13 de Mayo de 2019, 23:03:34 »
Citar
pero el primer número que es 1 va cambiando por 0.

No deberia pasar eso, mas cuando vos envias el numero 16 siempre.

Desconectado Sebas1010

  • PIC10
  • *
  • Mensajes: 5
Re:Consulta de comunicacion usart entre dos pic - Envio de valor
« Respuesta #4 en: 14 de Mayo de 2019, 12:11:02 »
Subo la simulacion para que se pueda ver.

Desconectado Sebas1010

  • PIC10
  • *
  • Mensajes: 5
Re:Consulta de comunicacion usart entre dos pic - Envio de valor
« Respuesta #5 en: 16 de Mayo de 2019, 09:04:40 »
Bueno en la libreria de Usart es donde tenia conflicto. Gracias por tada la ayuda que me diste.
Esta es la funcion original, por otro lado la idea original es mandar varios datos por ejemplo varios sensores, ahora viene la parte donde voy a ver como envio eso datos y mostrarlo en el lcd. Si tienen un idea de como hacerlo les agradeceré.

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);
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7167
Re:Consulta de comunicacion usart entre dos pic - Envio de valor
« Respuesta #6 en: 16 de Mayo de 2019, 14:58:10 »
Citar
Esta es la funcion original, por otro lado la idea original es mandar varios datos por ejemplo varios sensores, ahora viene la parte donde voy a ver como envio eso datos y mostrarlo en el lcd. Si tienen un idea de como hacerlo les agradeceré.

Si es fija la cantidad de datos a enviar, envia siempre la misma cantidad de datos. El receptor que espere esa cantidad.
Si es variable, el primer byte que sea la cantidad enviada. Y que el primer byte determine cuanto va a esperar el receptor.
Si queres asegurarte podes poner ademas alguna dato inicial para indicar donde comienza, recorda que esto implica que en tus datos no vas a poder usar ese dato.

Desconectado remi04

  • PIC16
  • ***
  • Mensajes: 188
Re:Consulta de comunicacion usart entre dos pic - Envio de valor
« Respuesta #7 en: 16 de Mayo de 2019, 17:42:43 »
Yo cuando envío tramas de datos por usart me gusta siempre fijar un ratio, normalmente uso 100 ms de ratio. Significa que cada 100 ms envío una trama. Esa trama se compone de una cabecera que al menos tiene 5 bytes, por ejemplo “0x80 0x8f 0xe0 0x11 0xfe”.   Es como una palabra clave o comando de cabecera.  El receptor siempre esperará a recibir esa cabecera completa y entonces empieza a recibir ahora todos los bytes relevantes.  Luego el emisor calcula un checksum con todos los datos relevantes, lo envía el último de todo. Finalmente envío un 0x0D 0x0A (Endline)  indicando el fin de la trama.

    Luego el receptor una vez que recibe y válida la cabecera, carga todos los datos en un array, comprueba el checksum y rechaza la trama si no es válido.

  Aquí entra en juego tu imaginación, las necesidades que tengas, el nivel de seguridad que le quieras poner a los datos , etc......



 

anything