Autor Tema: Comienzo en C  (Leído 17353 veces)

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

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #60 en: 20 de Junio de 2012, 01:32:30 »
Hola Macedo:
                 tenés que diferenciar lo que es una cadena de texto almacenada en un array de un simple array de caracteres.
Una cadena de texto es una secuencia de caracteres cuyo último carácter es '\0' el cual indica el final de la misma.
Un ejemplo de cadena es: "*Init. Cilindro*" // fijate que saqué el \0 que le habías puesto vos porque el compilador lo agrega automáticamente al final porque estamos usando comillas dobles.
¿que tamaño deberá tener el array para almacenar "*Init. Cilindro*"?
ojo que la catindad no es 16, sino 17.

Debemos almacenar los caracteres:  '*' 'I' 'n' 'i'  't'  '.'   ' '   'C'  'i'  'l'   'i'  'n'  'd'  'r'  'o'  '*' y el final de cadena '\0'  
                                                      1   2  3  4   5  6    7     8   9  10 11 12  13 14  15  16                               17

Fijate que usé comillas simples para indicarte los caracteres.
Cuando querés indicar un único caracter debés hacerlo entre comillas simples.
Si escribís "a" no le estás indicando al compilador sólo la letra 'a' sino la 'a' más el '\0'

Si entendiste lo que te expliqué más arriba estarás en condiciones de responderme que tamaño tendrá y que se almacenará en el siguiente array:

char my_array="";

¿y en este otro?
char my_array=" ";


cuando declarás un array así:
char texto[] = “Hola”; // el compilador reserva la cantidad de caracteres para hola más el \0, es decir 5

también podrías crearlo así:
char texto[5] = “Hola”;

Lo que no podés hacer es declarar el array y luego pretender cargarle valores con el operador de asignación =

por ejemplo:

char texto[5];
texto="hola"  // ERROR!!

Para cargarle al array la palabra "hola" luego de crearlo debés asignar elemento por elemento, así:

char texto[5];
texto[0]='h';
texto[1]='o';
texto[2]='l';
texto[3]='a';
texto[4]='\0'

El ejemplo que te transcribo aquí abajo ya no es una cadena de caracteres sino un simple array de caracteres.
char my_array [5] = {'a','b','c','d','e'}; array de caracteres. // no se agrega el \0 al final

El tutorial oficial de Suky  ((:-)) es uno solo y está en este link http://www.micros-designs.com.ar/tutorial-mplab-c18/

En respuesta al tema de guardar datos en rom, debés hacer así.

#pragma romdata seccionAbcdario
const rom char letras[]={' ','A','B','C','D','E','F',
                   'G','H','I','J','K','L',
                   'M','N','O','P','Q','R',
                   'S','T','U','V','W','X',
                             'Y','Z'};
#pragma romdata

En cuanto al problema del lcd nokia no puedo ayudarte porque nunca hice nada con el. Pero imagino que debe ser similar a los glcd. Suky hizo un tutorial aquí: http://www.micros-designs.com.ar/libreria-glcd-128x64-c/


Con relación a este Warning [2054] suspicious pointer conversion no es un error, solo es un warning, y  te lo debe estar dando porque le estás pasando a la función  LCDMsnj(unsigned char x,unsigned char y, const unsigned char *dataPtr) un dato como parámetro distinto del que está definido en la función.
const unsigned char   y const rom char. Es decir no es ni rom ni unsigned.


Para entender el tema punteros te recomiendo leas los tutoriales que están acá. http://www.ucontrol.com.ar/forosmf/programacion-en-c/tutorial-sobre-punteros-en-c-ansi/

« Última modificación: 20 de Junio de 2012, 01:35:23 por jukinch »
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #61 en: 20 de Junio de 2012, 13:56:52 »
Gracias jukinch por tomarte el tiempo y enseñarme, bueno esto explica porque veia ejemplos con el caracter final o no"\0":
Citar
Un ejemplo de cadena es: "*Init. Cilindro*" // fijate que saqué el \0 que le habías puesto vos porque el compilador lo agrega automáticamente al final porque estamos usando comillas dobles.

char my_array="";    Tiene un tamaño de un caracter el "\0" solamente

char my_array=" ";   Tienen un largo de dos caracteres el espacio y el "\0"

Este ejemplo
Citar
El ejemplo que te transcribo aquí abajo ya no es una cadena de caracteres sino un simple array de caracteres.
char my_array [5] = {'a','b','c','d','e'}; array de caracteres. // no se agrega el \0 al final

Los array de caracteres empiezan y terminan con {}? y las de cadena de caracteres?
Mira este ejemplo.
Código: C
  1. unsigned char Menu[MENU_NUMB][16] = {
  2.  "Test LEDS 12345 \0",
  3.  "Test IGT SAS  \0",
  4.  "Test CARBONERA  \0",
  5.  "Test macedo   \0",
  6.  "Test MMA      \0",
  7.  "Test Joystick \0"
  8. };
MENU_NUMB indica la cantidad de valores que contiene y el 16 el largo, pero empieza  y termina con {} y esto tiene algún limite?
Los arrays se guardan en ROM o RAM?

Con respecto a esto:
Citar
#pragma romdata seccionAbcdario
const rom char letras[]={' ','A','B','C','D','E','F',
                   'G','H','I','J','K','L',
                   'M','N','O','P','Q','R',
                   'S','T','U','V','W','X',
                             'Y','Z'};
