TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: LAFUMAT en 10 de Diciembre de 2010, 06:50:12

Título: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 10 de Diciembre de 2010, 06:50:12
hola:

saludos a tod@s los miembros del foro...

mi problema es el siguiente, y pido disculpas por  ser tan novato en esto de la comunicación serial.


uso el hitech version 9.80.

y en una parte de mi programa quiero pasar el contenido de la eeprom(donde registro sucesos) por via rs232 al hyperterminal...

bien, uso la libreria que ofrece el hitech que es la siguiente:


//**********************************
//rutinas de comunicaciones
void putch(unsigned char byte)
{
   /* output one byte */
   while(!TXIF)   /* set when register is empty */
      continue;
   TXREG = byte;
}

unsigned char getch()
{
   /* retrieve one byte */
   while(!RCIF)   /* set when register is not empty */
      continue;
   return RCREG;   
}

unsigned char getche(void)
{
   unsigned char c;
   putch(c = getch());
   return c;
}

//********************************************************************************************
//RUTINA DE COMUNICACIONES RS232
//
void SEND_RS232(void)
{

   INTCON=0;   // purpose of disabling the interrupts.

   init_comms();   // set up the USART - settings defined in usart.h

   // Output a message to prompt the user for a keypress   
//   printf("\rPress a key and I will echo it back:\n");//no entiendo para pantallas
   //while(1){
   //   input = getch();   // read a response from the user
   //   printf("\rI detected [%c]",input);   // echo it back
   //}
//   printf("datos:");
   for (i=0x00; i < 0xFF ; i++)
      {
      while(WR)continue;
      input = EEPROM_READ(i);
   //   printf(333);
   //   printf("\porueba\n");
      putch(input);
   //   printf("\n");
      
      }
   
   
}


resulta que los prinf no me funcionan, y el putch, si funciona, pero en hyperterminal solo veo texto corriendo sin significado.

lo que me gustaria que saliera en hyperterminal seria algo asi:

      Datos eeprom:
            00  00  00  ff  aa  00  00 5e  ff  ff  ff  aa  00 00  00  00

             00  00  00  ff  aa  00  00 5e  ff  ff  ff  aa  00 00  00  00



pero creo que hay cosas que no entiendo bien.



espero haberme explicado bien...

saludos
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 10 de Diciembre de 2010, 10:43:23
  Yo me hice mis propias rutinas para RS232 porque usaba una versión mas vieja del HiTech y no había visto estás que ya tenía el compilador.

  Si no me equivoco para que el "printf" pueda asociarse a la salida RS232 tenés que tener "#include <stdio.h>" en el programa.

  putch, lo que hace es enviar el byte, pero vos no vas a ver dicho byte sino el caracter que ese byte representa. Por ejemplo si envío 48 (putch (48 )), lo que veré en el hyperterminal es el número 0.
Para poder verlos en modo HEXA tendrías que convertirlos usando la función "itoa" (integer to ascii) y luego enviarlos con "printf".
En el manual de HiTech te muestra un ejemplo del uso de itoa y te indica que librerías tenés que incluir en tu programa. Con stdlib.h ya funciona, pero en el ejemplo incluyen stdio.h porque usan "printf" para mostrar el número convertido.
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 10 de Diciembre de 2010, 10:51:13
ok, y gracvias de antemano.

lo del include si que lo tengo...


y probare lo que me cuentas...

como dice maunix, voy a leer y si acaso luego pregunto..


saludos
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 13 de Diciembre de 2010, 06:37:01
PARA IR POCO A POCO:

He probado poner solo el    

putch(48);

y en vez de salir al hyperterminal el "0", me saca una Y con 2 puntos  (ÿ)....

¿que me fallará??

primero quiero sacer bien los ascii y luego doy el paso de pasar los datos hex...


gracias y un saludo
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 13 de Diciembre de 2010, 09:45:02
  Muchas veces los caracteres erróneos son generados por una diferencia en la velocidad. Es decir, tal vez el transmisor está configurado a 9600 baudios pero el receptor está a 19200 baudios, por dar un ejemplo.
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 13 de Diciembre de 2010, 13:39:14
despues de ver tu ultimo mensaje y leer el data sheet del pic (16f1937), he hecho modificaciones para ver como defino el puerto y lo he dejado asi:

void SEND_RS232(void)
{

   INTCON=0;   // purpose of disabling the interrupts.

   BAUDCON = 0b10000001;
   SPBRG = 25;//para ver tablas del data sheet//DIVIDER;        
   RCSTA = 0x90;//(NINE_BITS|0x90);   
   TXSTA = 0b00100100;



   for (i=0; i < 255 ; i++)
      {
      while(WR)continue;
      input = EEPROM_READ(i);

      putch(48);
   //      putch(input);
         
      }
   
   
}

pero sigue dejandome mucha info en vez de sacarme 255 ceros una y otra vez.

tengo los include correctos y el el main solo la rutina esta para probar; y nada.

yo creo que la clave esta en esos regitros que no losengo bien cnfigurados para 9600 baudios con 8 bits de datos, etc...


gracias y saludos
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 13 de Diciembre de 2010, 15:24:12
  ¿Podrías subir todo tu programa? ¿De cuanto es el cristal que estás utilizando?

  Suponiendo que tu cristal es de 4MHz y guiándome por la tabla de la página 303 del datasheet tengo lo siguiente

 bit  SYNC = 0        --> comunicación asincrónica
 bit  BRGH = 0
 bit  BRG16 = 0
 SPBRG = 25


 da una velocidad de 2400 baudios, así que a ésa velocidad deberías configurar el hyperterminal. Yo suelo usar el Proteus para simular y para RS232 hago uso del "virtual terminal" que tiene proteus.
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 14 de Diciembre de 2010, 05:37:29
hola y gracias por las molestias.

tengo un reloj interno configurado a 4mHz.

