limitaciones de memoria del microcontrolador PIC

1

Estoy intentando programar un PIC10f202 utilizando el compilador XC8 para comparar el valor de un temporizador con una variable que será una función de una tabla de consulta. Aquí hay un código de ejemplo:

#include <xc.h>

#pragma config MCLRE = OFF
#pragma config CP = OFF
#pragma config WDTE = OFF

Init(void){
    TRIS=0;
    GPIO=0;
    TMR0 = 0;
    OPTION = 0b00000011;
}

const unsigned char LUT[250] = {
0b00000000, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000001,
0b00000001, 0b00000001, 0b00000001, 0b00000010, 0b00000010,
0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b00000011,
0b00000011, 0b00000011, 0b00000011, 0b00000011, 0b00000100,
0b00000100, 0b00000100, 0b00000101, 0b00000101, 0b00000101,
0b00000110, 0b00000110, 0b00000110, 0b00000111, 0b00000111,
0b00001000, 0b00001000, 0b00001001, 0b00001001, 0b00001010,
0b00001010, 0b00001011, 0b00001100, 0b00001100, 0b00001101,
0b00001101, 0b00001110, 0b00001111, 0b00010000, 0b00010000,
0b00010001, 0b00010010, 0b00010011, 0b00010011, 0b00010100,
0b00010101, 0b00010110, 0b00010111, 0b00011000, 0b00011001,
0b00011010, 0b00011011, 0b00011100, 0b00011101, 0b00011110,
0b00011111, 0b00100000, 0b00100001, 0b00100010, 0b00100100,
0b00100101, 0b00100110, 0b00100111, 0b00101001, 0b00101010,
0b00101011, 0b00101100, 0b00101110, 0b00101111, 0b00110000,
0b00110010, 0b00110011, 0b00110101, 0b00110110, 0b00111000,
0b00111001, 0b00111011, 0b00111100, 0b00111110, 0b00111111,
0b01000001, 0b01000010, 0b01000100, 0b01000110, 0b01000111,
0b01001001, 0b01001011, 0b01001100, 0b01001110, 0b01010000,
0b01010001, 0b01010011, 0b01010101, 0b01010111, 0b01011000,
0b01011010, 0b01011100, 0b01011110, 0b01100000, 0b01100001,
0b01100011, 0b01100101, 0b01100111, 0b01101001, 0b01101010,
0b01101100, 0b01101110, 0b01110000, 0b01110010, 0b01110100,
0b01110110, 0b01111000, 0b01111001, 0b01111011, 0b01111101,
0b01111111, 0b10000001, 0b10000011, 0b10000101, 0b10000111,
0b10001000, 0b10001010, 0b10001100, 0b10001110, 0b10010000,
0b10010010, 0b10010100, 0b10010110, 0b10010111, 0b10011001,
0b10011011, 0b10011101, 0b10011111, 0b10100000, 0b10100010,
0b10100100, 0b10100110, 0b10101000, 0b10101001, 0b10101011,
0b10101101, 0b10101111, 0b10110000, 0b10110010, 0b10110100,
0b10110101, 0b10110111, 0b10111001, 0b10111010, 0b10111100,
0b10111110, 0b10111111, 0b11000001, 0b11000010, 0b11000100,
0b11000101, 0b11000111, 0b11001000, 0b11001010, 0b11001011,
0b11001101, 0b11001110, 0b11010000, 0b11010001, 0b11010010,
0b11010100, 0b11010101, 0b11010110, 0b11010111, 0b11011001,
0b11011010, 0b11011011, 0b11011100, 0b11011110, 0b11011111,
0b11100000, 0b11100001, 0b11100010, 0b11100011, 0b11100100,
0b11100101, 0b11100110, 0b11100111, 0b11101000, 0b11101001,
0b11101010, 0b11101011, 0b11101100, 0b11101101, 0b11101101,
0b11101110, 0b11101111, 0b11110000, 0b11110000, 0b11110001,
0b11110010, 0b11110011, 0b11110011, 0b11110100, 0b11110100,
0b11110101, 0b11110110, 0b11110110, 0b11110111, 0b11110111,
0b11111000, 0b11111000, 0b11111001, 0b11111001, 0b11111010,
0b11111010, 0b11111010, 0b11111011, 0b11111011, 0b11111011,
0b11111100, 0b11111100, 0b11111100, 0b11111101, 0b11111101,
0b11111101, 0b11111101, 0b11111101, 0b11111110, 0b11111110,
0b11111110, 0b11111110, 0b11111110, 0b11111110, 0b11111111};