#pragma romdata
Es semejante a hacer "org 0x200" y escribir mi tabla en ASM?
Le debo decir al programa donde empieza Abcdario y donde termina?

Como llamo al valor en este array, así:  Abcdario[2], que seria la letra"A".

Gracias y estoy viendo los tutoriales muy buen trabajo el de suky, sin desmerecer el tuyo.
Saludos





Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #62 en: 20 de Junio de 2012, 23:22:50 »
char my_array="";    Tiene un tamaño de un caracter el "\0" solamente

char my_array=" ";   Tienen un largo de dos caracteres el espacio y el "\0"

10 puntos Macedo.  :-/


Los array de caracteres empiezan y terminan con {}? y las de cadena de caracteres?

Un array de caracteres puede ser también una cadena. Lo que hace que sea cadena es el \0 del final. Es sólo una cuestión de nombres y convenciones.

Podés usar las dos formas para cargar un array,
                      con comillas dobles
                   y con llaves y comillas simples.

Pero con comillas dobles siempre tendrás un \0 al final. Y no sería un array de caracteres por el \0.
Lo importante es que sepas que con " " tenés un \0 y con {' ',' '} vos elegís si está o no está el \0.

char palabra[5] = {‘H’, ‘o’, ‘l’, ‘a’, ‘\0’}; // acá podés elegir si querés un \0 al final o no porque lo ponés vos.
char palabra[5] = “Hola”; //  // acá siempre tendrás un \0 al final.

mirá este tutorial: http://wikipnfi.wikispaces.com/file/view/Cadenas.pdf

En el caso de [MENU_NUMB][16] tenés un array multidimensional. Es una matriz de dos dimensiones.
MENU_NUMB debe estar definido en tu código en algún lado con un #define así:

#define MENU_NUMB 6

entonces te queda una matriz de 6*16

Una de las cosas que siempre confunde es que los arrays se definen de un tamaño n pero luego el índice para llamar a un elemento del array arranca desde 0. Es decir que el índice es siempre n-1;

en este ejemplo lo vas a ver claro:

char letra;
char palabra[5] = {‘H’, ‘o’, ‘l’, ‘a’, ‘\0’};

para acceder a la letra 'H' debo indicar indice 0
letra=palabra[0];
para acceder a la letra 'a' debo indicar indice 3
letra=palabra[3];


Es semejante a hacer "org 0x200" y escribir mi tabla en ASM?
Le debo decir al programa donde empieza Abcdario y donde termina?
De asm ni la más mínima idea. Ya me pasarás algún par de trucos para hacer un blink led  :-/.


Como llamo al valor en este array, así:  Abcdario[2], que seria la letra"A".
Abcdario[2] sería la letra b  acordate que arranca en 0 el índice. :)

Los arrays se guardan en ROM o RAM?
Podés cargarlo tanto en rom como en ram. Para ello debés usar los modificadores rom y ram. (página 21-24 del tutorial de Suky) y la directiva pragma romdata

#pragma romdata array_en_rom
const rom int myarray[10];
#pragma romdata

mirá también este link http://www.forosdeelectronica.com/f24/acceso-memoria-pic-c18-13884/

te paso otro link interesante con faqs. http://www.xargs.com/pic/c-faq.html#c18absolute  
                Saludos.
                        Jukinch

« Última modificación: 21 de Junio de 2012, 00:13:18 por jukinch »
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #63 en: 21 de Junio de 2012, 10:22:04 »
GRACIAS MAESTRO! (((:-)))

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #64 en: 22 de Junio de 2012, 09:16:55 »
Hola estuvi leyendo y aplicando lo que me dijiste, pero encontre algo que no me cierra, hize esto:
Código: C
  1. #pragma romdata array_temps=0x400
  2. const rom unsigned char mnsj2[]={"*Init. ale*\0"};
  3. const rom char mnsj3[]="Tipo Cilindro:\0";
  4. const rom char mnsj4[]="Distribucion :\0";
  5. #pragma romdata
  6.  
  7. unsigned char *men1;
  8. extern unsigned char mnsj2[];            // esta en otro archivo
  9.  
  10.  
  11.  
  12. void main(void) {
  13.  
  14.              men1=mnsj2;                // tiene que estar dentro de la funcion que lo llama o no?
  15.              LCDMsnj (0, 2, men1);   // escribo en el lcd
  16.  
  17.                         while(1)       
  18.                                 {
  19. ....
  20. ....
  21. ....
  22. }
Pero no sale nada en el LCD y el compilador no muestra error al compilar.
Otra forma es:
Código: C
  1. ]#pragma romdata array_temps=0x400
  2.  unsigned char mnsj2[]={"*Init. ale*\0"};
  3. const rom char mnsj3[]="Tipo Cilindro:\0";
  4. const rom char mnsj4[]="Distribucion :\0";
  5. #pragma romdata
Asi si muestra el mensaje en el LCD, siempre con mnsj2.
La rutina de envío, LCDMnsj esta descrita mas arriba.
Por que lo hace si me dijiste que colocara con "const rom" y no funciona.
Saludos



Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #65 en: 22 de Junio de 2012, 09:35:45 »
Macedo: subí el código de la función LCDMsnj así veo que debe recibir. Y los warnings que debés estar recibiendo.

