Manipulación de matriz en MCC18

Supongamos que tengo una matriz:

#define ARRAY_SIZE 576
#pragma udata DATA
float I_1[ARRAY_SIZE]; //My huge array
#pragma udata

Y que accedo a mi matriz así:

float compute()
{
    float *I_1_ptr = &I_1[0];
    //Somewhere in loop
    I_1_ptr[i] = IL_1 - IO_1 * (exp(Q * V_1/ (NS * N * K * temperature)) - 1.0) - V_1/Rsh;
    //Consider other variables constants.

    return (I_1_ptr[0] + I_1_ptr[1] + I_1_ptr[2] + I_1_ptr[3]);
}

He visto en los resultados de búsqueda en Google que Microchip prefiere que uno acceda a la matriz apuntando a su primer elemento usando punteros.

¿Lo hice bien o cómo accedo a mi matriz I_1?

Por alguna razón, mi cálculo no funciona en mi matriz y cuando hago una división por cero, obtengo NaN.

Gracias.

Un poco fuera de tema: ¿Dónde leíste que se prefieren los punteros? Todas mis búsquedas apuntan a que deben evitarse, pero por lo que puedo ver aquí, debido a la longitud de la matriz, deben usarse o ideben ser enteros. Si ino es un número entero, podría tener problemas allí porque C18 no promocionará los caracteres a tipos superiores de forma predeterminada.
También verifique si eso #define ARRAY_SIZE 576realmente está usando int allí. Es posible que deba agregar un sufijo para que sea int por si acaso. Otra cosa a considerar sería dividir la línea donde se calcula I_1_ptr en varias y verificar cada una con el depurador para ver qué sucede exactamente.
cuando hago una división por cero, obtengo NaN. Sí, eso es lo que se supone que sucederá con los flotadores que está utilizando.
@AndrejaKo, vea ejemplos ( electro-tech-online.com/microcontrollers/… o microchip.com/forums/m470067.aspx ). Perdí el enlace del tutorial que vi. Usan punteros para hacer referencia a la matriz.
@davidcary, lo sé. Estoy tratando de averiguar por qué no hay valores en mi matriz.

Respuestas (2)

corazonada

Sospecho que el problema está aquí:

#define ARRAY_SIZE 576
float I_1[ARRAY_SIZE]; //My huge array

Dado que cada flotante usa 4 bytes y cada doble usa 8 bytes, esto está asignando una sola matriz que usa más de 2 000 bytes de RAM.

El PIC18F4520 tiene 1 536 bytes de RAM; no es suficiente para almacenar toda la matriz, mucho menos esa matriz más todas las demás variables utilizadas en su programa.

entonces debes

  • actualice a una MCU más grande con más RAM en el chip, o
  • de alguna manera adjuntar algún tipo de RAM fuera del chip, o
  • descubra una manera de usar menos RAM (quizás un ARRAY_SIZE más pequeño, o quizás usando algún tipo de datos de 16 bits u 8 bits que requiera menos RAM por elemento en la matriz, o tal vez de alguna manera almacenar algunos de esos datos en FLASH, o . ..)

o alguna combinación de los anteriores.

otros comentarios

Muchos profesores del lenguaje de programación C dedican mucho tiempo a explicar que se puede acceder a las matrices mediante punteros. Al igual que muchos profesores de química, pasan mucho tiempo explicando cómo se pueden construir moléculas a partir de átomos individuales. Al igual que muchos profesores de física, pasan mucho tiempo explicando cómo se pueden construir átomos a partir de protones y neutrones individuales.

Si bien hacerlo de esa manera puede ser muy educativo, es innecesariamente complicado y, por lo general, existe una forma mejor y más simple de obtener el resultado final deseado. (Hay casos en los que necesita usar punteros, pero este no parece ser uno de ellos).

Una habilidad importante en la depuración es tomar un programa con un error conocido y descubrir el paso exacto en el que las cosas parecen salir mal.

Parece que piensas que el problema está en línea

I_1_ptr[i] = IL_1 - IO_1 * (exp(Q * V_1/ (NS * N * K * temperature)) - 1.0) - V_1/Rsh;

Esa línea hace muchas cosas. Es difícil para un depurador de un solo paso averiguar exactamente qué cosa está fallando en una línea tan complicada. Si tuviera este problema, mi primera acción sería dividir esa línea en un grupo de líneas más pequeñas y luego pasar de un solo paso a través de esas líneas más pequeñas y simples para delimitar dónde está el problema. Tal vez algo como

float denominator;
float ratio;
float temp1;
float temp2;
//...
denominator = NS * N * K * temperature;
ratio = Q * V_1 / denominator;
temp_1 = exp(ratio) - 1.0;
temp_2 = IL_1 - IO_1 * temp_1 - V_1/Rsh;
I_1[i] = temp2; // normal array access -- pointers not necessary here.

y compruebe que está obteniendo los valores esperados en cada paso. ¿Qué paso está dando resultados inesperados?

Una habilidad importante en la depuración es reducir un programa grande con un error conocido a un programa muy pequeño que presenta el mismo error.

¿Podría recortar las partes de su programa antes y después de la línea que hace algo inesperado, tal vez estableciendo variables antes de esa línea en un valor constante en lugar de pasar por una larga serie de cálculos, para darnos un resumen muy breve pero completo? programa que da el comportamiento inesperado?

gracias, el problema es que cuando "observo" mi I_1matriz, MPLAB dice "memoria restringida". Sin embargo, a menos que sepa que hay datos allí, no puedo verlos.
¿Qué sucede cuando reduce "ARRAY_SIZE" a un número pequeño como "4"?
Todavía tenía "Memoria restringida", creo que es porque lo tenía activado udata. Eliminarlo de udata ayuda (en un tamaño de matriz pequeño, pero necesitamos la matriz grande). Alternativamente, puedo probar y rediseñar la solución sin matriz. :-)

"Memoria restringida y secuencias de comandos del enlazador"

Según la gente en Internet a b c , normalmente cuando usa el depurador ICD, el compilador usa la secuencia de comandos especial del enlazador 'i' para asegurarse de que la RAM utilizada por el depurador no entre en conflicto con la RAM utilizada por su programa. Le dice al compilador que lo haga configurando el menú desplegable Depurar/Liberar en la barra de herramientas del IDE en "Depurar"; y luego reconstruir y reprogramar el chip.

Si lo tiene configurado de manera incorrecta (en "Liberar") y luego intenta depurar, obtendrá un mensaje de "Memoria restringida".

"punteros"

pd: en otro lugar de Internet a b veo que alguien repite la afirmación de que el acceso a la matriz "debe hacerse mediante punteros", seguido de otra persona que dice que el acceso normal a la matriz funciona bien con el compilador MC C18, no es necesario jugar con los punteros .

Me apegaría al acceso estándar normal a la matriz C a menos que me viera obligado a usar un compilador que tuviera algún tipo de error que me obligara a usar una solución alternativa. (Me imagino que una versión anterior de ese compilador podría haber tenido un error de este tipo, pero lo solucionaron hace años: esas soluciones alternativas antiguas ahora son obsoletas y contraproducentes).

"grandes búferes y secuencias de comandos de vinculación"

"Crear un gran búfer en un pic18f con el compilador microchip c18" menciona la edición de un script de vinculación.

¿Es posible que haya modificado accidentalmente la secuencia de comandos del enlazador de tal manera que la RAM utilizada por su programa ahora entre en conflicto con la RAM utilizada por el depurador?

¿Es posible que haya modificado accidentalmente la secuencia de comandos del enlazador de tal manera que su programa intente usar ubicaciones de "RAM" que no existen físicamente en su chip?