Autor Tema: Pic16f628a USART problema para recibir  (Leído 6494 veces)

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

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Pic16f628a USART problema para recibir
« en: 04 de Julio de 2015, 14:44:14 »
Hola a todos , hace un tiempo ya que estoy lidiando con un pic 16 f y su UART , funciona perfectamente transmitiendo datos , pero a la hora de recibir , solo recibo basura ...simule en proteus y lo mismo , no se si es la libreria o me falta configurar algo , creo que no ...les paso el codigo a ver si me pueden dar una mano por favor programo en XC8 MPLABX version 3.0

les paso el programa casi completo completo   ... ...cuando le envio datos recibo basura ...

Muchisimas gracias a todos



Fuses

Código: [Seleccionar]
// PIC16F628A Configuration Bit Settings

// 'C' source line config statements

#include <xc.h>

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

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = ON     // Brown-out Detect Enable bit (BOD disabled)
#pragma config LVP = ON       // Low-Voltage Programming Enable bit (RB4/PGM pin has PGM function, low-voltage programming enabled)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)



libreria

Código: [Seleccionar]
Serial communication library for PIC16F series MCUs.

 Compiler: Microchip XC8 v1.12 (http://www.microchip.com/xc)

 Version: 1.0 (21 July 2013)

 MCU: PIC16F877A
 Frequency: 4MHz

                                     NOTICE

NO PART OF THIS WORK CAN BE COPIED, DISTRIBUTED OR PUBLISHED WITHOUT A
WRITTEN PERMISSION FROM EXTREME ELECTRONICS INDIA. THE LIBRARY, NOR ANY PART
OF IT CAN BE USED IN COMMERCIAL APPLICATIONS. IT IS INTENDED TO BE USED FOR
HOBBY, LEARNING AND EDUCATIONAL PURPOSE ONLY. IF YOU WANT TO USE THEM IN
COMMERCIAL APPLICATION PLEASE WRITE TO THE AUTHOR.


WRITTEN BY:
AVINASH GUPTA
me@avinashgupta.com

*******************************************************************************/
#include <stdint.h>
#include <xc.h>

#include "usart_pic16.h"

void USARTInit(uint16_t baud_rate)
{
    //Setup queue
    UQFront=UQEnd=-1;
        
    //SPBRG
    switch(baud_rate)
    {
     case 9600:
        SPBRG=25; //datasheets pagina 76 pic16f628
        break;
     case 19200:
        SPBRG=12;
        break;
     case 28800:
        SPBRG=42;
        break;
     case 33600:
        SPBRG=36;
        break;
    }
    //TXSTA
    TXSTAbits.CSRC=1;
    TXSTAbits.TX9=0;  //8 bit ttsransmission
    TXSTAbits.TXEN=1; //Transmit enable
    TXSTAbits.SYNC=0; //Async mode
    TXSTAbits.BRGH=1; //High speed baud rate

    //RCSTA
    RCSTAbits.SPEN=1;   //Serial port enabled
    RCSTAbits.RX9=0;    //8 bit mode
    RCSTAbits.CREN=1;   //Enable receive
    RCSTAbits.ADDEN=0;  //Disable address detection

    //Receive interrupt
    RCIE=1;
    PEIE=1;

    ei();
}

void USARTWriteChar(char ch)
{
  while(!PIR1bits.TXIF);

  TXREG=ch;
}

void USARTWriteString(const char *str)
{
  while(*str!='\0')
  {
      USARTWriteChar(*str);
      str++;
  }
}

void USARTWriteLine(const char *str)
{
    USARTWriteChar('\r');//CR
    USARTWriteChar('\n');//LF

    USARTWriteString(str);
}

void USARTHandleRxInt()
{
  if(RB1==1)
    RB1=0;
  else
    RB1=1;
  
    //Read the data
    char data=RCREG;

    //Now add it to q
    if(((UQEnd==RECEIVE_BUFF_SIZE-1) && UQFront==0) || ((UQEnd+1)==UQFront))
    {
        //Q Full
UQFront++;
if(UQFront==RECEIVE_BUFF_SIZE) UQFront=0;
    }

    if(UQEnd==RECEIVE_BUFF_SIZE-1)
        UQEnd=0;
    else
UQEnd++;

    URBuff[UQEnd]=data;

    if(UQFront==-1) UQFront=0;
    
}

char USARTReadData()
{
    char data;

    //Check if q is empty
    if(UQFront==-1)
return 0;

    data=URBuff[UQFront];

    if(UQFront==UQEnd)
    {
        //If single data is left
//So empty q
UQFront=UQEnd=-1;
    }
    else
    {
UQFront++;

if(UQFront==RECEIVE_BUFF_SIZE)
            UQFront=0;
    }

    return data;
}

uint8_t USARTDataAvailable()
{
    if(UQFront==-1) return 0;
    if(UQFront<UQEnd)
return(UQEnd-UQFront+1);
    else if(UQFront>UQEnd)
return (RECEIVE_BUFF_SIZE-UQFront+UQEnd+1);
    else
return 1;
}

void USARTWriteInt(int16_t val, int8_t field_length)
{
    char str[5]={0,0,0,0,0};
    int8_t i=4,j=0;

    //Handle negative integers
    if(val<0)
    {
        USARTWriteChar('-');   //Write Negative sign
        val=val*-1;     //convert to positive
    }
    else
    {
        USARTWriteChar(' ');
    }

    if(val==0 && field_length<1)
    {
        USARTWriteChar('0');
        return;
    }
    while(val)
    {
        str[i]=val%10;
        val=val/10;
        i--;
    }

    if(field_length==-1)
        while(str[j]==0) j++;
    else
        j=5-field_length;


    for(i=j;i<5;i++)
    {
        USARTWriteChar('0'+str[i]);
    }
}

void USARTGotoNewLine()
{
    USARTWriteChar('\r');//CR
    USARTWriteChar('\n');//LF
}

void USARTReadBuffer(char *buff,uint16_t len)
{
uint16_t i;
for(i=0;i<len;i++)
{
buff[i]=USARTReadData();
}
}
void USARTFlushBuffer()
{
while(USARTDataAvailable()>0)
{
USARTReadData();
}
}

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

 Serial communication library for PIC16F series MCUs.

 Compiler: Microchip XC8 v1.12 (http://www.microchip.com/xc)

 MCU: PIC16F877A
 Frequency: 4MHz

                                     NOTICE

NO PART OF THIS WORK CAN BE COPIED, DISTRIBUTED OR PUBLISHED WITHOUT A
WRITTEN PERMISSION FROM EXTREME ELECTRONICS INDIA. THE LIBRARY, NOR ANY PART
OF IT CAN BE USED IN COMMERCIAL APPLICATIONS. IT IS INTENDED TO BE USED FOR
HOBBY, LEARNING AND EDUCATIONAL PURPOSE ONLY. IF YOU WANT TO USE THEM IN
COMMERCIAL APPLICATION PLEASE WRITE TO THE AUTHOR.


WRITTEN BY:
AVINASH GUPTA
me@avinashgupta.com

*******************************************************************************/

#ifndef USART_PIC16_H
#define USART_PIC16_H

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

//Constants
#define RECEIVE_BUFF_SIZE 64

//Varriables
volatile char URBuff[RECEIVE_BUFF_SIZE]; //USART Receive Buffer
volatile int8_t UQFront;
volatile int8_t UQEnd;

void USARTInit(uint16_t baud_rate);
void USARTWriteChar(char ch);
void USARTWriteString(const char *str);
void USARTWriteLine(const char *str);
void USARTWriteInt(int16_t val, int8_t field_length);
void USARTHandleRxInt();
char USARTReadData();
uint8_t USARTDataAvailable();
void USARTGotoNewLine();
void USARTReadBuffer(char *buff,uint16_t len);
void USARTFlushBuffer();



#ifdef __cplusplus
}
#endif

#endif /* USART_PIC16_H */


Código: [Seleccionar]
#include <stdint.h>
#include <xc.h>

#include "usart_pic16.h"

void interrupt ISR(void)
{
    if (RCIE && RCIF) {
        USARTHandleRxInt();
        return;
    }
}

Código: [Seleccionar]
#define _XTAL_FREQ 4000000
#include <xc.h>
#include <pic16f628a.h>
#include <stdio.h>
#include <stdlib.h>
#include "confbits.h"
#include "lcd.h"
#include "usart_pic16.h"
 

/* defino headers */


#define boton PORTBbits.RB4

//************************** defino funciones main *************************
void lcdout (int x , int y , char *b);
void led (void);
void init (void);
void web (void);
char data ;

unsigned char teclado (void);

//**************************************************************************
 unsigned char resultado = 0;


void main(void)
{
       init (); // inicializo el up
       Lcd_Init();
       Lcd_Clear();
       lcdout(4,1,"Programa"); // escribo lcd con datos de copyrights
       lcdout(2,2,"Copyrights 2015");
      
      
       USARTInit(9600);

     while(1)
      

   {
    
       //    if (teclado() == 1)
      {
       //led(); // prendo y apago led
      // web(); //transmito los datos al esp8266
      
        uint8_t n= USARTDataAvailable();

            //si tengo datos
            if(n!=0)
             {
               //leo el serie
               char  data=USARTReadData();
             Lcd_Clear();
             lcdout(1,1,data); // recibo repuesta de esp8266
             }

      
      }
  }
      
    
}
 
// ******************** inicializacion cpu ***************************  
void init (void)
{
   PCONbits.OSCF ;// reloj en 4 mhz
   CMCON = 0X07 ; //apaga los comparadores y habilita los pines de I/O
  TRISA = 0x00;
  PORTA = 0X00;
  TRISBbits.TRISB3 = 0; // led como salida
  TRISBbits.TRISB4 = 1; // boton como entrada
  TRISBbits.TRISB1 = 1; //terminal rx como entrada
  TRISBbits.TRISB2 = 1;
  
     }
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado RodrigoAndres

  • PIC16
  • ***
  • Mensajes: 171
Re: Pic16f628a USART problema para recibir
« Respuesta #1 en: 04 de Julio de 2015, 22:45:31 »
No soy para nada experto pero tratare de ayudarte.

creo qe el error es que estas leyendo el dato en la rutina del main, pero tambien estas recibiendo el dato en la rutina de interrupcion:

EN LA INTERRUPCION:
Código: [Seleccionar]
void interrupt ISR(void)
{
    if (RCIE && RCIF) {
        USARTHandleRxInt();
        return;
    }
}

Código: [Seleccionar]
void USARTHandleRxInt()
{
  if(RB1==1)
    RB1=0;
  else
    RB1=1;
  
    //Read the data
    char data=RCREG;

    //Now add it to q
    if(((UQEnd==RECEIVE_BUFF_SIZE-1) && UQFront==0) || ((UQEnd+1)==UQFront))
    {
        //Q Full
UQFront++;
if(UQFront==RECEIVE_BUFF_SIZE) UQFront=0;
    }

    if(UQEnd==RECEIVE_BUFF_SIZE-1)
        UQEnd=0;
    else
UQEnd++;

    URBuff[UQEnd]=data;

    if(UQFront==-1) UQFront=0;
    
}

EN EL MAIN:
Código: [Seleccionar]
uint8_t n= USARTDataAvailable();

            //si tengo datos
            if(n!=0)
             {
               //leo el serie
               char  data=USARTReadData();
             Lcd_Clear();
             lcdout(1,1,data); // recibo repuesta de esp8266
             }

prueba a desactivar la interrupcion asi:

Código: [Seleccionar]
USARTInit(9600);
RCIE=0;

Saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Pic16f628a USART problema para recibir
« Respuesta #2 en: 05 de Julio de 2015, 04:36:01 »
Para RodrigoAndres

Para mi que estas equivocado Rodrigo, al menos de lo que lei del codigo.

USARTHandleRxInt() lo que hace esa funcion es guardar el dato en el buffer que crea el archivo USART_PIC16.H
Esa variable se llama URBuff[] y de tamaño RECEIVE_BUFF_SIZE
Usa dos indices : UQEnd y UQFront, el primero indica la posicion del ultimo valor que llego al buffer, y el otro indica la posicion del caracter que va a ser leido , ejemplo recibi 10 caracteres y lei solo 3, UQFront=2 y UQEnd=9  (recorda que incluye el 0)

Basciamente crea un array y lo va llenando.

Las demas funciones:

USARTDataAvailable()
Simplemente ve si hay un dato en el buffer ese craedo, devuelve 0 si no hay nada o un valor que es el tamaño del buffer

USARTReadData()
Devuelve el dato recibido

Al menos las funciones esas parecen estar bien.,

Para Rseliman

Lo que si le quitaria es el return a la funcion de interrupcion, es decir:

Código: C
  1. void interrupt ISR(void)
  2. {
  3.     if (RCIE && RCIF) {
  4.         USARTHandleRxInt();
  5.     }
  6. }

Ademas en tu codigo, segun como estas haciendo el main, estaria enviando al 1,1 todas letras asi que irian apareciendo letra por letra lo que le estas enviando.
es decir si mandas "HOLA" imagino que verias solo la "A" en la posicion 1,1 del LCD.
La unica que te queda para probar si es esto, es que mandes 1 por 1 despacio los datos. Asi podes verlo.
Si aun asi despues de todo esto NO te funciona ya miraria la configuracion del UART.

Si quisieras recibir todo junto ya deberias modificar el codigo, usar otras funciones y por ahi hasta modificar algunas como la de la interrupcion.
« Última modificación: 05 de Julio de 2015, 05:18:08 por KILLERJC »

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Pic16f628a USART problema para recibir
« Respuesta #3 en: 05 de Julio de 2015, 10:04:39 »
No soy para nada experto pero tratare de ayudarte.

creo qe el error es que estas leyendo el dato en la rutina del main, pero tambien estas recibiendo el dato en la rutina de interrupcion:


Muchas gracias por la respuesta Rodrigo , sin importar si es o no , muchas veces cualquier repuesta ayuda a abrir los ojos de los programadores ...Gracias
« Última modificación: 05 de Julio de 2015, 10:07:35 por Rseliman »
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Pic16f628a USART problema para recibir
« Respuesta #4 en: 05 de Julio de 2015, 10:12:12 »
Para RodrigoAndres

Para mi que estas equivocado Rodrigo, al menos de lo que lei del codigo.

USARTHandleRxInt() lo que hace esa funcion es guardar el dato en el buffer que crea el archivo USART_PIC16.H
Esa variable se llama URBuff[] y de tamaño RECEIVE_BUFF_SIZE
Usa dos indices : UQEnd y UQFront, el primero indica la posicion del ultimo valor que llego al buffer, y el otro indica la posicion del caracter que va a ser leido , ejemplo recibi 10 caracteres y lei solo 3, UQFront=2 y UQEnd=9  (recorda que incluye el 0)

Basciamente crea un array y lo va llenando.

Las demas funciones:

USARTDataAvailable()
Simplemente ve si hay un dato en el buffer ese craedo, devuelve 0 si no hay nada o un valor que es el tamaño del buffer

USARTReadData()
Devuelve el dato recibido

Al menos las funciones esas parecen estar bien.,

Para Rseliman

Lo que si le quitaria es el return a la funcion de interrupcion, es decir:

Código: C
  1. void interrupt ISR(void)
  2. {
  3.     if (RCIE && RCIF) {
  4.         USARTHandleRxInt();
  5.     }
  6. }

Ademas en tu codigo, segun como estas haciendo el main, estaria enviando al 1,1 todas letras asi que irian apareciendo letra por letra lo que le estas enviando.
es decir si mandas "HOLA" imagino que verias solo la "A" en la posicion 1,1 del LCD.
La unica que te queda para probar si es esto, es que mandes 1 por 1 despacio los datos. Asi podes verlo.
Si aun asi despues de todo esto NO te funciona ya miraria la configuracion del UART.

Si quisieras recibir todo junto ya deberias modificar el codigo, usar otras funciones y por ahi hasta modificar algunas como la de la interrupcion.


Muchas gracias por la respuesta KillerJc ...lo que me esta pasando es lo siguiente ....inicio el programa y la interrupcion espera una tecla ...al escribir una A por ejemplo , me tira una serie de caracteres ....es como si no tuviese en cuenta la cantidad que le envio ...y a veces me muestra codigo que esta escrito al final del programa ...me explico ?? o sea ..toco una tecla y me tira parte del codigo escrito a la ultimo del mismo ...o sea es como si  UQEnd y UQFront no tuviesen valores reales ...no se si me explico ..

Gracias

Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Pic16f628a USART problema para recibir
« Respuesta #5 en: 05 de Julio de 2015, 14:25:08 »
Hay 3 cosas que me preocupan.. Como dije las funciones de la libreria parecen funcionar perfectamente, no las use pero siguiendo la logica del programa parece que si funciona.

1 - es el main. Hay llaves por demas {} , imagino que son del if, pero veo que no las comentaste. No se ni como es que compilo eso.
2 - la funcion lcdout() segun como este programado puede fallar , por lo que parece envia un string, y  normalmente un string en C es una coleccion de char + un caracter nulo , es decir '\0'. Ese caracter nulo se usa para saber cuando termina el string, con lo cual aca:

lcdout(4,1,"Programa");

Funcionaria ya que "Programa" en realidad es array[9]={'P','r','o','g','r','a','m','a','\0'} y estarias apuntando a la P al comienzo, es decir se le envia la direccion de comienzo. Por que es mas facil hacerlo con punteros

Mientras que cuando vos usas

lcdout(1,1,data);

ocurren 2 cosas que pueden hacer que falle lo que vos queres hacer, envias el contenido y por otro lado envias un solo caracter.
Asi que aca podes probar otra cosa

Si lcdout() acepta 1 solo caracter sin el caracter nulo entonces:

Código: C
  1. lcdour(1,1,&data);

Si lcdout() NO acepta sin el caracter nulo, es decir espera un string, podes hacer algo asi para intentar remediarlo

Código: C
  1. while(1)
  2.         {
  3.                 //si tengo datos
  4.                 if(USARTDataAvailable())
  5.                 {
  6.                         char data[2];
  7.                         data[0]=USARTReadData();
  8.                         data[1]='\0'
  9.                         Lcd_Clear();
  10.                         lcdout(1,1,data); // recibo repuesta de esp8266
  11.                 }
  12.        
  13.         }

3 - tamaño del buffer, en el .h esta definido en 64, lo cual estas ocupando 64 espacios de memoria sin sentido, achicalo a 10/15 , eso va a depender que rapido estes leyendo los datos guardados, a no ser que tengas que recibir los 64 datos para asi luego trabajar.

Citar
.y a veces me muestra codigo que esta escrito al final del programa
Esto no deberia pasar ni queriendo, ya que seria un poco imposible, en las PC "si se puede" por que los datos/instrucciones (Von Neumann) estan juntos y ante un buffer/stack overflow podria ocurrir que se libere informacion que no se deba. Pero aca esta limitado los limites de los punteros del buffer. Y es una arquitectura diferente ( Hardvard ).
Si esta sucediendo me parece mas un problema del simulador/debugger si es que estas usando... Ademas los 16F no poseen memoria lineal y creo que tampoco tienen acceso como datos la memoria flash, aparte de todo esto, el programa en C no es lo que se guarda en el micro, ni tampoco en ASM ya que estos son nemonicos y lo que se guarda son los OPcodes que no tienen ninguna relacion con las letras ni de ASM, ni de C. Asi que aun lo veo muchisimo mas improbable que sea un problema del micro.

Lo que si puede estar mostrando basura por redireccionarlo a otro lado. Y hasta no encontrar un caracter nulo agarrar todos los datos posibles ( de la memoria de datos ) y mostrarlos en el LCD

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Pic16f628a USART problema para recibir
« Respuesta #6 en: 05 de Julio de 2015, 14:47:26 »
Muchas gracias por la repuesta ..

en cuanto a las llaves es porque estaba simplificando parte para determinar el problema ...las llaves se anulan entre si por eso compila ...o sea las ignora ...

Ya encontr el problema ....la funcion andaba bien cuando lo que se enviaba eran caracteres ...solo caracteres , pero tal como vos lo decis ..estaba mesclando caracteres con strings ...

lo que si no pude entender es porque me imprimia parte del codigo ...la verdad no se , lo hacia en Proteus y en el protoboard tambien ....

Ahora veo las palabras completas , solo que de a una letra por ves ...y tengo que detectar un OK que viene del esp8266 placa wifi ....ya vere como lo resuelvo ...

Mil gracias por tu tiempo ...estoy a tus ordenes si te puedo servir para algo ...

te mando un Abrazo y nuevamente gracias



Hay 3 cosas que me preocupan.. Como dije las funciones de la libreria parecen funcionar perfectamente, no las use pero siguiendo la logica del programa parece que si funciona.

1 - es el main. Hay llaves por demas {} , imagino que son del if, pero veo que no las comentaste. No se ni como es que compilo eso.
2 - la funcion lcdout() segun como este programado puede fallar , por lo que parece envia un string, y  normalmente un string en C es una coleccion de char + un caracter nulo , es decir '\0'. Ese caracter nulo se usa para saber cuando termina el string, con lo cual aca:

lcdout(4,1,"Programa");

Funcionaria ya que "Programa" en realidad es array[9]={'P','r','o','g','r','a','m','a','\0'} y estarias apuntando a la P al comienzo, es decir se le envia la direccion de comienzo. Por que es mas facil hacerlo con punteros

Mientras que cuando vos usas

lcdout(1,1,data);

ocurren 2 cosas que pueden hacer que falle lo que vos queres hacer, envias el contenido y por otro lado envias un solo caracter.
Asi que aca podes probar otra cosa

Si lcdout() acepta 1 solo caracter sin el caracter nulo entonces:

Código: C
  1. lcdour(1,1,&data);

Si lcdout() NO acepta sin el caracter nulo, es decir espera un string, podes hacer algo asi para intentar remediarlo

Código: C
  1. while(1)
  2.         {
  3.                 //si tengo datos
  4.                 if(USARTDataAvailable())
  5.                 {
  6.                         char data[2];
  7.                         data[0]=USARTReadData();
  8.                         data[1]='\0'
  9.                         Lcd_Clear();
  10.                         lcdout(1,1,data); // recibo repuesta de esp8266
  11.                 }
  12.        
  13.         }

3 - tamaño del buffer, en el .h esta definido en 64, lo cual estas ocupando 64 espacios de memoria sin sentido, achicalo a 10/15 , eso va a depender que rapido estes leyendo los datos guardados, a no ser que tengas que recibir los 64 datos para asi luego trabajar.

Citar
.y a veces me muestra codigo que esta escrito al final del programa
Esto no deberia pasar ni queriendo, ya que seria un poco imposible, en las PC "si se puede" por que los datos/instrucciones (Von Neumann) estan juntos y ante un buffer/stack overflow podria ocurrir que se libere informacion que no se deba. Pero aca esta limitado los limites de los punteros del buffer. Y es una arquitectura diferente ( Hardvard ).
Si esta sucediendo me parece mas un problema del simulador/debugger si es que estas usando... Ademas los 16F no poseen memoria lineal y creo que tampoco tienen acceso como datos la memoria flash, aparte de todo esto, el programa en C no es lo que se guarda en el micro, ni tampoco en ASM ya que estos son nemonicos y lo que se guarda son los OPcodes que no tienen ninguna relacion con las letras ni de ASM, ni de C. Asi que aun lo veo muchisimo mas improbable que sea un problema del micro.

Lo que si puede estar mostrando basura por redireccionarlo a otro lado. Y hasta no encontrar un caracter nulo agarrar todos los datos posibles ( de la memoria de datos ) y mostrarlos en el LCD
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Pic16f628a USART problema para recibir
« Respuesta #7 en: 05 de Julio de 2015, 15:08:21 »
lo que si no pude entender es porque me imprimia parte del codigo ...la verdad no se , lo hacia en Proteus y en el protoboard tambien ....

Estas seguro que era parte del codigo o solo eran los datos ?, por ejemplo "Copyrights 2015" o "Programa" , etc

Ahora veo las palabras completas , solo que de a una letra por ves ...y tengo que detectar un OK que viene del esp8266 placa wifi ....ya vere como lo resuelvo ...

Eso lo podes solucionar, imagino que el ESP8266 te envia un retorno de carro y salto a nueva linea no? es decir un \r\n al final. o aunque sea un \n o un \r solo.
En tu rutina de interrupcion podrias hacer un:

Código: C
  1. // Aca arriba utilizo el handler
  2. if ( URBuff[UQEnd)=='\n')                                // Leo el ultimo valor que llego, UQEnd no deberia ser nunca -1 por que ya supuestamente llego un dato.
  3. {
  4.     g_cantidad_datos=USARTDataAvailable();     //Guardo la cantidad de datos hasta '\n', variable global
  5. }

Y luego cuando lees haces un:

Código: C
  1. while(1)
  2.                 if(g_cantidad_datos)    // Hay algo? es decir se completo una palabra?, recordar iniciarlo en 0 a esa variable global.
  3.                 {
  4.                         char data[20];                                                   // Esto es para guardarlo en otro lugar, recordar que tiene un tamaño maximo de 19 caracteres por ser 20.
  5.                         USARTReadBuffer(data,g_cantidad_datos);            // Leo por la cantidad de datos que hubo
  6.                         g_cantidad_datos=0;                                         // Pongo a 0 para que no entre mas hasta que llegue algo
  7.                         Lcd_Clear();                                                        // Limpio y envio al LCD
  8.                         lcdout(1,1,data); // recibo repuesta de esp8266
  9.                 }
  10.        
  11.         }