¿Porque agregás el \0 acá?: {"*Init. ale*\0"}; El texto entre comillas dobles ya te lo genera.

para copiar el contenido de un array a otro deberás usar una función, dependiendo de donde estén guardados, si en ROM o en RAM, deberás usar:
strcpy
strcpypgm
strcpypgm2ram
strcpyram2pgm
página DS51297F-page 126 del manual de librerias de c18.



mirá este link http://www.microchip.com/forums/m218767-print.aspx
y este otro http://www.programatium.com/manuales/c/18.htm
aquí tutorial de cadenas:
http://www.todopic.com.ar/foros/index.php?topic=25785

« Última modificación: 22 de Junio de 2012, 09:42:34 por jukinch »
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #66 en: 22 de Junio de 2012, 12:10:38 »
Hola es raro para mi lo que hace, te comento que sigo probando tratando de descubrir el problema, te paso los cod.
Código: C
  1. unsigned char My_Msnj[6][20] = {
  2. "*Init. ale*",
  3. "Tipo Cilindro:",
  4. "Distribucion :",
  5. "00 38",
  6. "* En Juego... *",
  7. "Win :--"
  8. };
  9.  
  10. unsigned char Inversion [] ={0,0,0,0,0,0};      // usado por UpdateMenu
  11. unsigned char offset=0, menu_flag=0;            // usado en UpdateMenu
  12. unsigned char MenuPos=0;                          // usado en UpdateMenu
  13.  
  14.  
  15. void LCDMsnj(unsigned char x,unsigned char y, const unsigned char *dataPtr) {
  16.  
  17.    rom unsigned char ** near_rom_ptr;
  18.    *near_rom_ptr=FontLookup[0];
  19.  
  20.    LCDSend(0x80|x, SEND_CMD );
  21.    LCDSend(0x40|y, SEND_CMD );
  22.  
  23.    while ( *dataPtr )                                   // loop to the end of string
  24.  {                    
  25.   for(k=0; k<6; k++)                                    // k<5
  26.       LCDSend(FontLookup[*dataPtr - 32][k], SEND_CHR);  //near_rom_ptr
  27.    
  28.       dataPtr++;
  29. //    LCDSend (0x00,SEND_CHR);                          // Espacio entre caracteres.
  30.   }
  31. }
  32.  
  33. void LCDStr(unsigned char row, const unsigned char *dataPtr, unsigned char inv ) {
  34.  
  35.   unsigned char x = 0;                    // variable for X coordinate
  36.  
  37.   while ( *dataPtr )                      // loop to the and of string
  38.           {
  39.     if(inv)
  40.                 LCDChrXY(0,row,'*');
  41.         if(inv)
  42.             {
  43.                 LCDChrXY( x+5, row, (*dataPtr));
  44.       //LCDChrXYInverse(x, row, (*dataPtr));
  45.       }
  46.     else
  47.             {
  48.       LCDChrXY( x, row, (*dataPtr));
  49.       }
  50.     x=x+6;      // x++;
  51.     dataPtr++;
  52.   }
  53. }  
  54.  
  55. void UpdateMenu(unsigned char pos) {
  56.  
  57.   Inversion[pos-1] = 1;
  58.  
  59.   Inversion[pos-1] = 1;
  60.  
  61.   LCDUpdate();
  62.   LCDClear();
  63.   LCDStr ( 0, My_Msnj[0+offset], Inversion[0]);
  64.   LCDStr ( 1, My_Msnj[1+offset], Inversion[1]);
  65.   LCDStr ( 2, My_Msnj[2+offset], Inversion[2]);
  66.   LCDStr ( 3, My_Msnj[3+offset], Inversion[3]);
  67.   LCDStr ( 4, My_Msnj[4+offset], Inversion[4]);
  68.   LCDStr ( 5, My_Msnj[5+offset], Inversion[5]);
  69.   Delay(65000);
  70. //  LCDUpdate();
  71.   Inversion[pos-1] = 0;
  72. };
Esto esta en un archivo LCD.c

Te comento que al llamar las funciones en main.c
Código: C
  1. LCDMsnj (0, 2, My_Msnj[1]);
  2.               LCDStr (0, My_Msnj[1], Inversion[0]);
Me dan "Warning [2054] suspicious pointer conversion", pero la funcion:
Código: C
  1. UpdateMenu(MenuPos);
No!, y si te fijas es igual a la que hize para probar:
Código: C
  1. LCDStr (0, My_Msnj[1], Inversion[1]);
Esta función me muestra la primer linea del mensaje en la LCD si a My_Msnj le quito [] y no me tira el error. Una esta en LCD.c y la otra que da error en main.c
La verdad que cada vez que te pregunto salgo con algo mas complicado, me debes querer matar.
Voy a revisar lo que me mandastes.
Saludos



Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #67 en: 23 de Junio de 2012, 13:45:21 »
Bueno resumo lo anterior:
Tengo mi arreglo multidimensional en el archivo LCD.c:
Código: C
  1. unsigned char My_Msnj[6][20] = {
  2. "Primera Linea",
  3. "Segunda Linea",
  4. "Tercera Linea",
  5. "Cuarta Linea",
  6. "Quinta Linea",
  7. "Sexta Linea"
  8. };