yo tengo configurado SYNC = 0; BRGH = 1; y BRG16 = 0; que a 4MHz segun la tabla 20, (DS41364B-page 228), me da 9600 baudios.

te pasaria el codigo completo pero son muchas rutinas para otras cosas. te pongo lo que uso pero si quieres te lo paso enterito.

// INCLUDES NECESARIOS
//#include <pic16f1937.h>
#include <htc.h>

//#include <delay.h>
//#include <PIC.h>
#include <EEPROM_ROUTINES.H>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <usart.h>
//PALABRA DE CONFIGURACION
//__CONFIG(INTIO & WDTDIS & PWRTEN & MCLREN & UNPROTECT & BORDIS & IESODIS & FCMDIS);
__INTERRUPT();



//DEFINICION PARA USAR LAS LIBRERIAS "DELAY"
#ifndef _XTAL_FREQ
// Unless already defined assume 4MHz system frequency
// This definition is required to calibrate __delay_us() and __delay_ms()
#define _XTAL_FREQ 4000000
#endif
//

//
//FUNCIONES DE BITS
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define flip_bit(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))
#define test_bit(ADDRESS,BIT) (ADDRESS & (1<<BIT))


//ROUTINE FOR INICIALICE ALL PORTS AND DEVICES OF SYSTEM
void init(void)
{
OSCCON = 0b11101011; //RELOJ INTERNO A 4MHz
INTCON=0b00000000;
OPTION_REG   = 0b10000111;

//TIMER CERO PARA CAP SENSING
TMR0IF=0;
TMR0IE=1;

PIE1  =  0x00;
PIE2  =  0b00000000;
PIE3  =  0x00;
IOCBP =  0b11111111;         //OJO ESTOS DOS MIRAR BIEN
IOCBN =  0b11111111;
PIR1  =  0X00;
PIR2  =  0X00;
PIR3  =  0X00;


//INTCON=0b10001000;
FVRCON = 0b10000010; //REGULADOR DE VOLTAJE lo cambiamos en cada lectura (depende de que midamos)

CPSCON0 = 0b1001001;//CAP SENSING
CPSCON1 = 0b0001010;
//INIC PORTA
//IOCA  = 0x00; WPUA  = 0x00;
PORTA = 0x00; LATA = 0x00; ANSELA = 0b00100011; TRISA = 0b01111111;
      
//INIC PORTB
//IOCB  = 0x00;
 
WPUB = 0X00;

PORTB = 0x00; LATB = 0x00; ANSELB = 0x00; TRISB = 0b11111111;

//INIC PORTC
PORTC = 0x00; LATC = 0x00;  TRISC = 0b10000000;   
//INIC PORTD
PORTD = 0x00; LATD = 0x00; ANSELD = 0b00000000; TRISD = 0b01000000;   //COMPRUEBA LAS ENTRADAS PARA LAS ANALOGICAS E/V
//INIC PORTE
PORTE = 0x00; LATE = 0x00; ANSELE = 0b11111111; TRISE = 0b11111101;   //COMPRUEBA
//

IOCIF=0;
IOCBF = 0b00000000;
IOCIF=0;

//DEFINIMOS MEMORIAS
MOTOR_ALARM_TIME = 3600 ;//TIEMPO DE ALARMA EN SEGUNDOS
MOTOR_ALARM_TIME = MOTOR_ALARM_TIME * 2;
LIMIT_TEMP = 710;
PROGRAM_MODE=0x00;


//**********************************
//rutinas de comunicaciones
void putch(unsigned char byte)
{
   /* output one byte */
   while(!TXIF)   /* set when register is empty */
      continue;
   TXREG = byte;
}

unsigned char getch()
{
   /* retrieve one byte */
   while(!RCIF)   /* set when register is not empty */
      continue;
   return RCREG;   
}

unsigned char getche(void)
{
   unsigned char c;
   putch(c = getch());
   return c;
}

//********************************************************************************************
//RUTINA DE COMUNICACIONES RS232
//
void SEND_RS232(void)
{

   INTCON=0;   // purpose of disabling the interrupts.

   BAUDCON = 0b10000001;
   SPBRG = 25;//para ver tablas del data sheet//DIVIDER;        
   RCSTA = 0x10010000;//(NINE_BITS|0x90);   
   TXSTA = 0b00100100;



   for (i=0; i < 255 ; i++)
      {
      while(WR)continue;
      input = EEPROM_READ(i);

      putch(48);
   //      putch(input);
         
      }
   
   
}

//*********************************************************************************
//EMPIEZA EL PROGRAMA PRINCIPAL
//*********************************************************************************
void  main(void)
{
init();
LOAD_EEPROM();
IOCBF = 0b00000000;
IOCIF=0;
//IOCIE=1;
PROGRAM_MODE=0x00;
MARK = 0;
ARRANQUE_AUTO();

PROG:
//INIT_EEPROM();
COMP_VIN();
//READ_ALARM();
//READ_INPUT();
//   while(1)
//   {

ABC:
   
   //ei();

//   SEND_RS232();
   READ_INPUT();
//   MOTOR_OPT();
   //SLEEP();
//   __delay_ms(50);
   goto ABC;

//   }
}




un saludo
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 16 de Diciembre de 2010, 09:04:49
MIRA QUE SOY IDIOTA (SI,SI, IDIOTA)!!!!!


Solo a mi se me ocurre el conectar el pic al rs232 olvidantome de poner el circuito adaptador de nniveles (a pelo!!).

como trabajo con 3V, voy a usar el max3232, pues no se si se puede hacer con los transistores como con el max232.


cuando me llegue el integrado te cuento

vaya tela!!
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 16 de Diciembre de 2010, 09:11:06
 Como dice el dicho "al mejor cazador se le escapa la liebre".

  Yo todavía no tuve tiempo de probar el programa, tenía pensado simularlo en Proteus para ver que pasaba pero estuve ocupado en unas reparaciones. Voy a tratar de simularlo de todos modos y así te asegurás que no haya nada mal en el programa.
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 04 de Febrero de 2011, 08:25:13
hola de nuevo:

he tardado pero he hecho progresos..

ya puse el adaptador de puerto, pero se me complico la cosa porque mi placa trabaja a 3v en vez de a 5v y hasta que consegui el max3232...

bueno , la libreria que al final uso es una de angel cris que muy bien.

ahora solo me falta convertir los datos bytes en ascii para mandar...

a ver que sale


gracias
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 04 de Febrero de 2011, 09:48:14
ESO ES, LO QUE NO SE HACER ES IR LEYENDO TODA LA EEPROM Y PONERLA EN EL HYPERTERMINAL

PUES LOS TEXTOS YA ME SALEN...


Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 04 de Febrero de 2011, 10:00:50
ESO ES, LO QUE NO SE HACER ES IR LEYENDO TODA LA EEPROM Y PONERLA EN EL HYPERTERMINAL

PUES LOS TEXTOS YA ME SALEN...


  Vamos por partes, ¿Qué es lo que no sale, ir leyendo la eeprom? ¿Vos querés ver los datos tal cual están en la eeprom? Es decir, ¿si hay un 0xFF que aparezca FF en el hyperterminal?
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 04 de Febrero de 2011, 10:09:50
eso es exactamente:

yo hago esto:

    Putst_s ("\n");     // envia el salto de linea
   Putst_s ("COMUNICATOR PROGRAM ");   // envia el string
    Putst_s ("\n");     // envia el salto de linea
    Putst_s ("\n");     // envia el salto de linea
   Putst_s ("Sucesos: ");   // envia el string
    Putst_s ("\n");     // envia el salto de linea

   Putst_s ("Veces en Alto Nivel: ");   // envia el string
   while(WR)continue;
   input = EEPROM_READ(0xD0);
    Putch_s (input);
   Putst_s ("\n");     // envia el salto de linea


   Putst_s ("Veces en Bajo Nivel: ");   // envia el string
   while(WR)continue;
   input = EEPROM_READ(0xD1);
    Putch_s (input);
   Putst_s ("\n");     // envia el salto de linea

mis dos problemas son:

1- Putch_s (input); con esto me sale efectivamente el ascii asociado y yo quiero que salga ff, ó 29 ó 1d, segun este esa posicion de memoria.

2- si quiero leer un rango de memoria ¿no podria usar un bucle for para ir leyendo el rango de eeprom?



muchas gracias, que esto empieza a coger color :-/
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 04 de Febrero de 2011, 10:34:47
  Por lo que veo estás usando las funciones Pust_s() y Putch_s. Pero creo que esas funciones estaban en una librería de manejo de RS232 por SoftWare y no en la de manejo de RS232 por HardWare. De ahí que tengan el guión bajo y la S al final.
  De todas maneras te dejo las nuevas versiones de ambas librerías...

RS232 por Soft

Código: C
  1. /**************************************************************************
  2. *    Libreria para emular puerto serie asincronico (UART) para HiTech     *
  3. ***************************************************************************
  4.  
  5. ***************************************************************************
  6. * Con clock de 4MHz la velocidad maxima de transmision es de 38400 Baud   *
  7. * Con clock de 8MHz en adelante la velocidad minima de transmision es de  *
  8. * 2400 Baud                                                               *
  9. ***************************************************************************
  10.  
  11. ***************************************************************************
  12. *                                                                         *
  13. * Antes de incluir este archivo en nuestro programa hay que definir       *
  14. * algunos parametros. Estos son                                           *
  15. *                                                                         *
  16. * PIC_CLK   (es necesario para los delay usados internamente)             *    
  17. *                                                                         *
  18. * TxPin     (puerto de salida)                                            *
  19. * RxPin     (puerto de entrada)                                           *
  20. * BaudRate  (velocidad de transferencia)                                  *
  21. *                                                                         *
  22. ***************************************************************************
  23.  
  24. ***************************************************************************
  25. *                                                                         *
  26. * Las rutinas de delay se encuentran en el archivo "delayhd.h"            *
  27. * El nombre original del archivo es:                                      *
  28. * "delay_alternative_enchanced_precision.h" y esta incluido dentro de     *
  29. * "PIC_Hi-Tech_C_delay_and_timeout_routines_for_PIC16xxxx_v7-1.zip"       *
  30. * Bajado de www.microchipc.com                                            *
  31. *                                                                         *
  32. * Hay que tener este archivo dentro de la carpeta de trabajo.             *
  33. *                                                                         *
  34. *  Si se quiere transmitir, el pin que se utilice como TX tiene que       *
  35. * configurarse como salida.                                               *
  36. *  Si se quiere recibir, el pin que se utilice como RX tiene que          *
  37. * configurarse como entrada.                                              *
  38. *                                                                         *
  39. ***************************************************************************
  40.  
  41. ***************************************************************************
  42. *                                                                         *
  43. * En esta libreria se encuentran las siguientes funciones                 *
  44. *                                                                         *
  45. * InitSoftUart()                (inicializa el puerto serie)              *
  46. * char getch_s()                (lee un byte del puerto serie)            *
  47. * putch_s(char)                 (envia un byte al puerto serie)           *
  48. * putst_s(char*)                (envia un string al puerto serie)         *
  49. * char * getst_s(char*)         (lee una cadena que termine con '\r')     *
  50. *                                                                         *
  51. *  El parametro de la funcion anterior puede ser un puntero a un String   *
  52. * o el propio String                                                      *
  53. *                                                                         *
  54. ***************************************************************************
  55.  
  56. * Ejemplo de configuracion y utilizacion
  57.  
  58.   #define PIC_CLK 10000000
  59.   #define TxPin RA0
  60.   #define RxPin RB1
  61.   #define BaudRate 9600
  62.  
  63.   #include "SoftUart.c"
  64.  
  65.   void main (void)
  66.   {
  67.     const char * pantalla = "Mundo";
  68.  
  69.     .....
  70.     .....
  71.     .....
  72.     TRISA0 = 0;
  73.     TRISB1 = 1;
  74.     InitSoftUart();
  75.     Putst_s ("Hola");   // envia el string "Hola" al puerto serie
  76.     Putst_s ("\n");     // envia el salto de linea al puerto serie
  77.     Putst_s (pantalla)  // envia el string apuntado por pantalla al puerto serie
  78.  
  79.   }
  80.  
  81. */
  82.  
  83.  
  84. #include "delayhd.h"   
  85.  
  86. #if defined (PIC_CLK) && defined (BaudRate) && defined (TxPin) && defined (RxPin)
  87.  
  88.   #if (PIC_CLK < 16000000)
  89.     #define BitDelay (1000000/BaudRate)
  90.     #define HalfBitDelay (500000/BaudRate)
  91.   #else
  92.     #define BitDelay (500000/BaudRate)
  93.     #define HalfBitDelay (250000/BaudRate)
  94.   #endif
  95.  
  96.   #if (PIC_CLK == 4000000)
  97.     #define DelayReceivebit DelayUs(BitDelay-7)\
  98.                                                         DelayUs(HalfBitDelay-7)
  99.     #if (BaudRate <= 19200)
  100.       #define DelayStartBit DelayUs(BitDelay-7)
  101.       #define DelaySendBit NDelayUs(BitDelay-18)
  102.     #elif (BaudRate == 28800)
  103.       #define DelayStartBit DelayUs(BitDelay-6)
  104.       #define DelaySendBit NDelayUs(BitDelay-18)
  105.     #elif (BaudRate == 38400)
  106.       #define DelayStartBit DelayUs(BitDelay-7)\
  107.                                                         dly2u
  108.       #define DelaySendBit DelayUs(BitDelay-19)\
  109.                                                    dly1u
  110.     #endif
  111.  
  112.   #elif (PIC_CLK == 8000000)
  113.     #define DelayReceivebit DelayUs(BitDelay-7)\
  114.                                                         DelayUs(HalfBitDelay-2)
  115.     #define DelayStartBit DelayUs(BitDelay-4)
  116.     #if (BaudRate <= 38400)
  117.       #define DelaySendBit NDelayUs(BitDelay-10)
  118.     #else         //(BaudRate == 57600)
  119.       #define DelaySendBit NDelayUs(BitDelay-9)
  120.         #endif
  121.  
  122.   #elif (PIC_CLK == 10000000)
  123.     #define DelayReceivebit DelayUs(BitDelay-7)\
  124.                                                         DelayUs(HalfBitDelay)
  125.     #if (BaudRate <= 38400)
  126.       #define DelayStartBit DelayUs(BitDelay-4)
  127.       #define DelaySendBit NDelayUs(BitDelay-8)
  128.     #else //(BaudRate == 57600)
  129.       #define DelayStartBit DelayUs(BitDelay-3)
  130.       #define DelaySendBit NDelayUs(BitDelay-7)
  131.         #endif
  132.  
  133.   #elif (PIC_CLK == 16000000) || (PIC_CLK == 20000000)
  134.     #if (PIC_CLK == 16000000)
  135.       #define DelayReceivebit DelayUs(BitDelay)\
  136.                                                           DelayUs(BitDelay)\
  137.                                                           DelayUs(BitDelay-5)
  138.     #else //(PIC_CLK == 20000000)
  139.       #define DelayReceivebit DelayUs(BitDelay)\
  140.                                                           DelayUs(BitDelay)\
  141.                                                           DelayUs(BitDelay-4)                                                          
  142.     #endif
  143.                
  144.         #if (BaudRate <= 38400)
  145.       #define DelayStartBit DelayUs(BitDelay)\
  146.                                                         DelayUs(BitDelay-2)
  147.       #define DelaySendBit NDelayUs(BitDelay)\
  148.                                                    NDelayUs(BitDelay-4)
  149.     #else //(BaudRate == 57600)
  150.       #define DelayStartBit DelayUs(BitDelay)\
  151.                                                         DelayUs(BitDelay-1)
  152.       #define DelaySendBit NDelayUs(BitDelay)\
  153.                                                    NDelayUs(BitDelay-3)
  154.     #endif
  155.   #endif
  156.  
  157. /*
  158. void InitSoftUart(void)
  159. {
  160.   TxPin = 1;
  161. }
  162. */
  163.  
  164.   #define InitSoftUart TxPin = 1
  165.  
  166.   unsigned char getch_s(void)
  167.   {
  168.     unsigned char contador = 7;
  169.     unsigned char letra = 0;
  170.  
  171.     DelayReceivebit;
  172.     do
  173.     {
  174.       if (RxPin == 1) letra += 128;
  175.       letra = letra >> 1;
  176.       contador--;
  177.       DelaySendBit;
  178.     }
  179.     while (contador > 0);
  180.     DelaySendBit;
  181.     return letra;
  182.   }
  183.  
  184.   void putch_s (unsigned char data)
  185.   {
  186.     unsigned char contador = 8;
  187.  
  188.     TxPin = 0;
  189.     DelayStartBit;
  190.     do
  191.     {
  192.       TxPin = data;
  193.       DelaySendBit;
  194.       data = data >> 1;
  195.       contador--;
  196.     }
  197.     while (contador > 0);
  198.     TxPin = 1;
  199.     DelayStartBit;   //tiempo de espera del bit de stop
  200.   }
  201.  
  202.   void putst_s (const char *word)
  203.   {
  204.     while (*word != 0)
  205.     {
  206.       putch_s(*word);
  207.       word++;
  208.     }
  209.   }
  210.  
  211.   char * getst_s (char * st)
  212.   {
  213.     char * st1;
  214.     char caracter;
  215.    
  216.     st1 = st;
  217.     do
  218.     {
  219.       caracter = getch();
  220.       if (caracter != '\r')
  221.       {
  222.         *st1 = getch_s();
  223.         st1++;
  224.       }
  225.       *st1 = '\0';
  226.     }
  227.     while (caracter != '\r');
  228.     return st;
  229.   }  
  230.  
  231. #else
  232.  #error Faltan definir parametros
  233. #endif

RS232 por Hard

Código: C
  1. /**************************************************************************
  2. *   Libreria para puerto serie (UART) PIC16xxx por HardWare para HiTech   *
  3. ***************************************************************************
  4.  
  5. ***************************************************************************
  6. *                                                                         *
  7. * Antes de incluir este archivo en nuestro programa hay que definir       *
  8. * algunos parametros. Estos son                                           *
  9. *                                                                         *
  10. * PIC_CLK        (se usa para calcular el valor de SPBRG)                 *    
  11. * BAUD           (velocidad de transferencia)                             *
  12. * BRGH_VALUE     (valor del bit BRGH)                                     *
  13. *                                                                         *
  14. * BRGH_VALUE solo puede tomar el valor 0 o 1                              *
  15. *                                                                         *
  16. ***************************************************************************
  17.  
  18. ***************************************************************************
  19. *                                                                         *
  20. * Si se quiere transmitir el puerto TX debe ser configurado como entrada  *
  21. * Si se quiere recivir el puerto RX debe ser configurado como entrada     *
  22. *                                                                         *
  23. ***************************************************************************
  24.  
  25. ***************************************************************************
  26. *                                                                         *
  27. * En esta libreria se encuentran las siguientes funciones                 *
  28. *                                                                         *
  29. * InitHardtUart(int)            (inicializa el puerto serie)              *
  30. * char getch()                  (lee un byte del puerto serie)            *
  31. * putch(char)                   (envia un byte al puerto serie)           *
  32. * putst(char*)                  (envia un string al puerto serie)         *
  33. * char * getst(char)            (lee una cadena que termina con \r)       *
  34. *                                                                         *
  35. *  El parametro de la funcion anterior puede ser un puntero a un String   *
  36. * o el propio String                                                      *
  37. *                                                                         *
  38. *  En esta libreria están definidos los parametros TRASMITE y RECEIVE.    *
  39. * Dichos parametros son los que se usan en la funcion InitHardtUart().    *
  40. *                                                                         *
  41. ***************************************************************************
  42.  
  43. * Ejemplo de configuracion y utilizacion
  44.  
  45.   #define PIC_CLK 10000000
  46.   #define BRGH_VALUE 1
  47.   #define BAUD 9600
  48.  
  49.   #include "HardUart16.c"
  50.  
  51.   void main (void)
  52.   {
  53.     const char * pantalla = "Mundo";
  54.  
  55.     .....
  56.     .....
  57.     .....
  58.     TRISC6 = 1;
  59.     TRISC7 = 1;
  60.     InitHardUart(TRASMITE || RECEIVE); // configuro para transmitir y recibir
  61.     putst ("Hola\n");   // envia el string "Hola" y el salto de linea al puerto serie
  62.     putst (pantalla);   // envia el string apuntado por pantalla al puerto serie
  63.     putst ("\n");       // envia el salto de linea al puerto serie
  64.   }
  65.  
  66. */
  67.  
  68. #if defined (BAUD) && defined (PIC_CLK) && defined (BRGH_VALUE)
  69.   #if (BRGH_VALUE == 1)
  70.     #define SPBRG_VALUE (PIC_CLK/(BAUD*16UL) -1)
  71.   #elif (BRGH_VALUE == 0)
  72.     #define SPBRG_VALUE (PIC_CLK/(BAUD*64UL) -1)
  73.   #endif
  74.  
  75.   #define TRANSMIT 0x8020
  76.   #define RECEIVE  0x9000
  77.  
  78.  
  79.   unsigned char dummy;
  80.  
  81.   #define InitHardUart(x) SPBRG = SPBRG_VALUE;\
  82.                           RCSTA = (x/256);\
  83.                           TXSTA = 0;\
  84.                           BRGH = BRGH_VALUE;\
  85.                           TXSTA |= (x & 0x00FF)\
  86.                    
  87.                          
  88.  
  89.   #define clear_error if (OERR)\
  90.                       {        \
  91.                         if (TXEN == 1)\
  92.                         {\
  93.                           TXEN=0;\
  94.                           TXEN=1;\
  95.                         }\
  96.                         if (CREN == 1)\
  97.                         {\
  98.                           CREN=0;\
  99.                           CREN=1;\
  100.                         }\
  101.                       }        \
  102.                       if (FERR)\
  103.                       {        \
  104.                         dummy = RCREG;\
  105.                         if (TXEN == 1)\
  106.                         {\
  107.                           TXEN=0;\
  108.                           TXEN=1;\
  109.                         }\
  110.                       }\
  111.  
  112.  
  113.   unsigned char getch (void)
  114.   {
  115.     while (RCIF != 1)
  116.     {
  117.        clear_error;
  118.        CLRWDT();
  119.     }
  120.     return RCREG;
  121.   }
  122.  
  123. /*
  124.   void InitHardUart (void)
  125.   {
  126.     SPBRG = SPBRG_VALUE;
  127.     RCSTA = 0b10010000;
  128.     TXSTA = 0;
  129.     BRGH = BRGH_VALUE;
  130.     TXEN = 1;
  131.   }
  132. */
  133.  
  134.   void putch (unsigned char DataOut)
  135.   {
  136.     while (TXIF != 1)
  137.     {
  138.       clear_error;
  139.       CLRWDT();
  140.     }
  141.     TXREG = DataOut;
  142.   }
  143.  
  144.   void putst (const char * Cadena)
  145.   {
  146.     while ((*Cadena) != 0)
  147.     {
  148.       putch (*Cadena);    
  149.       Cadena++;
  150.     }
  151.   }
  152.  
  153.   char * getst (char * st)
  154.   {
  155.     char * st1;
  156.     char caracter;
  157.    
  158.     st1 = st;
  159.     do
  160.     {
  161.       caracter = getch();
  162.       if (caracter != '\r')
  163.       {
  164.         *st1 = getch();
  165.         st1++;
  166.       }
  167.       *st1 = '\0';
  168.     }
  169.     while (caracter != '\r');
  170.     return st;
  171.   }
  172.  
  173. #else
  174.   #error Faltan definir parametros
  175. #endif

  Para ver el valor tal cual está y no el ASCII asociado, tendrías que pasar el valor decimal a ASCII y luego enviarlo, para ello tenés que hacer uso de la función itoa (IntegerToAscii), En el manual de HiTech te muestra como se la llama.

  Y sí, se puede usar un for par ir leyendo la eeprom.
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 07 de Febrero de 2011, 04:01:46
hola:

estamos con ello, pero:

¿que diferencia hay entre la rutina de manejo por sofware y por hardware. Comprendo que por sofware usamos cualquier patilla y por hardware usamos la uart del pic, pero ¿que ventajas tiene uno sobre el otro?


por otro lado, la funcion itoa pasa de integer a ascii, pero las posiciones de memoria eeprom son char, ¿cambio la variable a integer?


saludos y muchas gracias por todo tu aporte para que yo aprenda más...

Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 07 de Febrero de 2011, 04:32:25
hola de nuevo:

ahora tengo asi el programa (solo pongo lo relevante):

he incluido los includes como en el ejemplo:

#include <stdio.h>
#include <stdlib.h>

tambien he definido asi las variables:

unsigned char char_data[5]; //para rs232
unsigned int input;

y el codigo lo pongo asi:

void SEND_RS232(void)
   {
   InitSoftUart();
   __delay_ms(250);

   Putst_s ("Number of High Levels: ");   // envia el string
   while(WR)continue;
   input = EEPROM_READ(0xD0);
   itoa(char_data,input,16);
    Putch_s (char_data);
   Putst_s ("\n");     // envia el salto de linea


lo que me aparece en el hyperterminal, es algo pero no lo que debe pues en DO tengo un 55 (en ascii una U)

pero en el hyperteerminal aparece un 1 superindice.

Number of High Levels: ¹


eso me pasa con cualquier valor.


tampoco se que suncion tiene el parametro base en itoa...


saludos



Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 07 de Febrero de 2011, 04:38:08
ok, segun me estrujo, voy entendiendo:

el fallo es que seguia poniendo putch y hay que cambiar a putst porque ahora pasamos un string (que fallo).

voy pillanldo el tema.

ahora, todavia me falta entender para que sirve el paramentro base (yo pongo como en el ejemplo (16)).

y las diferencias entre las librerias de manejo por software y por hardware.


esto me gusta ya me sale lo que queria, al final, con tu ayuda voy a lograrlo (jeje), que alegria:

Number of High Levels: 55

biennnn!!!
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 07 de Febrero de 2011, 04:45:02
bueno, pues esto de leer un rango no me lo hace, algo pasa, pues en el hyperterminal, es como si nada...


for (i=0x00; i > 0x0F ; i++)
      {
      while(WR)continue;
      input = EEPROM_READ(i);
      itoa(char_data,input,16);
       Putst_s (char_data);
      Putst_s (" ");     // envia el salto de linea
      }

pretendo leer las posiciones de memoria desde la 0x00 hasta la 0x0f, o lo que es lo mismo desde la 0 a la 16 y plasmar su contenido, pero na de na...


gracias
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 07 de Febrero de 2011, 09:35:24
  Respondiendo a dudas anteriores... la diferencia entre las rutinas de RS232 por SoftWare y HardWare es que en el caso de las de SoftWare hace todo el programa, por lo tanto vas a quedar allí hasta que se terminen de transmitir todos los datos (y por supuesto ocupa mucha más memoria de programa). Si utilizas las de HardWare, lo único que hace el programa es ir llenando el registro TXREG. Como se lo está utilizando es casi lo mismo porque envías todo seguido, pero en el caso de usar por HardWare se podría usar interrupciones y llenar el TXREG sólo cuando éste esté vacío. Otra diferencia será que por HardWare se puede tener un rango más amplio de velocidades.

  En cuanto el parámetro base de la función itoa se usa para elegir el tipo de representación. Si usas base 10, sera representación decimal y si usas base 16 será Hexadecimal.

  En cuanto al bucle for, creo que está mal por como está puesto trabajaría mientras i sea mayor a 0x0F, pero el valor inicial de i es 0 por lo tanto nunca trabaja. Tendrías que ponerlo así.

Código: C
  1. for (i = 0x00; i < 0x0F; i++)
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 07 de Febrero de 2011, 10:00:30
COORECTO:

Corregido lo del for.

entendido lo de las diferencias.

no termino de entender lo del parametro base, pues si le cambio a 10, directamente se bloquea el programa...

segun lo tengo, pues bien, leo una posicion de memoria y me pone por ejemplo 11, claro es en haxadecimal, y sale 11 por el hyperterminal. pero si quisiera que en el hyperterminal en vez de 11 (que es hexadecimal), quiero que ponga 17, que es su valor en decimal, ¿que haria? poner el itoa en base 10, o habria primero (antes de convertir a string), que convertir de hexadecimal a decimal?.

ya se que me estoy poniendo pesao, pero quiero aprender a usar bien todas estas cosas.... y bastante quie me hechas unn cable y voy cogiendo...


por otro lado, si quiero ahora que el pic espere un comando, es simplemente esperar y leer??

saludos y como siempre gracias por tu paciencia y dedicacion.
 :-/
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 07 de Febrero de 2011, 10:36:46

no termino de entender lo del parametro base, pues si le cambio a 10, directamente se bloquea el programa...

segun lo tengo, pues bien, leo una posicion de memoria y me pone por ejemplo 11, claro es en haxadecimal, y sale 11 por el hyperterminal. pero si quisiera que en el hyperterminal en vez de 11 (que es hexadecimal), quiero que ponga 17, que es su valor en decimal, ¿que haria? poner el itoa en base 10, o habria primero (antes de convertir a string), que convertir de hexadecimal a decimal?.


  Basta con solo poner el itoa en base 10, para poder ver el valor en decimal. Así lo tengo en una prueba para un frecuencímetro

Código: C
  1. itoa (texto,Frecuencia,10);


por otro lado, si quiero ahora que el pic espere un comando, es simplemente esperar y leer??


  En teoría sí, es simplemente esperar y leer. Lógicamente hay varias formas distintas de implementar eso y todo dependerá de lo que quieras hacer en concreto.
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 07 de Febrero de 2011, 10:47:12
correcto:

no se que ocurriria, pero es cierto, al poner un 10, lo veo en hexadecimal...

muchas gracias.

la unica pega que veo es que al poner los datos en hexadecimal, los de dos cifras bien por ejemplo ff, pero los de 1 cifra por ejemplo 01, no me pone el 01 sino 1 solamente o en 0a solo me pone a, ¿hay foma de ajustarlo para que al volcarlo se vea un 01 0a, etc y no 1 a ...


con lo de recibir, pues podria, practicar en que el terminal se quede a la espera de un comando o letras y cuando el pic reciba ese comando, responda (por ejemplo , devolviendo el contenido de la eeprom).

en principio usare la libreria por software, pues esta comunicacion la hare solamente si entro especificamente a ese programita para ver la eeprom y como mucho si aprendo a dar algun comando.

el sentido de esto es que memorizo ciertas actividades de la aplicacion y despues poder saber cuantas veces ha ocurrido sin necesidad de programador...

un saludo
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 07 de Febrero de 2011, 11:49:01

la unica pega que veo es que al poner los datos en hexadecimal, los de dos cifras bien por ejemplo ff, pero los de 1 cifra por ejemplo 01, no me pone el 01 sino 1 solamente o en 0a solo me pone a, ¿hay foma de ajustarlo para que al volcarlo se vea un 01 0a, etc y no 1 a ...


  Y... quizá se podría implementar algo asi...

Código: C
  1. if (input <= 0x0f) Putch_s ('0'); //input seria lo que se lee de la eeprom
  2. //con la linea anterior se envia el 0 antes del valor leido siempre y cuando el mismo sea menor o igual a 0x0f
  3. Putst_s (char_data);


con lo de recibir, pues podria, practicar en que el terminal se quede a la espera de un comando o letras y cuando el pic reciba ese comando, responda (por ejemplo , devolviendo el contenido de la eeprom).

en principio usare la libreria por software, pues esta comunicacion la hare solamente si entro especificamente a ese programita para ver la eeprom y como mucho si aprendo a dar algun comando.

el sentido de esto es que memorizo ciertas actividades de la aplicacion y despues poder saber cuantas veces ha ocurrido sin necesidad de programador...

un saludo


  Entiendo lo que quieres hacer con esperar a un comando, pero mi comentario iba por ejemplo a que te podías quedar esperando en un loop infinito (y no hacer otra cosa) u organizar un loop infinito pero pudiendo hacer otras cosas o implementar la lectura de lo recibido vía interrupciones. Por éso decía yo que hay varias formas para implementarlo.

  En cuanto a la memorización de ciertas actividades de la aplicación, ten en cuenta que tienes un limitado número de veces el cual puedes grabar la eeprom. Eso está especificado en el datasheet. Tal vez sea más conveniente usar una eeprom externa (tipo 24Cxxx) y en el caso de que no sirva más simplemente cambias de memoria y listo.
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 08 de Febrero de 2011, 04:03:39
el codigo de poner el cero, probado y correcto.

sobre la eeprom, pues tienes razon, pero, esos sucesos nunca llegaran al numero que se permite, por lo que en principio no impoorta mucho. ademas, casi por precio (depende del pic), cambias el pic entero... (quien sabe).

sobre el comando de recibir, pues tengo una duda, pues solo veo en la libreria un comando para recibir un caracter, Getch(), y veo que no tiene parametro, entonces yo pongo:

Getch_s();

y despues que variable es la que comparo, ¿quizás la interna "letra"?. Pues imagino que tendré que comparar lo que entra con un caracter (no se si se puede hacer con un comando como el retorno de carro), o incluso, con varias letras, por ejemplo, hacer algo cuando en el hyperterminal escribes read con retorno de carro...

saludos.
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 08 de Febrero de 2011, 09:39:02
ok.

he probado de esta forma:

bb:
input=Getch_s();
   if (input == 0x0D)
        {
        .......
        lo que quiero hacer
        .......
        }
else
{ goto a bb;}


pero resulta que funciona, pero cuando le doy al intro unas veces obedece y otras no. no se si es porque tarda en llegar a leer o por otra cosa.

en fin mas o menos voy viendo....


saludos
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 08 de Febrero de 2011, 09:43:15
el codigo de poner el cero, probado y correcto.

sobre la eeprom, pues tienes razon, pero, esos sucesos nunca llegaran al numero que se permite, por lo que en principio no impoorta mucho. ademas, casi por precio (depende del pic), cambias el pic entero... (quien sabe).


  Ah, bueno. En ese caso si que no conviene meter otro integrado.

sobre el comando de recibir, pues tengo una duda, pues solo veo en la libreria un comando para recibir un caracter, Getch(), y veo que no tiene parametro, entonces yo pongo:

Getch_s();

y despues que variable es la que comparo, ¿quizás la interna "letra"?. Pues imagino que tendré que comparar lo que entra con un caracter (no se si se puede hacer con un comando como el retorno de carro), o incluso, con varias letras, por ejemplo, hacer algo cuando en el hyperterminal escribes read con retorno de carro...

saludos.


  getch_s() es una función que devuelve un char, por lo tanto para leer el comando tendrías que hacer esto

Código: C
  1. variable = Getch_s();


  El problema de hacerlo así es que te quedás esperando si o si a que se presione una tecla, o sea que no podés hacer otra cosa hasta no salir de allí.

  Justo que estaba escribiendo apareció tu respuesta.

  Ojo! que Getch_s() es para leer un solo caracter, por lo tanto si sólo te interesa el "enter" tenés que asegurarte de no presionar ninguna otra tecla. Sino te va a tomar dicha tecla y obviamente no va a hacer nada porque tu if evalua el caracter del "enter"
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 08 de Febrero de 2011, 09:48:58
EL UNICO PROBLEMA QUE VEO ES LA TARDANZA, QUE AUNQUE ESTE CONTINUAMENTE LEYENDO, RESULTA QUE NO OBEDECE A LA PRIMERA....


YA IMAGINO QUE SI QUIERES HACER COSAS MIENTRAS HABRA QUE USAR COMUNICACION POR HARD ¿VERDAD?.

Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 08 de Febrero de 2011, 12:31:46
  Le estoy prestando más atención a mi rutina de getch_s() y veo que en realidad no espera a que llegue un caracter, o sea que si la ejecutás cuando no envías nada puede generar fallos.
Tal vez se solucione haciendo algo así...

Código: C
  1. if (pinRX == 0) variable = Getch_s();

  Siendo pinRX el pin que quieras usar como RX y variable la variable donde quieras almacenar lo leído.

  Hago ese testeo para saber si el pin se pone en 0, porque por el protocolo el pin TX del transmisor está siempre en 1 y cuando se pone a 0 se lo toma como el inicio de la transmisión.
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 08 de Febrero de 2011, 13:06:27
he colocado esta linea, y da resultado, incluso, ya me lee más rápido.... :D

gb:   if (RC7 == 0) {input = Getch_s();}else{goto gb;}

y despues segun el caracter, actuo...



nota: me quedaria estudiar la libreria mas a fondo y averiguar para introducir ese cambio directamente en la libreria. y por otra parte, descubir como recibir una cadena. pero me doy por satisfecho por el momento, porque gracias a ti, he aprendido a nejar un lcd y el rs232, en esta semana...


gracias....

 :-/
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 08 de Febrero de 2011, 13:50:30
he colocado esta linea, y da resultado, incluso, ya me lee más rápido.... :D

gb:   if (RC7 == 0) {input = Getch_s();}else{goto gb;}

y despues segun el caracter, actuo...


  No son muy elegantes las estructuras con goto, en lugar de ello tenés las estructuras while y do-while. El ejemplo que mostrás arriba, hecho con while quedaría...

Código: C
  1. while (1) // loop infinito
  2. {
  3.   if (RC7 == 0) input = Getch_s(); // si es una sola linea no son necesarias las llaves ( { } ) para determinar el bloque
  4. }

nota: me quedaria estudiar la libreria mas a fondo y averiguar para introducir ese cambio directamente en la libreria. y por otra parte, descubir como recibir una cadena. pero me doy por satisfecho por el momento, porque gracias a ti, he aprendido a nejar un lcd y el rs232, en esta semana...


  El cambio lo tendrías que introducir en la función getch_s(); Esta es la implementación de dicha función sin el cambio

Código: C
  1. unsigned char getch_s(void)
  2.   {
  3.     unsigned char contador = 7;
  4.     unsigned char letra = 0;
  5.  
  6.     DelayReceivebit;
  7.     do
  8.     {
  9.       if (RxPin == 1) letra += 128;
  10.       letra = letra >> 1;
  11.       contador--;
  12.       DelaySendBit;
  13.     }
  14.     while (contador > 0);
  15.     DelaySendBit;
  16.     return letra;
  17.   }

  Y creo que el cambio podría ser poner lo siguiente justo después de declarar las variables y justo antes de la línea "DelayReceivebit;"

Código: C
  1. while (RxPin == 1); // mientras que el pin este en 1 no hago nada y me quedo esperando

  Con dicho cambio, la función getch_s() quedaría a la espera que llegue un caracter,

  Por otra parte en la última versión que subí de la librería existe la función getst_s(), que justamente recibe una cadena de caracteres que termine con "CarrierResturn" que sería el caracter correspondiente al enter
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: LAFUMAT en 09 de Febrero de 2011, 03:04:55
ok, me apunto los cambios y creo que ya es suficiente. si mas adelante surjen cosas las preguntaré.

ahora voy a asimilar todo esto.

y seguro que mirare otras librerias, par ir aprendiendo....

se admiten sugerencias...

Pero megustria aprender a manejar los TIMERs, hacer un reloj en tiempo real (que hay cosas que no entiendo)...

pero no se en  que hilo encuadrarlas para que quede claro que es para el hitech y pic16, pues creo yo que los que trabajamos con pic16 nos tienen un poco abandonados...


saludos y muchas gracias
Título: Re: pasar datos de eeprom a hyperterminal con hitech
Publicado por: AngelGris en 09 de Febrero de 2011, 09:20:13

Pero megustria aprender a manejar los TIMERs, hacer un reloj en tiempo real (que hay cosas que no entiendo)...

pero no se en  que hilo encuadrarlas para que quede claro que es para el hitech y pic16, pues creo yo que los que trabajamos con pic16 nos tienen un poco abandonados...


  En C es muy difícil que puedas hacer un reloj en tiempo real con los TIMERs del PIC, ya que uno no tiene un control preciso del tiempo que tarda cada instrucción. Si lo hicieras en ASM seguramente se podría llegar a algo razonable.

  Básicamente el uso de los TIMERs es similar tanto para PIC16 como para PIC18, hay un hilo de ejemplos para PIC16F648 que quizá tenga lo que estás buscando.