Todo eso si es que se envia algun caracter de finalizacion desde el ESP8266, sino tendrias que buscar otra forma.
Ademas tambien existe la posibilidad de que pueda perderse un dato, si es asi deberias implementar un timeout con algun timer y sin necesidad de interrupcion.
Y los datos deberian leerse y pasarse al array data, antes que llegue otro '\n'
« Última modificación: 05 de Julio de 2015, 15:24:41 por KILLERJC »

Desconectado RodrigoAndres

  • PIC16
  • ***
  • Mensajes: 171
Re: Pic16f628a USART problema para recibir
« Respuesta #8 en: 05 de Julio de 2015, 17:06:56 »
si es verdad el tiene razon con eso, pero es muy raro qe funcione sin qe borres la bandera de interrupcion RCIF, como ases para que funcione asi??

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Pic16f628a USART problema para recibir
« Respuesta #9 en: 05 de Julio de 2015, 18:13:24 »
si es verdad el tiene razon con eso, pero es muy raro qe funcione sin qe borres la bandera de interrupcion RCIF, como ases para que funcione asi??

Cuando se lee el RCREG se borra automaticamente la bandera

Usando el datasheet de un PIC16F887:

Sobre el flag:
Citar
RCIF: EUSART Receive Interrupt Flag bit
1 = The EUSART receive buffer is full (cleared by reading RCREG)
y
Citar
The RCIF interrupt flag bit is read-only, it cannot be set or cleared by software.
Yo tambien por ahi me olvido de esto xD.

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Pic16f628a USART problema para recibir
« Respuesta #10 en: 05 de Julio de 2015, 20:08:35 »
lo que si no pude entender es porque me imprimia parte del codigo ...la verdad no se , lo hacia en Proteus y en el protoboard tambien ....