unsigned char cnt1=0;

void main(){
        Init();
        for(;;){
            cnt1 = LUT[100];
            while(TMR0 > 100){
            GPIO=0b00000001;
            }
            GPIO=0b00000000;
        }
}

La tabla de consulta tiene 250 caracteres porque este es el tamaño máximo permitido por el compilador antes de que me diera un error. ". El código se compila bien, con MPLAB X que indica un uso de memoria flash del 55% y un uso de memoria RAM del 0%. Si cambio la condición "while" a esto:

while(TMR0 > cnt1)

El compilador nuevamente me dará un error similar: "No puedo encontrar las palabras x0FA (x0fa withtotal) para el psect" stringtext1 "en la clase" Entrada "". Entiendo que el compilador no puede encontrar suficiente memoria para escribir el código, pero no veo que el 45% de espacio libre no sea suficiente para esta tarea. Además, ¿por qué no puedo crear una matriz con 255 elementos? El PIC10f202 tiene 512 palabras de memoria, debería ser posible.

¿Por qué el compilador está dando esos errores?

    
pregunta jul059

4 respuestas

3

Este es un ejemplo perfecto de cómo usar ciegamente un compilador en un sistema pequeño de recursos limitados sin comprender realmente las limitaciones de la máquina puede causarle problemas.

Primero, observe cómo se debería implementar una tabla de constantes en la memoria del programa. Ve a leer la hoja de datos. No, en serio, ve a leerlo. ¿Cómo se haría esta necesidad también? ¿Ve alguna forma de leer la memoria del programa, como un mecanismo de lectura de tabla que tienen otros PIC? La única forma de eliminar constantes de la memoria del programa es con instrucciones que contengan literales. ¿Cómo implementar una tabla con eso? No, en realidad, piense en esto antes de seguir leyendo. Echa un vistazo a la lista de instrucciones. La única forma de implementar una tabla de búsqueda es con la instrucción RETLW. Eso significa que básicamente hace una llamada de subrutina a la entrada de la tabla, que devuelve el valor de esa entrada en W. Ahora mire el mecanismo de llamada de subrutina. Después de haber realizado la lectura que debe tener antes de escribir la primera línea de código, debe ser obvio por qué no puede tener más de 256 entradas de tabla, y algunas de esas posibles entradas de tabla deben utilizarse para el código.

Demuestre que ha leído un poco la hoja de datos y puedo entrar en más detalles.

    
respondido por el Olin Lathrop
2

Como los números en la LUT no son únicos, los números aumentan de forma monótona y, de hecho, los cambios parecen bastante escasos, ¿es posible escribir una función pequeña para reemplazar la LUT?

por ejemplo, y = x > = 1 + x > = 23 + .....

Lo dejaré para que averigües cuánta memoria, si hay, se puede guardar de esta manera.

Quizás hay otros métodos que utilizan técnicas dispersas que también podrían ayudar, tal vez almacenar los valores únicos y diferentes de x donde ocurren las transiciones.

    
respondido por el Scott Seidman
0

PIC10f202 tiene 24 bytes de RAM y 750 bytes de flash, de acuerdo a este resumen de Microchip. Si es posible mantener y ejecutar una tabla en flash, puede ajustar un pequeño programa utilizando el resto de la memoria del programa. Pero no veo nada en la declaración de su tabla que parezca una directiva para usar flash, y la tabla ahora tiene aproximadamente 12 veces el tamaño de la RAM disponible, incluso si no hubiera ninguna otra demanda (como la pila ...) .

    
respondido por el JRobert
0

No he marcado todas las entradas en la tabla, pero parece que las entradas solo cambian en 1 (después de varias entradas en una fila que son iguales). Creo que, en cambio, podría reorganizar la tabla de la siguiente manera, en la que cada intervalo es el punto en el que el valor en la tabla anterior aumenta.

const unsigned char LUT[nn] = {
0, 23, 29, 34, ...

El índice en la nueva tabla es el valor con el que habría coincidido antes (ahora es una búsqueda de tabla), y el valor devuelto de la tabla es el mismo que el índice que habría estado en la tabla anterior.

Debería ser mucho más rápido, y la tabla será mucho más corta.

    
respondido por el tcrosley

Lea otras preguntas en las etiquetas