Autor Tema: memcpy_p adaptado a CCS  (Leído 2228 veces)

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

Desconectado jesusm

  • PIC10
  • *
  • Mensajes: 7
memcpy_p adaptado a CCS
« en: 18 de Agosto de 2018, 06:54:21 »
Hola estoy intentando traducir esta función de arduino a CCS (memcpy_p). Alguien me podría explicar lo que hace en este código.
Saludos

Código: C++
  1. PROGMEM const unsigned char CH[] = {
  2. 3, 8, B00000000, B00000000, B00000000, B00000000, B00000000, // space
  3. 1, 8, B01011111, B00000000, B00000000, B00000000, B00000000, // !
  4. 3, 8, B00000011, B00000000, B00000011, B00000000, B00000000, // "
  5. 5, 8, B00010100, B00111110, B00010100, B00111110, B00010100, // #
  6. 4, 8, B00100100, B01101010, B00101011, B00010010, B00000000, // $
  7. 5, 8, B01100011, B00010011, B00001000, B01100100, B01100011, // %
  8. 5, 8, B00110110, B01001001, B01010110, B00100000, B01010000, // &
  9. 1, 8, B00000011, B00000000, B00000000, B00000000, B00000000, // '
  10. 3, 8, B00011100, B00100010, B01000001, B00000000, B00000000, // (
  11. 3, 8, B01000001, B00100010, B00011100, B00000000, B00000000, // )
  12. 5, 8, B00101000, B00011000, B00001110, B00011000, B00101000, // *
  13. 5, 8, B00001000, B00001000, B00111110, B00001000, B00001000, // +
  14. 2, 8, B10110000, B01110000, B00000000, B00000000, B00000000, // ,
  15. 4, 8, B00001000, B00001000, B00001000, B00001000, B00000000, // -
  16. 2, 8, B01100000, B01100000, B00000000, B00000000, B00000000, // .
  17. 4, 8, B01100000, B00011000, B00000110, B00000001, B00000000, // /
  18. 4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // 0
  19. 3, 8, B01000010, B01111111, B01000000, B00000000, B00000000, // 1
  20. 4, 8, B01100010, B01010001, B01001001, B01000110, B00000000, // 2
  21. 4, 8, B00100010, B01000001, B01001001, B00110110, B00000000, // 3
  22. 4, 8, B00011000, B00010100, B00010010, B01111111, B00000000, // 4
  23. 4, 8, B00100111, B01000101, B01000101, B00111001, B00000000, // 5
  24. 4, 8, B00111110, B01001001, B01001001, B00110000, B00000000, // 6
  25. 4, 8, B01100001, B00010001, B00001001, B00000111, B00000000, // 7
  26. 4, 8, B00110110, B01001001, B01001001, B00110110, B00000000, // 8
  27. 4, 8, B00000110, B01001001, B01001001, B00111110, B00000000, // 9
  28. 2, 8, B01010000, B00000000, B00000000, B00000000, B00000000, // :
  29. 2, 8, B10000000, B01010000, B00000000, B00000000, B00000000, // ;
  30. 3, 8, B00010000, B00101000, B01000100, B00000000, B00000000, // <
  31. 3, 8, B00010100, B00010100, B00010100, B00000000, B00000000, // =
  32. 3, 8, B01000100, B00101000, B00010000, B00000000, B00000000, // >
  33. 4, 8, B00000010, B01011001, B00001001, B00000110, B00000000, // ?
  34. 5, 8, B00111110, B01001001, B01010101, B01011101, B00001110, // @
  35. 4, 8, B01111110, B00010001, B00010001, B01111110, B00000000, // A
  36. 4, 8, B01111111, B01001001, B01001001, B00110110, B00000000, // B
  37. 4, 8, B00111110, B01000001, B01000001, B00100010, B00000000, // C
  38. 4, 8, B01111111, B01000001, B01000001, B00111110, B00000000, // D
  39. 4, 8, B01111111, B01001001, B01001001, B01000001, B00000000, // E
  40. 4, 8, B01111111, B00001001, B00001001, B00000001, B00000000, // F
  41. 4, 8, B00111110, B01000001, B01001001, B01111010, B00000000, // G
  42. 4, 8, B01111111, B00001000, B00001000, B01111111, B00000000, // H
  43. 3, 8, B01000001, B01111111, B01000001, B00000000, B00000000, // I
  44. 4, 8, B00110000, B01000000, B01000001, B00111111, B00000000, // J
  45. 4, 8, B01111111, B00001000, B00010100, B01100011, B00000000, // K
  46. 4, 8, B01111111, B01000000, B01000000, B01000000, B00000000, // L
  47. 5, 8, B01111111, B00000010, B00001100, B00000010, B01111111, // M
  48. 5, 8, B01111111, B00000100, B00001000, B00010000, B01111111, // N
  49. 4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // O
  50. 4, 8, B01111111, B00001001, B00001001, B00000110, B00000000, // P
  51. 4, 8, B00111110, B01000001, B01000001, B10111110, B00000000, // Q
  52. 4, 8, B01111111, B00001001, B00001001, B01110110, B00000000, // R
  53. 4, 8, B01000110, B01001001, B01001001, B00110010, B00000000, // S
  54. 5, 8, B00000001, B00000001, B01111111, B00000001, B00000001, // T
  55. 4, 8, B00111111, B01000000, B01000000, B00111111, B00000000, // U
  56. 5, 8, B00001111, B00110000, B01000000, B00110000, B00001111, // V
  57. 5, 8, B00111111, B01000000, B00111000, B01000000, B00111111, // W
  58. 5, 8, B01100011, B00010100, B00001000, B00010100, B01100011, // X
  59. 5, 8, B00000111, B00001000, B01110000, B00001000, B00000111, // Y
  60. 4, 8, B01100001, B01010001, B01001001, B01000111, B00000000, // Z
  61. 2, 8, B01111111, B01000001, B00000000, B00000000, B00000000, // [
  62. 4, 8, B00000001, B00000110, B00011000, B01100000, B00000000, // \ backslash
  63. 2, 8, B01000001, B01111111, B00000000, B00000000, B00000000, // ]
  64. 3, 8, B00000010, B00000001, B00000010, B00000000, B00000000, // hat
  65. 4, 8, B01000000, B01000000, B01000000, B01000000, B00000000, // _
  66. 2, 8, B00000001, B00000010, B00000000, B00000000, B00000000, // `
  67. 4, 8, B00100000, B01010100, B01010100, B01111000, B00000000, // a
  68. 4, 8, B01111111, B01000100, B01000100, B00111000, B00000000, // b
  69. 4, 8, B00111000, B01000100, B01000100, B00101000, B00000000, // c
  70. 4, 8, B00111000, B01000100, B01000100, B01111111, B00000000, // d
  71. 4, 8, B00111000, B01010100, B01010100, B00011000, B00000000, // e
  72. 3, 8, B00000100, B01111110, B00000101, B00000000, B00000000, // f
  73. 4, 8, B10011000, B10100100, B10100100, B01111000, B00000000, // g
  74. 4, 8, B01111111, B00000100, B00000100, B01111000, B00000000, // h
  75. 3, 8, B01000100, B01111101, B01000000, B00000000, B00000000, // i
  76. 4, 8, B01000000, B10000000, B10000100, B01111101, B00000000, // j
  77. 4, 8, B01111111, B00010000, B00101000, B01000100, B00000000, // k
  78. 3, 8, B01000001, B01111111, B01000000, B00000000, B00000000, // l
  79. 5, 8, B01111100, B00000100, B01111100, B00000100, B01111000, // m
  80. 4, 8, B01111100, B00000100, B00000100, B01111000, B00000000, // n
  81. 4, 8, B00111000, B01000100, B01000100, B00111000, B00000000, // o
  82. 4, 8, B11111100, B00100100, B00100100, B00011000, B00000000, // p
  83. 4, 8, B00011000, B00100100, B00100100, B11111100, B00000000, // q
  84. 4, 8, B01111100, B00001000, B00000100, B00000100, B00000000, // r
  85. 4, 8, B01001000, B01010100, B01010100, B00100100, B00000000, // s
  86. 3, 8, B00000100, B00111111, B01000100, B00000000, B00000000, // t
  87. 4, 8, B00111100, B01000000, B01000000, B01111100, B00000000, // u
  88. 5, 8, B00011100, B00100000, B01000000, B00100000, B00011100, // v
  89. 5, 8, B00111100, B01000000, B00111100, B01000000, B00111100, // w
  90. 5, 8, B01000100, B00101000, B00010000, B00101000, B01000100, // x
  91. 4, 8, B10011100, B10100000, B10100000, B01111100, B00000000, // y
  92. 3, 8, B01100100, B01010100, B01001100, B00000000, B00000000, // z
  93. 3, 8, B00001000, B00110110, B01000001, B00000000, B00000000, // {
  94. 1, 8, B01111111, B00000000, B00000000, B00000000, B00000000, // |
  95. 3, 8, B01000001, B00110110, B00001000, B00000000, B00000000, // }
  96. 4, 8, B00001000, B00000100, B00001000, B00000100, B00000000, // ~
  97. };
  98.  
  99. int data = 8;    // DIN pin of MAX7219 module
  100. int load = 9;    // CS pin of MAX7219 module
  101. int clock = 10;  // CLK pin of MAX7219 module
  102.  
  103. int maxInUse = 2;  //how many MAX7219 are connected
  104.  
  105. MaxMatrix m(data, load, clock, maxInUse); // define Library
  106.  
  107. byte buffer[10];
  108.  
  109. char string1[] = " Brainy-Bits.com      ";  // Scrolling Text
  110.  
  111.  
  112. void setup(){
  113.   m.init(); // module MAX7219
  114.   m.setIntensity(5); // LED Intensity 0-15
  115. }
  116.  
  117. void loop(){
  118.  
  119.   byte c;
  120.   delay(100);
  121.   m.shiftLeft(false, true);
  122.   printStringWithShift(string1, 100);  // Send scrolling Text
  123.  
  124. }
  125.  
  126. // Put extracted character on Display
  127. void printCharWithShift(char c, int shift_speed){
  128.   if (c < 32) return;
  129.   c -= 32;
  130.   memcpy_P(buffer, CH + 7*c, 7);
  131.   m.writeSprite(maxInUse*8, 0, buffer);
  132.   m.setColumn(maxInUse*8 + buffer[0], 0);
  133.  
  134.   for (int i = 0; i < buffer[0]+1; i++)
  135.   {
  136.     delay(shift_speed);
  137.     m.shiftLeft(false, false);
  138.   }
  139. }
  140.  
  141. // Extract characters from Scrolling text
  142. void printStringWithShift(char* s, int shift_speed){
  143.   while (*s != 0){
  144.     printCharWithShift(*s, shift_speed);
  145.     s++;
  146.   }
  147. }

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:memcpy_p adaptado a CCS
« Respuesta #1 en: 18 de Agosto de 2018, 11:30:47 »
Citar
The memcpy_P() function is similar to memcpy(), except the src string resides in program space.

