TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: rbpkirow en 25 de Mayo de 2011, 11:03:39
-
Hola a tod@s.
Estoy teniendo un problema en la compilacion de un programa con el pic 16f886, a ver si alguien me puede ayudar, o explicar porqué me está ocurriendo.
Necesito un vector de char o int (mejor char por memoria) de unos 300 elementos. El problema es que no me deja declarar un vector de mas de 96 elementos. Me ocurre lo siguiente:
#define MAX_ANG 97
// Variables globales
char angulos[MAX_ANG];
#include <htc.h>
#include <math.h>
__CONFIG(FOSC_INTRC_CLKOUT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF & LVP_OFF & DEBUG_OFF & BOR4V_BOR40V & WRT_OFF);
void main()
{
for(int i = 0; i<MAX_ANG; i++)
{
angulos[i]=80;
}
} /*main*/
Error [1250] \main.c; 5. could not find space (97 bytes) for variable _angulos
Como se puede ver, con 97 elementos me devuelve error de espacio, sin embargo, modificando el tamaño a 96 compila correctamente y me indica un uso de espacio de datos de 27%
Memory Summary:
Program space used 2Fh ( 47) of 2000h words ( 0.6%)
Data space used 64h ( 100) of 170h bytes ( 27.2%)
EEPROM space used 0h ( 0) of 100h bytes ( 0.0%)
Configuration bits used 1h ( 1) of 2h words ( 50.0%)
ID Location space used 0h ( 0) of 4h bytes ( 0.0%)
De hecho, si declaro 2 vectores de 96 elementos, tampoco tengo ningun problema y compila correctamente con un uso de 53%
#define MAX_ANG 96
// Variables globales
char angulos[MAX_ANG];
char angulos2[MAX_ANG];
#include <htc.h>
#include <math.h>
__CONFIG(FOSC_INTRC_CLKOUT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF & LVP_OFF & DEBUG_OFF & BOR4V_BOR40V & WRT_OFF);
void main()
{
for(int i = 0; i<MAX_ANG; i++)
{
angulos[i]=80;
angulos2[i]=80;
}
} /*main*/
Memory Summary:
Program space used 3Ch ( 60) of 2000h words ( 0.7%)
Data space used C4h ( 196) of 170h bytes ( 53.3%)
EEPROM space used 0h ( 0) of 100h bytes ( 0.0%)
Configuration bits used 1h ( 1) of 2h words ( 50.0%)
ID Location space used 0h ( 0) of 4h bytes ( 0.0%)
Alguien me puede explicar porqué motivo no puedo usar un vector de mas de 96 elementos si usando 2 vectores tengo un 50%?
muchas gracias
un saludo
Edito:
Utilizo MPLAB version 8.63 con el compilador PIC16 version 9.81 PRO version (Evaluacion)
-
Hola, no uso microcontroladores MicroChip, pero por lo que aprendí en este foro la RAM de algunos miembros de la familia no es lineal si no que esta divida en bancos, por eso el compilador te avisa que no podes declarar arrays de un tamaño mayor al mismo. También aprendí que hay compiladores que te permiten ocultar esta restricción dándose cuenta del elemento a acceder y por ende haciendo el correspondiente switch de banco.
Saludos !
-
Estoy de acuerdo con Richi777, seguro que el problema se debe a la división de la memoria en bancos. Como no tenés tanta ram en un banco te tira el error. Seguramente con un PIC de la familia 18 no tendrías el error.
-
Yo lo aseguro, es ese el problema, y CCS no hace lo que comenta Richi : "También aprendí que hay compiladores que te permiten ocultar esta restricción dándose cuenta del elemento a acceder y por ende haciendo el correspondiente switch de banco. " :tongue:
Así que se debe usar un buffer de menor tamaño o cambiar de micro y de la familia 18F.
Saludos!
-
Hola si lo dice Suky tómalo como palabra santa.
Saludos !
-
Muchisimas gracias a todos.
Estoy estudiando el pic 16f1938 que tiene mas memoria y a primera vista es pin a pin compatible con el 16f886.
Muchas gracias de nuevo.
-
Según el datasheet que estoy mirando del 193x, sí tenés mas memoria RAM, pero por banco sigue manteniendo el máximo de 96 bytes.
-
Muchisimas gracias a todos.
Estoy estudiando el pic 16f1938 que tiene mas memoria y a primera vista es pin a pin compatible con el 16f886.
Muchas gracias de nuevo.
Si bien el 16F1938 es de arquitectura extendida y permite con punteros direccionar toda la ram sin tener que cambiar de banco, el problema está en que la ram para tus datos no es continua como en los 18F. Por ende tenes varios puntos donde existen posiciones de memoria que se acceden desde todos los bancos pero la parte util que utilizarías para tus datos no es continua por ende tampoco te servirá para declarar un arreglo tan grande.
saludos
-
Hola AngelGris, muy bueno el dato.
Saludos !
PD: Competis conmigo para ver quien llega primero a los 1000 post ? :P
-
Hola Maunix, disculpa mi ignorancia, me podrías explicar como con punteros salvas la no linealidad de la RAM ? Desde ya muchas gracias !
Saludos !
-
También me gustaría aprenderlo :)
-
Hola AngelGris, muy bueno el dato.
Saludos !
PD: Competis conmigo para ver quien llega primero a los 1000 post ? :P
:D :D :D
Nah, yo no puedo competir en nada...
-
Hola Maunix, disculpa mi ignorancia, me podrías explicar como con punteros salvas la no linealidad de la RAM ? Desde ya muchas gracias !
Saludos !
Los pic 16f1938 y todos los de arquitectura extendida de la familia 16F tienen doble registro FSR (Low y High) lo que les permite acceder a toda la ram con el formato "indirecto" de direccionamiento. Eso te permite por un lado cargar en esos registros la posición absoluta (de 0 a 65535) de ram a la cual queres acceder y luego trabajas con el registro INDF para leer o grabar en dicha posición.
Esto lo podes hacer directamente trabajando con el assembly ya que el uso del direccionamiento indirecto (escribís en un lado la dirección y en otro se graba el dato). Ahora bien para hacerlo en C depende del compilador. En CCS no tengo ni idea ya que no lo uso, pero no se si estos registros y su modo de direccionamiento esten abiertos al usuario, probablemente si, probablemente no ahora pero si en el futuro, vaya uno a saber.
En C18 esto se hace trabajando con el linkerfile y usando punteros directamente (no accediendo con el nombre de vector[nn])
Si aún así no queda claro , tiro un ejemplo ;)
-
También me gustaría aprenderlo :)
Ah no, por cantidad es otro precio :D :D
-
dentro de los ejemplos de ccs hay uno que se llama EX_MXRAM.C, cuya finalidad es utilizar toda la ram para crear arreglos. no se si mikroC tenga ejemplo similares.
-
Hola Maunix, si se entiende perfectamente. Muchas gracias !!!
Saludos !
-
También me gustaría aprenderlo :)
Ah no, por cantidad es otro precio :D :D
Aaa.. en asm! :D CCS de por si solo no lo soluciona, o sea como para hacer un buffer de 256 elementos y trabajarlos de forma comun, hay que inventar algo como lo que muestra PalitroqueZ en el ejemplo que da.
Pero en C18! Seguramente te refieres a que C18 divide la memoria en bancos, y que si se quiere trabajar con un buffer mayor a 256 hay que modificar el *.lkr, pero la memoria es lineal, así que no tienes problemas.
Ahora uno de los problemas que tuve al realizar eso en C18 fue que si una variable multibyte pertenece a dos bancos consecutivos (por supuesto) no funciona correctamente :? Por eso lo trabajé con punteros :D
Saludos!
-
Aaa.. en asm! :D CCS de por si solo no lo soluciona, o sea como para hacer un buffer de 256 elementos y trabajarlos de forma comun, hay que inventar algo como lo que muestra PalitroqueZ en el ejemplo que da.
Ah, por eso ni idea, no uso ccs jiji.
Pero en C18! Seguramente te refieres a que C18 divide la memoria en bancos, y que si se quiere trabajar con un buffer mayor a 256 hay que modificar el *.lkr, pero la memoria es lineal, así que no tienes problemas.
Ahora uno de los problemas que tuve al realizar eso en C18 fue que si una variable multibyte pertenece a dos bancos consecutivos (por supuesto) no funciona correctamente :? Por eso lo trabajé con punteros :D
El que tiene la división en bancos es la arquitectura PIC18, que con punteros se pueda acceder a toda la ram ese es otro cantar. Lo que tienen de ventajoso es que los registros especiales estan al final por lo tanto entre banco y banco no hay mas que ram de usuario y ram de usuario por eso se puede hacer de esta forma.
El uso de punteros entre bancos es necesario ya que necesitas si o si usar ambos FSRL y FSRH para poder traspasar el banco o mejor dicho "trabajar sin bancos". Ppor defecto C18 solo usa el FSR Low para hacer más ágil el código, mas optimizado y más veloz.
-
Saludos, Estoy usando un pic16f877a y lo estoy programando en MikroC, se me ha presentado un problema parecido al mencionado en este foro y es que una vez que he llegado a un porcentaje mayor al 50% de la memoria RAM al compilar me sale una advertencia que dice que la IRP debe ponerse en "1" para direccionamiento indirecto para "una determinada variable que puse digamos contador", mi pregunta es si alguien ha manejado MikroC y como puedo hacer para poder trabajar con toda la memoria....... les agradezco cualquier ayuda o consejo que puedan darme...