Manipulación de matrices en MCC18

1

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 de esta manera:

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 se deba acceder a la matriz al señalar su primer elemento mediante el uso de punteros.

¿Obtuve este derecho o cómo accedo a mi matriz I_1 ?

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

Gracias.

    
pregunta Buhake Sindi

2 respuestas

3

hunch

Sospecho que el problema está aquí:

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

Dado que cada flotador usa 4 bytes y cada doble usa 8 bytes, esto es asignar una única matriz que utiliza más de 2 000 bytes de RAM.

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

Así que debes

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

o alguna combinación de lo anterior.

otros comentarios

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

Aunque hacerlo de esta manera puede ser muy educativo, es innecesariamente complicado y por lo general hay una forma más simple y mejor de obtener el resultado final deseado. (Hay casos en los que necesitas 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 donde las cosas parecen ir 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á mal 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 en un solo paso a través de esas líneas más pequeñas y simples para reducir dónde está el problema. Quizás 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 exhibe el mismo error.

¿Podría recortar las partes de su programa antes y después de la línea que hace algo inesperado? quizás configurando las variables antes de esa línea a un valor constante en lugar de realizar largas series de cálculos, para darnos un muy breve , pero programa completo que da el comportamiento inesperado?

    
respondido por el davidcary
1

"Memoria restringida y scripts de vinculador"

Según las personas en Internet a b c normalmente cuando usas el depurador ICD, el compilador usa el script del enlazador 'i' especial para asegurarse de que la memoria RAM utilizada por el depurador no entra en conflicto con la memoria RAM utilizada por su programa. Le dices al compilador que haga eso por configurando el menú desplegable Debug / Release en la barra de herramientas IDE en "Debug"; y luego reconstruir y reprogramar el chip.

Si lo has configurado de forma incorrecta (en "Liberar"), y luego intentas depurar, aparece un mensaje de "Memoria restringida".

"pointers"

ps: En otra parte de Internet a b Veo que alguien repite la afirmación de que el acceso a la matriz" debe hacerse mediante punteros ", seguido por otra persona que dice que el acceso a la matriz normal funciona bien con el compilador MC C18 - no hay necesidad de jugar con los punteros.

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

"buffers grandes y scripts de vinculador"

"Crea un gran búfer en una pic18f con microchip El compilador c18 " menciona la edición de un script de vinculador.

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

¿Es posible que haya modificado accidentalmente el script del vinculador de tal manera que su programa intente utilizar ubicaciones "RAM" que no existen físicamente en su chip?

    
respondido por el davidcary

Lea otras preguntas en las etiquetas