# Acceso a memoria de PIC con C18



## catoi (Abr 25, 2008)

Hola.

Tengo un problema con la programación de un PIC. el 18F220, mediante el compilador C18.

He consultado distintos manuales i no termino de entender como se hace el acceso a memoria a la hora de declarar variables e inicializarlas. En el archivo adjunto se muestran las caracteristicas principales de la memoria del PIC. No termino de comprender el uso del comando #pragma, se que sirve para ubicar secciones de codigo en posiciones concretas de memoria. Necesito definir un vector de más de 100 variables tipo int ( 2 Bytes por variable), intento definirlo dentro de los margenes establecidos (512Bytes de SRam) pero sale un error donde dice que no cabe dicho vector en esa seccion.  Tambien he provado de definirlo como datos en la Rom mediante #pragma romdata, pero tampoco funciona. Mi programa todavia no es muy extenso, por eso creo que es un error de concepto y no de que realmente mis variables no quepan en la memoria.



Parte de uno de los códigos usados és la siguiente:

//Llibreries:
#include <p18f2220.h>
#include <stdio.h>
#include <math.h>
#include <i2c.h>
#include <adc.h>
#include <timers.h>
#include <delays.h>

//Configuració:
#pragma config OSC=INTIO2, WDT=OFF

#pragma romdata array_temps
int temps[110]; //He provado con variables char, ya que solo ocupan un solo Byte
#pragma romdata

#pragma idata ferquencies
int freq[8]={100,120,145,168,190,210,245,268};
#pragma idata

//Definicions:
#define led_verd LATCbits.LATC0
#define led_groc LATCbits.LATC1
#define led_vermell LATCbits.LATC2
#define switch_1 LATBbits.LATB0
#define switch_2 LATAbits.LATA4
#define switch_3 LATBbits.LATB4
#define switch_4 LATBbits.LATB5
#define dio_1 LATCbits.LATC5
#define dio_2 LATCbits.LATC6
#define dio_3 LATCbits.LATC7

const rom double pi = 3.14159265;

..............



El tipo de error es el siguiente:

Copyright (c) 2008 Microchip Technology Inc.
Error - section '.udata_Untitled.o' can not fit the section. Section '.udata_Untitled.o' length=0x000000dc
Errors    : 1
BUILD FAILED: Fri Apr 25 11:35:13 2008



Les agradeceria si pudieeran aclararme el uso y acceso a la memoria de dicho PIC.

Gracias.


----------



## f_point (Abr 27, 2008)

Hola catoi.

Generalmente veo que poca gente tiende a usar el compilador C18 de Microchip para desarrollo de aplicaciones basadas en microcontrolador PIC18, probablemente debido a que es un poco mas dificil de usar que otros compiladores similares de C como el CCS. Yo como tu, somos de los pocos que nos animamos a usar este compilador, que a mi opinion, es superior a el resto.

Tu duda tiene una solucion que con gusto te detallare.

La directiva #pragma es una mecanica estandarizada del lenguaje C que permite a los creadores de los compiladores introducir mecanicas adicionales al lenguaje. Has de saber que el lenguaje C esta oficialmente regulado por el instituto ANSI, es decir, que los creadores de los compiladores estan moralmente motivados a no generar extensiones del lenguaje fuera del estandar. Para los casos en que es imposible aislar el lenguaje del entorno de programacion (en este caso del entorno del microcontrolador), la directiva #pragma es la mecanica oficial para controlar los aspectos que requieran una interaccion con el entorno.

Asi pues, #pragma tiene diversos usos en C18 ajenos al C tradicional, como la definicion de fuses o el alojamiento de datos (ROM y RAM), entre otras funciones, que son exclusivas de los PIC.

En tu caso particular, tu codigo esta bastante bien escrito excepto por un pequeño error que podriamos catalogar como sintactico.

Por ejemplo, en tu programa declaras un arreglo de datos en la ROM flash asi:


```
#pragma romdata array_temps
int temps[110]; //He provado con variables char, ya que solo ocupan un solo Byte
#pragma romdata
```

Cuando la manera adecuada es agregar los tipos *const* y *rom*, asi:


```
#pragma romdata array_temps
const rom int temps[110];
#pragma romdata
```

La ausencia de esos tipos indica erroneamente al compilador que genere el arreglo en RAM (cuando lo que deseas es que se genere en ROM), eso genera el error que listas, porque se agota el espacio en la RAM de acceso que es donde intenta alojarlo por defecto y esta limitada a 128 bytes (tu arreglo ocupa 220 bytes).

Aparte, si deseas hacer un arreglo en RAM que exceda los 128 bytes de la RAM de acceso, sugiero que le indiques al C18 que aloje el arreglo en otro banco de memoria que este definido en el archivo .lkr. Esto puedes hacerlo asi en base a tu codigo:


```
#pragma udata array_temps=0x80
int temps[50];
#pragma udata
```