Estas seguro que era parte del codigo o solo eran los datos ?, por ejemplo "Copyrights 2015" o "Programa" , etc

Ahora veo las palabras completas , solo que de a una letra por ves ...y tengo que detectar un OK que viene del esp8266 placa wifi ....ya vere como lo resuelvo ...
Era parte del codigo , pero claro otra ves tenes razon ...eran caracteres asschi , ya que estaban entre comillas , uso el esp8266 para enviar datos a una pagina web ..y lo que se veia eran los datos que direccion web ...de todas maneras es raro , pero bueno ...desp te voy a preguntar de nuevo por el tema de reconocer el OK que me devuelve el 8266 ...yo le transmito comandos AT ..y el me contesta con OK ...pero en el ultimo caso tengo que detectar la respuesta de la pagina ..que es un numero de 3 cifras ...el tema es que viene con mucho texto ...lo que hago es un GET a un PHP ...a una base de datos y cuando me contesta tengo que tomar ese numero ...

Gracias Muchas gracias
« Última modificación: 05 de Julio de 2015, 20:11:46 por Rseliman »
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Pic16f628a USART problema para recibir
« Respuesta #11 en: 05 de Julio de 2015, 23:05:53 »
Lo que necesitarias es un parser de la respuesta que te da.

Basicamente cuando generas una peticion HTTP enviandole el header, el server te responde con otro header+pagina

