Autor Tema: USART pic16f628 tx ok RX error  (Leído 3339 veces)

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

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
USART pic16f628 tx ok RX error
« en: 10 de Enero de 2016, 10:58:09 »
Hola  a todos ..

No puedo darme cuenta donde esta el error que cometo..me he pasado leyendo el datasheets del PIC y nada ...no logro transmitirle un caracter desde la pc al pic

tengo un modulo usb TTL conectado al notebook ...este recibe perfectamente los caracteres que transmite el pic ...pero a la hora de enviar un caracter al pic ..no encuentro forma de que funcione ...alguien me da una mano por favor ...gracias

esta es la lib del usart

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(void)
{
    //Setup queue
    UQFront=UQEnd=-1;
       
    //SPBRG
        SPBRG=25; //datasheets pagina 76 pic16f628 4MHZ velocidad 2400
   
    //TXSTA
    TXSTAbits.TX9=0;  //8 bit ttsransmission
    TXSTAbits.TXEN=1; //Transmit enable
    TXSTAbits.SYNC=0; //Async mode    1= sync 0= async
    TXSTAbits.BRGH=0; //High speed baud rate    1= high  0= low

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


Headers

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 32
   

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




void USARTInit(void);
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 */


y esto hago en el main


Código: [Seleccionar]
#define _XTAL_FREQ 4000000

#include <xc.h>
#include <pic16f628a.h>
#include <stdio.h>
#include <stdlib.h>
#include "confbits.h"
#include <string.h>
#include "711.h"
#include "usart_pic16.h"
 



//**************************** variables globales



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


void main(void)
{
   
       // **********************inicializo el micro
      // ******************** inicializacion cpu *************************** 

      PCONbits.OSCF;// reloj en 4 mhz
      CMCON = 0X07 ; //apaga los comparadores y habilita los pines de I/O
      TRISA = 0x00;
      PORTA = 0X00;
     
      TRISBbits.TRISB1 = 1; //terminal rx como entrada
      TRISBbits.TRISB2 = 0; //terminal tx como salida
      TRISBbits.TRISB5 = 0;  // adsk como salida
      TRISBbits.TRISB3 = 1; // add0 como entrada
      TRISBbits.TRISB4 = 0; // salida relay
     

     
      USARTInit();
      unsigned long datos ;
      unsigned char salida[7];
      unsigned char  *ptr, i,datas;

       
       

     
      while (1)
        {   
              uint8_t n = USARTDataAvailable();
             

             
              if (n != 0)
              {
               datas = USARTReadData();
               USARTWriteChar(datas);
               PORTBbits.RB4 = 1;
               __delay_ms(100);
              }

               PORTBbits.RB4 = 0;
 //           datos = ReadCount();
 //           ptr = &datos; // puntero apunta a la direccion de 8 bits donde se encuentra el dato
 //           sprintf(salida,",%02X%02X%02X",*(ptr+2),*(ptr+1),*ptr); //suma 1 y 2 al puntero 8 16 y 24 bits       
 //           USARTWriteString(salida); // transmito los 24 bits completos en Hexa
        }

 
     
 

estan comentadas las lineas de tx porque solo quiero probar las RX que es la que no funciona ...


Código: [Seleccionar]
// PIC16F648A 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 = INTOSCCLK // 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 = OFF      // 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)


//__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_ON & LVP_OFF & CPD_OFF & CP_OFF);


« Última modificación: 10 de Enero de 2016, 13:25:12 por Rseliman »
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re:USART pic16f628 tx ok RX error
« Respuesta #1 en: 10 de Enero de 2016, 13:39:05 »
Muchas gracias a todos ...ya logre que funcione , siempre me pasa lo mismo ...lo soluciono desp de haber preguntado por aca ...

tenia un problema en el protoboard ....


saludos ....asi como esta funciona bien

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

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:USART pic16f628 tx ok RX error
« Respuesta #2 en: 10 de Enero de 2016, 14:18:30 »
Tu problema es que no estas usando las interrupciones, ya que no entiendo como funcionaria sino....

Me explico, tu codigo crea un buffer circular, el cual cuando recibe un dato lo guarda en ese buffer, el tema es que UARTdataRead o como se llame, lee del buffer y no la entrda. Igual que la otra funcion que usaste indicando si hay datos disponibles. se f ija si el buffer contiene algo.. Pero... ¿quien llena ese buffer? Veamos eso...

En tu UARTInit:

Código: C
  1. //Receive interrupt
  2.     RCIE=1;
  3.     PEIE=1;
  4.  
  5.     ei();
  6. }

Se activan las interrupciones.. eso quiere decir que con las interrupciones tenemos que hacer algo.. deberiamos crear una por nosotros mismo y que vaya llenando el buffer? No.. ya esta realizado:

Código: C
  1. void USARTHandleRxInt()

Asi que en tu main. o cualquier otro arhivo que tengas para todas las interrupciones, deberias hacer algo asi:

Código: C
  1. void interrupt INTs (void)
  2. {
  3.         if(PIR1bits.RCIF && PIE1bits.RCIE) USARTHandleRxInt();
  4. }

De esa forma el Handler se encarga de cuando entra a una interrupcion de llenar ese buffer circular y avanzar los indices.
Creo que es lo unico que te falla, ya que sin esa llamada nunca se llenaria ese buffer. Y es por eso que no lees nada.

Es algo que no veo en el codigo, pero aun asi afirmas que funciona. Y es la unica funcion que lee el RCREG
« Última modificación: 10 de Enero de 2016, 14:27:16 por KILLERJC »

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re:USART pic16f628 tx ok RX error
« Respuesta #3 en: 10 de Enero de 2016, 14:22:27 »
Mil disculpas KILLERJC ...me olvide de postear la interrupt ....pero la tengo escrita ....ya funciona ...

ahora el tema es que mientras estoy saliendo por tx , me deberia recibir el caracter por RX ...y lo recibe, pero desp de insistir ...es como que mientras esta transmitiendo no se activa la interrup ...o algo asi

Gracias

saludos



Tu problema es que no estas usando las interrupciones...

Te explico, tu codigo crea un buffer circular, el cual cuando recibe un dato lo guarda en ese buffer, el tema es que UARTdataRead o como se llame, lee del buffer y no la entrda. Igual que la otra funcion que usaste indicando si hay datos disponibles. se f ija si el buffer contiene algo.. Pero... ¿quien llena ese buffer? Veamos eso...

En tu UARTInit:

Código: C
  1. //Receive interrupt
  2.     RCIE=1;
  3.     PEIE=1;
  4.  
  5.     ei();
  6. }