Lamentablemente el PIC18F2220 cuenta con muy poca memoria, y el mayor tamaño de arreglo disponible que se puede obtener mas alla de la memoria de acceso (haciendo mis pruebas) es de 100 bytes. Podria intentarse usar el banco 1 (direccion 0x100) pero lamentablemente esta reservado para la pila (que sirve para guardar datos temporales de calculos y almacenar argumentos de funciones).

El mayor tamaño de arreglo posible para todo PIC18 es de 256 bytes (en el caso de modelos con mas memoria) que es precisamente el tamaño del banco de RAM convencional en estos microcontroladores. Pero puedes usar varios bancos consecutivos juntos para generar arreglos de mas de 256 bytes.

Si deseas un arreglo mas grande, puedes intentar usar la RAM de acceso (primeros 128 bytes) mas una porcion de la segunda mitad del banco 0 (segundos 128 bytes), pero entonces te quedaria muy poco espacio para variables y demas datos que necesites. Adicionalmente puedes usar un PIC con mas memoria para tu proyecto (Recomiendo particularmente el PIC18F2620 en este caso).

Espero mis comentarios te ayuden en lo posible. Si tienes mas dudas, no vaciles en preguntar.

Buena suerte.


----------



## cyberian (Oct 20, 2009)

Hola f_point, he leído tu respuesta anterior, y está genial, yo estoy usando un pic18f4620, y necesito crear un array de 512 bytes como un buffer, que después será escrito en una tarjeta sd en modo spi. Con el ejemplo que diste, he podido crear un array en el banco 2, en la RAM, dirección 0x200, pero con un máximo de 256 byte (unsigned char). Cómo sería posible unir los bancos 2 y 3 para crear uno de 512. Agradecería tu respuesta.

Hola, creo que ya lo logré, tuve un eureka, simplemente borré del archivo linker el banco 3, y al banco 2 le puse la dirección de fin del banco 3, lugo compilé y todo ok, y el gauge de memoria ram aumentó. Creo que todo ok. Si lo que hice está mal, por favor avisame.
Muchas Gracias.


----------



## diego_z (Oct 22, 2009)

una consulta que no tiene nada que ver con el post , pero veo que son pocos los que usan el c18 del mplab, puesto que hace tiempo estoy interesado en empezar c , solo e programado en assembler hasta ahora y me gustaria seguir bajo el mismo entorno del mplab , el problema es que no e podido crear un proyecto , bueno si e podido crearlo pero siempre me da este error 

*Clean: Deleting intermediary and output files.*
*Clean: Deleted file "D:\mis documentos\mplab\curso compilador c18\Ba\Cbasico\cbasico.o".*
*Clean: Deleted file "D:\mis documentos\mplab\curso compilador c18\Ba\Cbasico\ll.mcs".*
*Clean: Done.*
*Executing: "C:\MCC18\bin\mcc18.exe" -p=18F452 "cbasico.c" -fo="cbasico.o" /i"C:\MCC18\h" -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-*
*MPLAB C18 v3.33 (evaluation)*
*Copyright 2000-2009 Microchip Technology Inc.*
*Days remaining until evaluation becomes feature limited: 59*
*Skipping link step. The project contains no linker script.*
*BUILD FAILED: Thu Oct 22 21:31:48 2009*

obiando lo de los 59 dias el resto no se que mas hacer para que me funcione , agradecido por su respuesta de antemano diego


----------



## di3gosl (Dic 11, 2009)

diego_z dijo:


> una consulta que no tiene nada que ver con el post , pero veo que son pocos los que usan el c18 del mplab, puesto que hace tiempo estoy interesado en empezar c , solo e programado en assembler hasta ahora y me gustaria seguir bajo el mismo entorno del mplab , el problema es que no e podido crear un proyecto , bueno si e podido crearlo pero siempre me da este error
> 
> *Clean: Deleting intermediary and output files.*
> *Clean: Deleted file "D:\mis documentos\mplab\curso compilador c18\Ba\Cbasico\cbasico.o".*
> ...



Que tal diego_z, nose si ya hayas resuelto tu problema pero por sino lo has hecho y para que quede aquí por si alguien más lo requiere. Mira a mi también me pasaba lo mismo y me daba ese error y la solución es muy simple, tienes que agregar el linker script al proyecto, para tu caso sería el archivo 18f452.lkr que generalmente se encuentra en la carpeta C:\MCC18\lkr o en su defecto en donde hayas instalado el compilador C18. Espero te sea de ayuda, saludos.


----------



## Biker12 (Dic 27, 2009)

Hola amigos, ya que estan con el tema de acceso a memoria quería ver si alguien me podría ayudar con una pequeña duda. Actualmente estoy trabajando en un proyecto en el cual una sección de código (hecha en ensamblador) llena una sección de memoria con datos. El asunto es que ahora debo accesar a estos datos desde un procedimiento en PIC C y la verdad estoy iniciando en ello. Mi idea era utilizar un puntero que hiciera referencia a la primera locación de memoria a partir de la cual se almacenaron los datos, pero en realidad no he logrado hacerlo ya que siempre obtengo errores de compilación. Alguien podría decirme como puedo crear un puntero y "decirle", por ejemplo, que apunte hacia la dirección específica 0x300?

Gracias.

Biker12


----------