Citar
HTTP/1.x 200 OK
Transfer-Encoding: chunked
Date: Sat, 28 Nov 2009 04:36:25 GMT
Server: LiteSpeed
Connection: close
X-Powered-By: W3 Total Cache/0.8
Pragma: public
Expires: Sat, 28 Nov 2009 05:36:25 GMT
Etag: "pub1259380237;gz"
Cache-Control: max-age=3600, public
Content-Type: text/html; charset=UTF-8
Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT
X-Pingback: http://net.tutsplus.com/xmlrpc.php
Content-Encoding: gzip
Vary: Accept-Encoding, Cookie, User-Agent
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Top 20+ MySQL Best Practices - Nettuts+</title>
<!-- ... rest of the html ... -->

De ahi imagino que queres obtener el status unicamente, que es el numero ahi (en negrita), mas que el OK.

Lo cual cuando envias vas a tener que recibir linea por linea en tu buffer.. la primera linea podes buscar hasta encontrar la posicion de los espacios ' ' y luego retirar el numero. Sabiendo que la primer linea del protocolo es esa, el protocolo + status
De ahi en mas te llegaria todo lo demas, que puede o no servirte.. lo que sigue.

Ahora si esto es una pagina o algo que necesitas obtener de una pagina que VOS creaste tal ves pueda sacar los datos en otro formato en otra pagina/direccion, como un txt/json/csv o algo asi para tener menor cantidad de texto y ahorrarte la llegada de todos los tags HTML.  Si ya es una pagina que no hiciste vos entonces vas a tener que renegar un poco con el tema de un parser, ya que encontrar el contenido de una pagina en todo el HTML es medio complejo, especialmente cuando se les ocurre cambiar una cosita chiquita de la pagina y ya deja de andar todo.

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Pic16f628a USART problema para recibir
« Respuesta #12 en: 26 de Septiembre de 2015, 12:34:22 »
Hola a todos :