Para CCS primero definis tu variable como const, eso lo aloja en la flash o memoria de programa, no hay necesidad de usar PROGMEM como en el ARDUINO.

Luego usas el memcpy normal.

El memcpy es:

void *memcpy(void *dst, const void *src, size_t n)

Donde tenes que *dst es el puntero destino, *src es el puntero fuente y n es la cantidad de bytes a trasladar.

Citar
Alguien me podría explicar lo que hace en este código.

La primer GRAN constante que tenes definida, por lo que parece son los bits a enviar a un integrado para una matriz de led (lo se por el MAX7219) supongamos para dibujar algun caracter.. Por ejemplo, el mas simple de ver es el "!"

Si observas los que dicen Bxxxxxxxx, que pertenences al "!" (comentado a la derecha) vas a ver que si lo reordenas (esto depende del barrido del matriz):

Código: [Seleccionar]
BBBBB
00001
00001
00001
00001
00001
00000
00001
00000

Te queda algo asi... es decir el signo de exclamacion.

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

Luego se declara una variable, que pertenece a una libreria MaxMatrix, seguramente esta sea la encargada de enviar los datos al MAX7219, la cual llama "m" , y le pasa los datos de que pines son los del SPI para que se pueda comunicar, me refiero a los declarados antes y comentados como DIN, CS y CLK