y mis dos funciones:
En el archivo main.c:
Código: C
  1. LCDMsnj (0, 2, My_Msnj[1]);

Y en el archivo lcd.c:
Código: C
  1. UpdateMenu(MenuPos);

La cosa es así, si yo lllamo a UpdateMenu(0), en lcd.c, me muestra todo el arreglo en la lcd perfecto, y si yo llamo a LCDMsnj (0, 2, My_Msnj[1]), en main.c, no muestra nada y debería mostrarme "Segunda Linea", cabe aclarar que para que me muestre algo debo quitarle el indice a My_Msnj asi:
Código: C
  1. LCDMsnj (0, 2, My_Msnj);
Y me muestra solamente "Primera Linea".

Si yo cambio de archivo a mi arreglo, o sea pasarlo de lcd.c a main.c y viceversa dependiendo en que archivo este la función funciona que este en el mismo archivo funcionara perfecto, si mi arreglo esta en main.c la función LCDMsnj (0, 2, My_Msnj[1])
funciona perfecto y UpdateMenu(0) NO, y viceversa.

Otra cosa que vi tambien acompañado de este cambio de archivo de mi arreglo es que la funcion que no este en el mismo que mi arreglo debo castearla, asi:
Código: C
  1. LCDMsnj (0, 2, (unsigned char*) My_Msnj[0]);

Para que no me salga: Warning [2054] suspicious pointer conversion.
y si se fijan mi arreglo es unsigned char, espero haberlo puesto bien.
Esto es lo que me detiene por el momento  :5]
Espero que puedan entender lo que me pasa y me digan donde me equivoco, ya leí los ejemplos creo que el arreglo esta bien pero no veo aun el error.
Saludos

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #68 en: 23 de Junio de 2012, 15:30:05 »
Macedo. Cuando haces uso de un array multidimensional tenés que indicar los dos indices.

My_Msnj[0][0] para la primera línea.
 My_Msnj[1][0] para la segunda

My_Msnj[2][0] para la tercera

Etc.

Y ojo que so lo pones así suelto:
  My_Msnj es un puntero.
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #69 en: 23 de Junio de 2012, 15:38:47 »
Ya lo había probado pero me tira el error:
Error [1129] [] operator requires a pointer and an integer as operands
Saludos

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #70 en: 23 de Junio de 2012, 18:54:01 »
Macedo:
          Vamos a tener que ver estos temas para poder entender como solucionar el problema.
             Punteros,
             Aritmética de punteros,
             Arrays bidimensionales y punteros,
             Como hacer para pasarle un array multidimensional a una función.-

         Tené presente que cuando invocás la función LCDMsnj el compilador no copia todo el array a la función.
Solo podés pasar un puntero y eso es lo que debe hacer tu código.

           En tu código el puntero dataPtr, sirve para recorrer tu matriz de 6 bytes*20 bytes = 120 bytes.
Esos 120 bytes son consecutivos, ya que la función no lo toma como un array, ni unidimensional ni bidimensional. Solo los ve como bytes consecutivos.

probá así:
 LCDMsnj (0, 2, (My_Msnj+20));

Si mis cálculos no me fallan deberían mostrarte la segunda línea.

Subí si podés el proyecto completo zipeado así podemos probar compilarlo.


Mirá esta página que te había comentado.
http://www.xargs.com/pic/c-faq.html#twodarray

Código: C
  1. How can I pass a pointer to a two-dimensional array to a function, or declare a pointer to a two-dimensional array?
  2.  
  3. With a two-dimensional array, the compiler needs to know how many elements are in a column to move from one row to the next, but movement within a row is always by a single element, so the compiler doesn't need to know the number of rows. Thus the pointer declaration must include the number of columns in the array:
  4.  
  5. char array[2][3] = { "19", "42" };
  6.  
  7. void func(char (*ptr)[3])
  8. {
  9.   puts(ptr[1]);      // prints "42"
  10. }
  11.  
  12. func(array);
  13.  
  14. /* or */
  15.  
  16. char (*ptr)[3];
  17. ptr = array;


Si vos tenés un array:         char array[6][20];

Un puntero al primer elemento de la segunda fila sería:

char *ptr;
ptr = &array[1][0];


Luego podés incrementar el puntero para ir avanzando a los elementos subsiguientes de ese renglón.

No se como te manejás con el tema de los punteros. Parecen un cuco pero no lo son. Pero si hay que dedicarles su tiempo y práctica.-

podés ver este link:
http://www.monografias.com/trabajos38/manual-programacion/manual-programacion-c4.shtml
allí buscá Punteros y Arreglos.

aquí también tenés más info sobre el tema de los arrays:
http://www.microchip.com/forums/m161017-print.aspx
http://www.microchip.com/forums/m145824-print.aspx
http://www.microchip.com/forums/m573688.aspx
http://www.todopic.com.ar/foros/index.php?topic=12926.0

Te recomiendo leas este hilo también:
http://www.todopic.com.ar/foros/index.php?topic=27462

Encontré este video en inglés pero muy copado.
Agrego otro más sobre cadenas y punteros.

              Saludos.
                    Jukinch

Modifique: el 6 por el 20
LCDMsnj (0, 2, (My_Msnj+20));

Modifiqué. agregué otro video más.

modifiqué: lo tachado. ya que mis cálculos me fallaron. jijiji :)