Se activan las interrupciones.. eso quiere decir que con las interrupciones tenemos que hacer algo.. deberiamos crear una por nosotros mismo y que vaya llenando el buffer? No.. ya esta realizado:

Código: C
  1. void USARTHandleRxInt()

Asi que en tu main. o cualquier otro arhivo que tengas para todas las interrupciones, deberias hacer algo asi:

Código: C
  1. void interrupt   RX_INT  (void)
  2. {
  3.      USARTHandleRxInt();
  4. }

De esa forma el Handler se encarga de cuando entra a una interrupcion de llenar ese buffer circular y avanzar los indices.
Creo que es lo unico que te falla
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:USART pic16f628 tx ok RX error
« Respuesta #4 en: 10 de Enero de 2016, 14:32:40 »
Mil disculpas KILLERJC ...me olvide de postear la interrupt ....pero la tengo escrita ....ya funciona ...

ahora el tema es que mientras estoy saliendo por tx , me deberia recibir el caracter por RX ...y lo recibe, pero desp de insistir ...es como que mientras esta transmitiendo no se activa la interrup ...o algo asi

Gracias

saludos

Solamente estas probando esto no ?:

Código: C
  1. if (USARTDataAvailable())
  2.               {
  3.                datas = USARTReadData();
  4.                USARTWriteChar(datas);
  5.                PORTBbits.RB4 ^= 1;
  6.                __delay_ms(100);
  7.               }

Si es solo eso.. quitale el delay y probalo. o usa

void USARTReadBuffer(char *buff,uint16_t len);
y
void USARTWriteString(const char *str);

Sino estas leyendo caracter por caracter, y la transmision es bloqueante
« Última modificación: 10 de Enero de 2016, 14:39:36 por KILLERJC »

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re:USART pic16f628 tx ok RX error
« Respuesta #5 en: 10 de Enero de 2016, 14:35:54 »
Ahora estoy Probando asi


Código: [Seleccionar]
      PORTBbits.RB4 = 0; 

     
      while (1)
        {   
              uint8_t n = USARTDataAvailable();
            if (n != 0)
              {
                  datas = USARTReadData();

                     if (datas == 'D') // DISPARO
                       {
                        PORTBbits.RB4 = 1;
                       }
                     else if (datas == 'C') // CORTE
                       {
                        PORTBbits.RB4 = 0;
                       }
              }


            datos = ReadCount();
            ptr = &datos; // puntero apunta a la direccion de 8 bits donde se encuentra el dato
            sprintf(salida,",%02X%02X%02X",*(ptr+2),*(ptr+1),*ptr); //suma 1 y 2 al puntero 8 16 y 24 bits       
            USARTWriteString(salida); // transmito los 24 bits completos en Hexa
           
        }
     
     
     
}

y me cuesta que reciba el caracter ...tengo que insistir hasta que por ultimo lo recibe








Mil disculpas KILLERJC ...me olvide de postear la interrupt ....pero la tengo escrita ....ya funciona ...

ahora el tema es que mientras estoy saliendo por tx , me deberia recibir el caracter por RX ...y lo recibe, pero desp de insistir ...es como que mientras esta transmitiendo no se activa la interrup ...o algo asi

Gracias

saludos

Solamente estas probando esto no ?:

Código: C
  1. if (USARTDataAvailable())
  2.               {
  3.                datas = USARTReadData();
  4.                USARTWriteChar(datas);
  5.                PORTBbits.RB4 ^= 1;
  6.                __delay_ms(100);
  7.               }

Si es solo eso.. quitale el delay y probalo. o usa

void USARTReadBuffer(char *buff,uint16_t len);
y
void USARTWriteString(const char *str);

Sino estas leyendo caracter por caracter, y la transmision es bloqueante
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:USART pic16f628 tx ok RX error
« Respuesta #6 en: 10 de Enero de 2016, 14:43:33 »
Si probas, quitale el sprint y lo demas... solamente deja la parte de arriba, asi vemos que parte es el problema. Me refiero a dejar esta parte de codigo:

Código: C
  1. if (USARTDataAvailable())
  2.               {
  3.                   datas = USARTReadData();
  4.  
  5.                      if (datas == 'D') // DISPARO
  6.                        {
  7.                         PORTBbits.RB4 = 1;
  8.                        }
  9.                      else if (datas == 'C') // CORTE
  10.                        {
  11.                         PORTBbits.RB4 = 0;
  12.                        }
  13.               }

Tambien prodrias probar poner que cada ves que entre a la interrupcion cambie el estado de otro pin suponete RB3 y te aseguras que si o si se recibio correctamente.

Código: C
  1. void interrupt INTs (void)
  2. {
  3.         if(PIR1bits.RCIF && PIE1bits.RCIE) USARTHandleRxInt();  PORTBbits.RB3 ^= 1;
  4. }


EDIT:

No hagas caso a lo ultimo que dije lo de la salida, veo que ya el Handler maneja el RB1
« Última modificación: 10 de Enero de 2016, 14:45:37 por KILLERJC »

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re:USART pic16f628 tx ok RX error
« Respuesta #7 en: 10 de Enero de 2016, 14:46:12 »
Como lo escribiste funciona perfecto ...el tema es cuando agrego el tema TX ....

Ahora pruebo meter el PORTB en la interrup





Si probas, quitale el sprint y lo demas... solamente deja la parte de arriba, asi vemos que parte es el problema. Me refiero a dejar esta parte de codigo:

Código: C
  1. if (USARTDataAvailable())
  2.               {
  3.                   datas = USARTReadData();
  4.  
  5.                      if (datas == 'D') // DISPARO
  6.                        {
  7.                         PORTBbits.RB4 = 1;
  8.                        }
  9.                      else if (datas == 'C') // CORTE
  10.                        {
  11.                         PORTBbits.RB4 = 0;
  12.                        }
  13.               }

Tambien prodrias probar poner que cada ves que entre a la interrupcion cambie el estado de otro pin suponete RB3 y te aseguras que si o si se recibio correctamente.

Código: C
  1. void interrupt INTs (void)
  2. {
  3.         if(PIR1bits.RCIF && PIE1bits.RCIE) USARTHandleRxInt();  PORTBbits.RB3 ^= 1;
  4. }
                     
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re:USART pic16f628 tx ok RX error
« Respuesta #8 en: 10 de Enero de 2016, 14:56:01 »
Ya lo encontre !!!!!!

estoy con los modulos APC230 ...confiado que es un puerto trasnparente ...y no es tan asi ...conecte todo directo al USB / TTL y anda perfecto ....tendre que empezar a probar con las velocidades de los APC230 ....andan casi 100 puntos ....solo me faltaria corregir ese tema

Gracias de nuevo KILLERJC






Si probas, quitale el sprint y lo demas... solamente deja la parte de arriba, asi vemos que parte es el problema. Me refiero a dejar esta parte de codigo:

Código: C
  1. if (USARTDataAvailable())
  2.               {
  3.                   datas = USARTReadData();
  4.  
  5.                      if (datas == 'D') // DISPARO
  6.                        {
  7.                         PORTBbits.RB4 = 1;
  8.                        }
  9.                      else if (datas == 'C') // CORTE
  10.                        {
  11.                         PORTBbits.RB4 = 0;
  12.                        }
  13.               }

Tambien prodrias probar poner que cada ves que entre a la interrupcion cambie el estado de otro pin suponete RB3 y te aseguras que si o si se recibio correctamente.

Código: C
  1. void interrupt INTs (void)
  2. {
  3.         if(PIR1bits.RCIF && PIE1bits.RCIE) USARTHandleRxInt();  PORTBbits.RB3 ^= 1;
  4. }


EDIT:

No hagas caso a lo ultimo que dije lo de la salida, veo que ya el Handler maneja el RB1
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re:USART pic16f628 tx ok RX error
« Respuesta #9 en: 10 de Enero de 2016, 15:10:14 »
Recien lo veo ....los modulos APC 230 son HALF DUPLEX ....NO SON FULL DUPLEX ...ese es el problema


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

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:USART pic16f628 tx ok RX error
« Respuesta #10 en: 10 de Enero de 2016, 17:57:52 »
Bueno por lo menos lo solucionaste.