Código: C
  1. MaxMatrix m(data, load, clock, maxInUse); // define Library

Inicializa el modulo, lo que hace dentro depende de la libreria en uso. Y fija la intensidad de los leds. En CCS te vas a tener que comunicar y crear una funcion para cada uno de estos.

Código: C
  1. m.init(); // module MAX7219
  2.   m.setIntensity(5); // LED Intensity 0-15

Define algun modo de operacion... no se que sera, ya que no me fije en la libreria.

Código: C
  1. m.shiftLeft(false, true);

Finalmente, imprime el texto con shift, es decir con desplazamiento, ese 100, es el delay de movimiento. Si observas se le pasa todo el string ( en realidad un puntero) pero es COMPLETO
Código: C
  1. printStringWithShift(string1, 100);  // Send scrolling Text

Esa funcion esta definida en el codigo, una forma de simplificar y facilitar las cosas es tratarlo caracter por caracter hasta llegar al final que es el caracter nulo ( '\0' o 0 ).
Es por eso que por cada caracter llama a la funcion printCharWithShift()

Código: C
  1. void printStringWithShift(char* s, int shift_speed){
  2.   while (*s != 0){
  3.     printCharWithShift(*s, shift_speed);
  4.     s++;
  5.   }
  6. }

Y aqui es donde finalmente le envia los datos a la matriz.