« Última modificación: 24 de Junio de 2012, 04:32:25 por jukinch »
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #71 en: 24 de Junio de 2012, 04:38:47 »
Macedo:
          Hice este código en c y lo compilé con devc++ para hacer pruebas y pude acceder a los elementos del array multidimensional. Pero no como te había indicado. Por eso modifiqué el post anterior tachando lo que creo que no va antes de generar más confusión.  :-)
          Habría que adaptarlo a tu proyecto y probar.
                Saludos.
                        Jukinch
Código: C
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5. // ---------------------------------------------------------------------------
  6. // ejemplo de arrays unidimensionales y bidimensionales y uso de punteros
  7.  
  8. unsigned char miCadena[10] = "JUKINCH";
  9.  
  10. unsigned char My_Msnj[6][20] = {"Primera Linea",
  11.                                 "Segunda Linea",
  12.                                 "Tercera Linea",
  13.                                 "Cuarta Linea",
  14.                                 "Quinta Linea",
  15.                                 "Sexta Linea"
  16.                                 };
  17.  
  18.  
  19.  
  20. printf("%c\n",*(miCadena+0)); // J
  21. printf("%c\n",*(miCadena+1)); // U
  22. printf("%c\n",*(miCadena+2)); // K
  23. printf("%c\n",*(miCadena+3)); // I
  24. printf("%c\n",*(miCadena+4)); // N
  25. printf("%c\n",*(miCadena+5)); // C
  26. printf("%c\n",*(miCadena+6)); // H
  27. printf("\n");
  28. printf("%s\n",miCadena); // JUKINCH
  29. printf("\n");
  30.  
  31. printf("%c \n",*(My_Msnj[0]+0)); // P
  32. printf("%c \n",*(My_Msnj[0]+1)); // r
  33. printf("%c \n",*(My_Msnj[0]+2)); // i
  34. printf("%c \n",*(My_Msnj[0]+3)); // m
  35. printf("%c \n",*(My_Msnj[0]+4)); // e
  36. printf("%c \n",*(My_Msnj[0]+5)); // r
  37. printf("%c \n",*(My_Msnj[0]+6)); // a
  38. printf("\n");
  39.  
  40. printf("%c \n",*(My_Msnj[1]+0)); // S
  41. printf("%c \n",*(My_Msnj[1]+1)); // e
  42. printf("%c \n",*(My_Msnj[1]+2)); // g
  43. printf("%c \n",*(My_Msnj[1]+3)); // u
  44. printf("%c \n",*(My_Msnj[1]+4)); // n
  45. printf("%c \n",*(My_Msnj[1]+5)); // d
  46. printf("%c \n",*(My_Msnj[1]+6)); // a
  47. printf("\n");
  48. printf("%c \n",*(*(My_Msnj+0)+0)); // P
  49. printf("%c \n",*(*(My_Msnj+0)+1)); // r
  50. printf("%c \n",*(*(My_Msnj+0)+2)); // i
  51. printf("%c \n",*(*(My_Msnj+0)+3)); // m
  52. printf("%c \n",*(*(My_Msnj+0)+4)); // e
  53. printf("%c \n",*(*(My_Msnj+0)+5)); // r
  54. printf("%c \n",*(*(My_Msnj+0)+6)); // a
  55. printf("\n");
  56. printf("%c \n",*(*(My_Msnj+1)+0)); // S   EQUIVALENTE printf("%c \n",**(My_Msnj+1)); // S
  57. printf("%c \n",*(*(My_Msnj+1)+1)); // e
  58. printf("%c \n",*(*(My_Msnj+1)+2)); // g
  59. printf("%c \n",*(*(My_Msnj+1)+3)); // u
  60. printf("%c \n",*(*(My_Msnj+1)+4)); // n
  61. printf("%c \n",*(*(My_Msnj+1)+5)); // d
  62. printf("%c \n",*(*(My_Msnj+1)+6)); // a
  63. printf("\n");
  64. printf("%c \n",*(*(My_Msnj+2)+0)); // T
  65. printf("%c \n",*(*(My_Msnj+2)+1)); // e
  66. printf("%c \n",*(*(My_Msnj+2)+2)); // r
  67. printf("%c \n",*(*(My_Msnj+2)+3)); // c
  68. printf("%c \n",*(*(My_Msnj+2)+4)); // e
  69. printf("%c \n",*(*(My_Msnj+2)+5)); // r
  70. printf("%c \n",*(*(My_Msnj+2)+6)); // a
  71.  
  72. printf("\n");
  73.  
  74. system("PAUSE");
  75. return 0;
  76. }

"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #72 en: 24 de Junio de 2012, 15:52:33 »
Macedo:
        Adjunto un proyecto en c18 en donde mustra el contenido de un array de 1d y otro de 2d con varias variantes para mostrar el texto. Lo probé en mi placa entrenadora Multiboard Pictrainer 2.0 de Felixls y funciona ok.
              Saludos.
                    Jukinch

