Autor Tema: una ayuda con punteros en C18  (Leído 2681 veces)

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

Desconectado SiO2

  • PIC10
  • *
  • Mensajes: 6
una ayuda con punteros en C18
« en: 22 de Abril de 2010, 14:35:02 »
Hola a todos.

   Llevo unos meses aprendiendo C gracias a este foro y me he animado por el C18. He empezado un nuevo programa para mostrar en una vieja matriz de leds letras, números etc..
   y tengo problemas para definir un puntero a la libreria con los datos que se muestran . El motivo de querer hacerlo con un puntero es porque representa los
   primeros 38 vectores, pero el 39 solo muestra la mitad. Inicialmente la forma de cargar los datos era:

void main (void)
{
   unsigned char aux, y, espacio, fila;
   while(1)
   {
      for( fila=0; fila<134; fila++)
      {
         espacio=10;                   //alineamos a la izquierda 10-6=4
         espacio-=libreria[fila][0];     //cargamos el byte 0, el ancho del caracter 6 para el numero 5
                                    
         for( y=0; y<5;y++)            //cargamos los datos en el array que usaremos para mostrar
         {
            for(aux=1; aux<11; aux++)
            {
                 matriz[y][aux-1]=libreria[fila][aux]<<espacio;     //cargamos el dato y desplazamos a la izquierda 3 posiciones
            }
         }
         envia_datos();               //esta funcion representa correctamente los datos
         Delay10KTCY(250);Delay10KTCY(250);Delay10KTCY(250);
      }
   }
}
   
No tenia problemas hasta el registro libreria[39][4]. La placa tiene un led que se enciende/apaga cuando entra en la función envía_datos() y he verificado
con un osciloscopio que envía los pulsos del reloj pero los datos que carga son ceros.asi que decidí hacerlo con punteros pero es realmente confuso el tema.
He encontrado cosas como esta pero el array no es multidimensional:

/*****************************************************************************************************/
FAQ-10 How do I create a large object in data memory (> 256 bytes)?
By default, MPLAB C18 assumes that an object will not cross a bank boundary. The
following steps are required to safely use an object that is larger than 256 bytes:
1. The object must be allocated into its own section using the #pragma idata or
#pragma udata directive:
#pragma udata buffer_scn
static char buffer[0x180];
#pragma udata
2. Accesses to the object must be done via a pointer:
char * buf_ptr = &buffer[0];
...
// examples of use
buf_ptr[5] = 10;
if (buf_ptr[275] > 127)

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

en la guía del c18 :C18_User_Guide_51288 pagina 14,17 etc, pero no me aclaro
y en los programas de ejemplos del c18 hay uno sobre como definirlo se llama pointer.c:

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

ram char * ram_ptr;
near rom char * near_rom_ptr;
far rom char * far_rom_ptr;

char ram_array[] = "ram";
rom char rom_array[] = "ROM";

void main (void)
{
  ram_ptr = &ram_array[0];
  near_rom_ptr = &rom_array[0];
  far_rom_ptr = (far rom char *)&rom_array[0];

  while (1)
    ;
}

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

De esta manera no me da error al compilar pero se ilumina la matriz entera, carga 0xFF de las posiciones vacías de memoria supongo.
   El micro es un pic18f4525 y el programa:

//********includes************
#include <p18f4525.h>
#include <stdio.h>      //

//*******datos**************
#pragma romdata  Datos

static rom const unsigned char libreria[][11]={{6,0x1E,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x1E},       //0
                                 {6,0x1C,0xC,0xC,0xC,0xC,0xC,0xC,0xC,0xC,0x1E},         //1
                                 .........
                                 {6,0x1E,0x33,0x3,0x3,0x6,0xC,0x18,0x30,0x30,0x3F},};   //134 vectores de 11 datos

#pragma romdata

#pragma udata Datos_matriz

unsigned char matriz[5][10];

#pragma udata


unsigned char rom *ptrlibreria;      //tambien he probado unsigned char rom (*ptrlibreria); pero creo que no es la correcta
                                 //en ambos casos el resultado es el mismo



void main (void)
{
   unsigned char aux, y, espacio, fila;
   ptrlibreria=&libreria[0][0];
   while(1)
   {
      for( fila=0; fila<134; fila++)
      {
         espacio=10;                  //alineamos a la izquierda 10-6=4
         espacio-=*((unsigned char*)(ptrlibreria+fila)+0);   //cargamos el byte 0, el ancho del caracter 6 para el numero 5
                                    
         for( y=0; y<5;y++)               //cargamos los datos en el array que usaremos para mostrar
         {
            for(aux=1; aux<11; aux++)
            {
                 matriz[y][aux-1]=*((unsigned char*)(ptrlibreria+fila)+aux)<<espacio;     //cargamos el dato y desplazamos a la izquierda 3 posiciones
            }
         }
         envia_datos();               //esta funcion envia correctamente los datos a la matriz. 
         Delay10KTCY(250);Delay10KTCY(250);Delay10KTCY(250);
      }
   }
}


Los datos no salen en pantalla

Necesito ayuda y una aspirina bien grande

Saludos.
                       
edito: matriz[5] es matriz[5][10]  y para añadir (unsigned char*)                         
« Última modificación: 22 de Abril de 2010, 18:18:56 por SiO2 »

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: una ayuda con punteros en C18
« Respuesta #1 en: 23 de Abril de 2010, 12:06:47 »
En C18 tienes que modificar el *.lkr para unir 2 bancos de memoria y poder crear arreglos mayores a 256 elementos...



Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado SiO2

  • PIC10
  • *
  • Mensajes: 6
Re: una ayuda con punteros en C18
« Respuesta #2 en: 23 de Abril de 2010, 17:03:52 »
Hola Suky

Supongo que te refieres a esto:
FAQ-10 How do I create a large object in data memory (> 256 bytes)?
By default, MPLAB C18 assumes that an object will not cross a bank boundary. The
following steps are required to safely use an object that is larger than 256 bytes:
1. The object must be allocated into its own section using the #pragma idata or
#pragma udata directive:
#pragma udata buffer_scn
static char buffer[0x180];
#pragma udata
2. Accesses to the object must be done via a pointer:
char * buf_ptr = &buffer[0];
...
// examples of use
buf_ptr[5] = 10;
if (buf_ptr[275] > 127)
...
3. A region that spans multiple banks must be created in the linker script:
- Linker script before modification:
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
- Linker script after modification:
DATABANK NAME=big START=0x200 END=0x37F PROTECTED
DATABANK NAME=gpr3 START=0x380 END=0x3FF
4. The object’s section (created in Step 1) must be assigned into the new region
(created in Step 3) by adding a SECTION directive to the linker script:
SECTION NAME=buffer_scn RAM=big
lo he sacado de: http://www.electro-tech-online.com/micro-controllers/89004-variable-initialization-too-large.html

pero es para los datos en la memoria ram, mis datos estan en la rom y matriz[5][10] no tiene muchos elementos.

Gracias por la respuesta. Sigo investigando.


 

anything