Parece mentira pero no puedo solucionar lo siguiente ...estoy leyendo de la uart una pagina html ..lo que me da el siguiente resultado

+IPD,175:HTTP/1.1 200 OK
Server: nginx
Date: Sat, 26 Sep 2015 14:03:28 GMT
Content-Type: text/html
Connection: close
X-Powered-By: PHP/5.3.29
X-Proxy-Cache: BYPASS

(CONECTADO)CLOSED


y quiero extraer de ahi solo el texto (conectado) ...le puse los parentesis para poder parsearlo ...

hago lo siguiente

Código: [Seleccionar]
void respuesta(void)
 {
     while(1)
     {
         //Get the amount of data waiting in USART queue
         uint8_t n= USARTDataAvailable();
         char data[];
              //If we have some data
          if(n!=0)
            {
              //Read it)
              USARTReadBuffer(&data,n);
              sprintf(salida,"%s",&data);
              Lcd_Clear();
              Lcd_Set_Cursor(2,1);
              Lcd_Write_String(salida);
            }
     }
 }

de esta manera imprimo el total de datos en el buffer , en el lcd ...que es 2x16 ..asi que solo veo lo ultimo ...

pero quiero solamente ver el conectado y no me doy cuenta como sacarlo de una manera prolija ..

Gracias por la ayuda

mplabx xc8 pic 16f628
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Pic16f628a USART problema para recibir
« Respuesta #13 en: 26 de Septiembre de 2015, 13:17:40 »
podrias buscar por un doble salto de linea \n\n (si es que solamente son \n y no \r\n ), sino buscar por 2 \r\n


Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: Pic16f628a USART problema para recibir
« Respuesta #14 en: 26 de Septiembre de 2015, 14:30:54 »
Para buscar la plabra "conectado" dentro del buffer, tendras que utilizar una rutina de busqueda quisas utilizando ,if, anidados para ello y usar punteros.

Saludos


 

anything