Código: C
  1. /*
  2. programa: EJEMPLO DE USO DE ARRAYS DE 1 y 2 dimensiones
  3.  
  4. pic 18f4550
  5. crystal: 4 MHz CPU 4MHZ
  6.  
  7. CONEXIONES:
  8. lcd conectado en PUERTO D
  9.  
  10. bus de datos en el nible alto conector idc D4a7
  11.  
  12. DATA7    PUERTO D.7
  13. DATA6    PUERTO D.6
  14. DATA5    PUERTO D.5
  15. DATA4    PUERTO D.4
  16.  
  17.  
  18. bus de control en el nible bajo conector idc rD0a3
  19.  
  20. E_PIN    PUERTO D.3
  21. RS_PIN   PUERTO D.2
  22. RW_PIN   PUERTO D.1
  23.  
  24. */
  25.  
  26.  
  27. /*Includes globales*/
  28. #include <p18F4550.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include <delays.h>
  32.  
  33.  
  34.  
  35. /*Includes locales*/
  36. #include "xlcd_portd.h"
  37.  
  38.  
  39.  
  40. /* Bits de configuración*/
  41.  
  42. #pragma config FOSC = XT_XT, CPUDIV = OSC1_PLL2 // Cristal de 4 Mhz y Frecuencia de trabajo del CPU a 4Mhz
  43. #pragma config FCMEN = OFF,IESO = OFF
  44. #pragma config PWRT = ON,BOR = OFF,BORV = 0
  45. #pragma config WDT = OFF,WDTPS = 32768
  46. #pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = OFF
  47. #pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
  48. #pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF
  49. #pragma config CPB = OFF,CPD = OFF
  50. #pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF
  51. #pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF
  52. #pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF
  53. #pragma config EBTRB = OFF
  54.  
  55.  
  56.  
  57.  
  58. /********************** DEFINICIONES *********************/
  59. #define CLOCK 4000000
  60. #define TCY 4/CLOCK
  61. #define BITRATE 100000
  62.  
  63. // 1 TCY se calcula como 4/fosc  
  64. // 1 TCY = X segundos      ======>      4/4000000hz =0,000001s = 1us
  65.  
  66. // 1.000.000 de TCYs equivalen a 1 segundo.
  67. // Delay10KTCYx(100)= 100*10000*TCY=1s
  68. // Delay10KTCYx(100)= 100*10000*1us=1s
  69. // Delay10KTCYx(10)= 100*10000*1us=100ms
  70.  
  71.  
  72.  
  73. #pragma romdata seccionAbcdario
  74. const rom unsigned char My_Msnj[6][20] = {"Primera Linea",
  75.                                                   "Segunda Linea",
  76.                                                   "Tercera Linea",
  77.                                                   "Cuarta Linea",
  78.                                                   "Quinta Linea",
  79.                                                   "Sexta Linea"
  80.                                                   };
  81. const rom unsigned char miCadena[10] = "JUKINCH"; // cadena para mostrar en lcd
  82.  
  83. #pragma romdata
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91. /*declaración de funciones*/
  92.  
  93. void DelayFor18TCY(void);
  94. void DelayPORXLCD(void);
  95. void DelayXLCD(void);
  96. void initlcd(void);
  97. //******************************************************//
  98. // Programa Principal
  99. //******************************************************//
  100. void main(void)
  101. {
  102. ADCON0 = 0X00,ADCON1 = 0X0F,CMCON = 0X07; //puerto A con todos los pines digitales
  103. TRISA = 0X00;
  104. TRISB = 0XFF;
  105. TRISC = 0X00;
  106.  
  107. LATA = 0X00;
  108. LATB = 0X00;
  109. LATC = 0X00;
  110.  
  111.  
  112.  
  113. initlcd(); // inicializamos lcd
  114.  
  115.  
  116. WriteCmdXLCD(LINE_0+0);
  117. putrsXLCD("  MULTIBOARD");
  118. WriteCmdXLCD(NEXT_LINE+0);
  119. putrsXLCD("PIC TRAINER 2.0");
  120. Delay10KTCYx(100);    //Retardo para mostrar valor                                      }
  121. WriteCmdXLCD(0x01);             // Borra pantalla y vuelve al origen.-
  122. WriteCmdXLCD(LINE_0+0);
  123. putrsXLCD("arrays de 1 y 2D");
  124. WriteCmdXLCD(NEXT_LINE+0);
  125. while(BusyXLCD()){}
  126. WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
  127. Delay10KTCYx(100);    //Retardo para mostrar valor                                      }
  128.  
  129.  
  130. /////////////// PRUEBA DE ESCRITURA DE ARRAY DE 1D con putrs y con putc ///////////////
  131.  
  132. WriteCmdXLCD(0x01);             // Borra pantalla y vuelve al origen.-
  133. WriteCmdXLCD(LINE_0+0);
  134.  
  135. putrsXLCD(miCadena); // escribe JUKINCH
  136.  
  137. WriteCmdXLCD(NEXT_LINE+0);
  138. putcXLCD(*(miCadena+0)); // J
  139. putcXLCD(*(miCadena+1)); // U
  140. putcXLCD(*(miCadena+2)); // K
  141. putcXLCD(*(miCadena+3)); // I
  142. putcXLCD(*(miCadena+4)); // N
  143. putcXLCD(*(miCadena+5)); // C
  144. putcXLCD(*(miCadena+6)); // H
  145.  
  146. Delay10KTCYx(100);    //Retardo para mostrar valor                                      }
  147.  
  148. // PRUEBA DE ESCRITURA DE ARRAY DE 2D con putrs pasando My_Msnj, My_Msnj+1 y My_Msnj+2 //
  149. WriteCmdXLCD(0x01);             // Borra pantalla y vuelve al origen.-
  150. WriteCmdXLCD(LINE_0+0);
  151. putrsXLCD(My_Msnj); // escribe Primera Linea
  152.  
  153. WriteCmdXLCD(NEXT_LINE+0);
  154. putrsXLCD(My_Msnj+1); // escribe Segunda Linea
  155. Delay10KTCYx(100);    //Retardo para mostrar valor                                     
  156.  
  157. WriteCmdXLCD(0x01);             // Borra pantalla y vuelve al origen.-
  158. WriteCmdXLCD(LINE_0+0);
  159. putrsXLCD(My_Msnj+2); // escribe Tercera Linea
  160. Delay10KTCYx(100);    //Retardo para mostrar valor                                     
  161.  
  162.  
  163. /////////////// PRUEBA DE ESCRITURA DE ARRAY DE 2D con aritmética de punteros ////
  164.  
  165. WriteCmdXLCD(0x01);             // Borra pantalla y vuelve al origen.-
  166. WriteCmdXLCD(LINE_0+0);
  167. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  168. putcXLCD(*(*(My_Msnj+0)+0)); // P
  169. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  170. putcXLCD(*(*(My_Msnj+0)+1)); // r
  171. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  172. putcXLCD(*(*(My_Msnj+0)+2)); // i
  173. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  174. putcXLCD(*(*(My_Msnj+0)+3)); // m
  175. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  176. putcXLCD(*(*(My_Msnj+0)+4)); // e
  177. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  178. putcXLCD(*(*(My_Msnj+0)+5)); // r
  179. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  180. putcXLCD(*(*(My_Msnj+0)+6)); // a
  181. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  182. putcXLCD(' '); // espacio
  183. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  184. putcXLCD(*(*(My_Msnj+2)+0)); // T
  185. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  186. putcXLCD(*(*(My_Msnj+2)+1)); // e
  187. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  188. putcXLCD(*(*(My_Msnj+2)+2)); // r
  189. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  190. putcXLCD(*(*(My_Msnj+2)+3)); // c
  191. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  192. putcXLCD(*(*(My_Msnj+2)+4)); // e
  193. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  194. putcXLCD(*(*(My_Msnj+2)+5)); // r
  195. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  196. putcXLCD(*(*(My_Msnj+2)+6)); // a
  197.  
  198. WriteCmdXLCD(NEXT_LINE+0);
  199.  
  200. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  201. putcXLCD(*(*(My_Msnj+4)+0)); // Q
  202. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  203. putcXLCD(*(*(My_Msnj+4)+1)); // u
  204. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  205. putcXLCD(*(*(My_Msnj+4)+2)); // i
  206. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  207. putcXLCD(*(*(My_Msnj+4)+3)); // n
  208. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  209. putcXLCD(*(*(My_Msnj+4)+4)); // t
  210. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  211. putcXLCD(*(*(My_Msnj+4)+5)); // a
  212. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  213. putcXLCD(' '); // espacio
  214. putcXLCD(' '); // espacio
  215. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  216. putcXLCD(*(*(My_Msnj+5)+0)); // S
  217. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  218. putcXLCD(*(*(My_Msnj+5)+1)); // e
  219. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  220. putcXLCD(*(*(My_Msnj+5)+2)); // x
  221. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  222. putcXLCD(*(*(My_Msnj+5)+3)); // t
  223. while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  224. putcXLCD(*(*(My_Msnj+5)+4)); // a
  225.  
  226. Delay10KTCYx(100);    //Retardo para mostrar valor                     
  227.  
  228. /////////////// PRUEBA DE ESCRITURA DE ARRAY DE 2D con  [][] ////
  229.  
  230. WriteCmdXLCD(0x01);             // Borra pantalla y vuelve al origen.-
  231. WriteCmdXLCD(LINE_0+0);
  232. putrsXLCD(&My_Msnj[3][0]); // escribe Cuarta Linea
  233. Delay10KTCYx(100);    //Retardo para mostrar valor                                     
  234.  
  235. while (1);
  236.  
  237.  
  238.                
  239.  
  240.  
  241. //*******************************************************
  242. //*******************************************************
  243. }
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++*/
  252. /*++++++++++++++++++++++++++++             F U N C I O N E S          +++++++++++++++++++++++++++++++*/
  253. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  254.  
  255.  
  256. /****************** Funciones de retardos para librería del lcd **************************************/
  257.  
  258. /*
  259.  *              - The user must provide three delay routines:
  260.  *              - DelayFor18TCY() provides a 18 Tcy delay
  261.  *              - DelayPORXLCD() provides at least 15ms delay
  262.  *              - DelayXLCD() provides at least 5ms delay
  263.  
  264. para aprender como se calcularon los delays de abajo ver el archivo:
  265. "D:\My Dropbox\c18\delays - calculo de demoras\calculo de retardos ejemplos con varios cristales - leo.txt"
  266.  
  267. TCY se calcula como 4/fosc
  268.  
  269. donde fosc = frecuencia de trabajo del CPU
  270.  
  271. Ejemplo a velocidad de CPU de 4mhz
  272.  
  273.     TCY = 4/4000000 = 0,000001s
  274.   1 TCY = 0,000001s
  275.   1s / 0,000001s = 1.000.000TCY
  276.  
  277. A  4mhz         1 Tcy equivale a 1  us =======> 20Tcy = 20us
  278.  
  279.                
  280. ***********************************************************************************************************/
  281.  
  282. // para velocidad de CPU de 4mhz descomentar el siguiente código y comentar el de 20mhz
  283.                 void DelayFor18TCY(void)
  284.                 {
  285.                 Delay10TCYx(2); //provides a 20 Tcy delay.          
  286.                 }      
  287.                 void DelayPORXLCD(void)
  288.                 {
  289.                    Delay1KTCYx(15); //Delay 15 mSeg        para CPU de  4mhz. 1 Tcy equivale a 1  us =======> 15000Tcy =15ms              
  290.                 }
  291.                
  292.                 void DelayXLCD(void)
  293.                 {
  294.                    Delay1KTCYx(5);  // Delay 5 mSeg        para CPU de  4mhz. 1 Tcy equivale a 1  us =======>  5000Tcy =5ms
  295.                 }
  296.  
  297.  
  298.  
  299. // para velocidad de CPU de 20mhz descomentar el siguiente código y comentar el de 4mhz
  300. /*
  301.                 void DelayFor18TCY(void)
  302.                 {
  303.                 Delay10TCYx(2); //provides a 20 Tcy delay.          
  304.                 }      
  305.                 void DelayPORXLCD(void)
  306.                 {
  307.                Delay1KTCYx(75); //Delay 15 mSeg        para CPU de 20mhz. 1 Tcy equivale a 0,2us =======> 75000Tcy =15ms              
  308.                 }
  309.                
  310.                 void DelayXLCD(void)
  311.                 {
  312.                    Delay1KTCYx(25); // Delay 5 mSeg                para CPU de 20mhz. 1 Tcy equivale a 0,2us =======> 25000Tcy =5ms
  313.                 }
  314.  
  315. */
  316. /****************** fin de Funciones de retardos para librería del lcd *******************************/
  317.  
  318.  
  319.  
  320. /*************** función inicialización del lcd *****************************************************/
  321. void initlcd(void)
  322.         {
  323.                 Delay10KTCYx(10);    //Retardo para esperar que pase cualquier transitorio
  324.                 OpenXLCD(FOUR_BIT&LINES_5X7);   //inicializamos LCD con varias lineas y caracteres 5x7
  325.                 WriteCmdXLCD(0x01);             // Borra pantalla y vuelve al origen.-
  326.                 while(BusyXLCD()){}     //Preguntamos al RW si el display esta ocupado  
  327.                 WriteCmdXLCD(0x80);     // Nos posicionamos en la la posicion x=0 Y=0
  328.         }
  329. /*************** final función inicialización del lcd ***********************************************/