Código: C
  1. void printCharWithShift(char c, int shift_speed){
  2.   if (c < 32) return;
  3.   c -= 32;
  4.   memcpy_P(buffer, CH + 7*c, 7);
  5.   m.writeSprite(maxInUse*8, 0, buffer);
  6.   m.setColumn(maxInUse*8 + buffer[0], 0);
  7.  
  8.   for (int i = 0; i < buffer[0]+1; i++)
  9.   {
  10.     delay(shift_speed);
  11.     m.shiftLeft(false, false);
  12.   }
  13. }

Vamos a entender que es lo que hace y por que.
Obtenemos el primer caracter, estos se representan en ASCII, dejo la imagen de a la tabla:



El problema es que nuestra tabla, la del comienzo, no tiene presentes los caracteres desde 0 al 31(decimal) sino necesitariamos mucho mas espacio en la flash. Entonces comienza por el 32, que es el espacio. Si yo debo ajustar para que esa tabla coincida con lo que le paso debo restarle 32.

Un ejemplo: el caracter "!" en la tabla te dice que es el 33, entonces al momento de nosotros enviarle el caracter a la funcion esta, le llega un 33, pero nuestro array al comienzo el ! es la posicion numero 1, entonces si le resto 32 a ese 33, me queda justamente 1.

Ahora continuamos con nuestro "memcpy_P"

Código: C
  1. memcpy_P(buffer, CH + 7*c, 7);

CH asi solo es el puntero al objeto 0 del array, o mejor dicho donde comienza. Y si observas cada "caracter" posee 7 bytes:

Código: C
  1. 3, 8, B00000000, B00000000, B00000000, B00000000, B00000000, // space

Entonces si por ejemplo quisiera conocer la posicion de mi 3er caracter que son las comillas dobles, se que comienza en la posicion 14, pero para hacerlo con una formula es ese 7*c que tenes, recorda que para el primer caracter al restar te quedaba 1, si multipicas te queda CH + 7, para el segundo caracter luego de restar te queda 2, y la formula queda CH + 14.

En fin, define el principio de cada caracter, y le dice que copie los 7 bytes que le corresponden al array buffer.

Código: C
  1. m.writeSprite(maxInUse*8, 0, buffer);
  2.   m.setColumn(maxInUse*8 + buffer[0], 0);

Escribe en la matriz con writeSprite, y luego define la cantidad de columnas imagino, sera para darle el espacio entre caracteres, realmente no tengo el codigo fuente de la libreria.

Por ultimo el delay que hace el "desplazamiento"

Código: C
  1. for (int i = 0; i < buffer[0]+1; i++)
  2.   {
  3.     delay(shift_speed);
  4.     m.shiftLeft(false, false);
  5.   }

Dado por la cantidad de columas, hace un delay y le indica a la libreria que haga un desplazamiento.

Desconectado jesusm

  • PIC10
  • *
  • Mensajes: 7
Re:memcpy_p adaptado a CCS
« Respuesta #2 en: 18 de Agosto de 2018, 19:40:35 »
Menuda respuesta currada  ((:-)) ((:-))
Gracias por dedicar tu tiempo a responderme.

Saludos

Otra pregunta, si tienes una variable global a dos archivos .c (que se pueda modificar en ambos) como se declara?

En a.c  variable=2, quiero que en b.c vea que el valor es 2

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:memcpy_p adaptado a CCS
« Respuesta #3 en: 18 de Agosto de 2018, 21:03:18 »
En los archivos

a.c
Código: C
  1. int8 variable = 8;

b.c
Código: C
  1. extern int8 variable;

Pero CCS tiene un poco de problemas al compilar con varios .c, pero esta es la forma que lo podrias hacer con cualquier compilador

Desconectado jesusm

  • PIC10
  • *
  • Mensajes: 7
Re:memcpy_p adaptado a CCS
« Respuesta #4 en: 19 de Agosto de 2018, 00:23:56 »
Estoy haciendo pruebas con proteus y me gustaria ver esa variable buffer correctamente. Utilizo:

Código: C++
  1. printf ("Buffer[0] = %d\r", buff[0]);  //Para el caracter Espacio se muestra un 4

Es posible que para el caracter Espacio me aparezca esto? O algo que me pueda valer para identificar la validez de memcpy?

Código: C++
  1. 3, 8, 0x00, 0x00, 0x00, 0x00, 0x00,

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:memcpy_p adaptado a CCS
« Respuesta #5 en: 19 de Agosto de 2018, 09:33:14 »
Luego de que se ejecute el memcpy, si deberias tener un 3, si es que el caracter es el espacio. Veo que en el printf usaste "buff" cuando es "buffer", si lo estas enviando por RS232, tal ves asi sea mejor:

Código: C
  1. void printCharWithShift(char c, int shift_speed){
  2.   if (c < 32) return;
  3.   printf("char: %c",c);
  4.   c -= 32;
  5.   memcpy_P(buffer, CH + 7*c, 7);
  6.   printf ("Buf= %u,%u,%u,%u,%u\r",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5]);  //Para el caracter Espacio se muestra un 4
  7.   m.writeSprite(maxInUse*8, 0, buffer);
  8.   m.setColumn(maxInUse*8 + buffer[0], 0);
  9.  
  10.   for (int i = 0; i < buffer[0]+1; i++)
  11.   {
  12.     delay(shift_speed);
  13.     m.shiftLeft(false, false);
  14.   }
  15. }


 

anything