"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #73 en: 24 de Junio de 2012, 16:36:36 »
Gracias jukinch sos un groso, pero vos tenes declarados los array en main.c, trata de cambiarlo a otro archivo como lcd.c y decime si te funciona igual, es lo que me pasa: tengo declarado mi array en lcd.c y no en main.c:
Código: C
  1. unsigned char My_Msnj[6][20] = {
  2. "Primera Linea",
  3. "Segunda Linea",
  4. "Tercera Linea",
  5. "Cuarta Linea",
  6. "Quinta Linea",
  7. "Sexta Linea"
  8. };

En main.c lo declaro asi:
Código: C
  1. extern unsigned char My_Msnj[];

entonces por lo que me diste a probar:
Código: C
  1. LCDMsnj (0, 2, (My_Msnj+20));

Si funciona y deduzco que el compilador no lo toma bidimencional sino como una linea de caracteres consecutivos, pero si coloco el array en main.c y lo llamo con la funcion:
Código: C
  1. LCDMsnj (0, 0, My_Msnj[0]);

Funciona perfecto y puedo hacer:
Código: C
  1. LCDMsnj (0, 0, My_Msnj);   //primera linea
  2. LCDMsnj (1, 1, My_Msnj);   //segunda linea
  3. LCDMsnj (2, 2, My_Msnj);   //tercera linea
  4. LCDMsnj (3, 3, My_Msnj);   //cuarta linea
  5. LCDMsnj (4, 4, My_Msnj);   //quinta
Todo esto sin problemas.

Ves la pregunta del millón: ¿POR QUE SI CAMBIO EL ARRAY DE ARCHIVO NO FUNCIONA?
Saludos


Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #74 en: 24 de Junio de 2012, 17:11:15 »
Macedo:
           en main declarás el array como unidimensional My_Msnj[];

Código: C
  1. extern unsigned char My_Msnj[];
pero en lcd.c lo definís como bidimensional My_Msnj[6][20];
Código: C
  1. unsigned char My_Msnj[6][20] = {
  2. "Primera Linea",
  3. "Segunda Linea",
  4. "Tercera Linea",
  5. "Cuarta Linea",
  6. "Quinta Linea",
  7. "Sexta Linea"
  8. };
Será por eso?

probá ponerlo así en main.c

extern unsigned char My_Msnj[][20];

luego en donde le asignas la dirección de memoria al puntero myptr deberás ponerlo así:
myptr = &My_Msnj[0][0];

Probá y comentá.
        Saludos.
               Jukinch
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes