3 votos

Cómo crear un puntero a memoria de código en microchip C30

Tengo un pequeño problema con este código. El código pretende crear un MAPA LCD, con rutinas LCD para interconectar un LCD basado en 7 segmentos con el MCU PIC24FJ128GA310 con controlador LCD interno.

las matrices DIGIT1 a DIGIT6 contienen el mapeo del LCD para cada DIGIT de 7 segmentos en el LCD, y todas se guardan en la memoria de código.

el array DIGITS[] está pensado para contener la dirección de todos los arrays de segmentos de forma que se pueda utilizar un índice numérico con DIGIT[] para acceder a cada dígito de la pantalla LCD para su visualización.

enum COMS{COM0=0,COM1=0x40,COM2=0x80,COM3=0xC0};
enum SEGS
{//COM 0
    SEG_1A      = COM0 |0 , SEG_1B = COM0 |53, SEG_2A = COM0 |33, SEG_K1 = COM0 |44,
    SEG_K2      = COM0 |22, SEG_K8 = COM0 |21, SEG_4A = COM0 |62, SEG_4B = COM0 |61,
    SEG_5A      = COM0 |60, SEG_5B = COM0 |59, SEG_6A = COM0 |58, SEG_6B = COM0 |50,
    SEG_7A      = COM0 |61, SEG_7B = COM0 |48 ,SEG_8A = COM0 |59, SEG_8B = COM0 |26,
    SEG_9A      = COM0 |25, SEG_9B = COM0 |24, SEG_10A= COM0 |23, SEG_10B= COM0 |45,
    SEG_2B      = COM0 |52, SEG_3A = COM0 |32, SEG_3B = COM0 |51, SEG_S3 = COM0 |24,
//... LCD MAPS for COM1 - COM3 are ommited here for space
};

const BYTE DIGIT1[] = {SEG_1A,SEG_1B,SEG_1C,SEG_1D,SEG_1E,SEG_1F,SEG_1G};
const BYTE DIGIT2[] = {SEG_2A,SEG_2B,SEG_2C,SEG_2D,SEG_2E,SEG_2F,SEG_2G};
const BYTE DIGIT3[] = {SEG_3A,SEG_3B,SEG_3C,SEG_3D,SEG_3E,SEG_3F,SEG_3G};
const BYTE DIGIT4[] = {SEG_4A,SEG_4B,SEG_4C,SEG_4D,SEG_4E,SEG_4F,SEG_4G};
const BYTE DIGIT5[] = {SEG_5A,SEG_5B,SEG_5C,SEG_5D,SEG_5E,SEG_5F,SEG_5G};
const BYTE DIGIT6[] = {SEG_6A,SEG_6B,SEG_6C,SEG_6D,SEG_6E,SEG_6F,SEG_6G};
//...
const BYTE * Digits[] = {DIGIT1,DIGIT2,DIGI3,DIGIT4,DIGIT5,DIGIT6};

enum DIGITS {DIG1,DIG2,DIG3,DIG4,DIG5,DIG6,DIG7,DIG8,DIG9,DIG10};

enum MASK {
        ZERO = 0x3F, ONE = 0x06, TWO   = 0x5B, THREE = 0x4F, FOUR = 0x66,
        FIVE = 0x6D, SIX = 0x7C, SEVEN = 0x07, EIGHT = 0x7F, NINE = 0x67,
        BLANK= 0x00, MINUS = 0x40, OVERFLOW = 0x49,};

void DisplayDigit2(BYTE idx,BYTE Mask)
{
    const BYTE * digit;
    digit = Digits[idx];
    //BYTE vals;
    //vals = *digit;
    for(i=0; i<8;i++){
        DisplaySeg(digit,(Mask&1));
        digit++;//incrememt pointer
        Mask >>=1;
    }
}

La función DisplayDigit2() se llama así:

DisplayDigit2(DIG1,ONE);//Display 1 on the first digit of the LCD

El código se compila sin problemas, pero cuando intento recorrer el código, el compilador se detiene en la primera línea

digit = Digits[idx];

con el mensaje "Programa de usuario detenido"

Luego observo que en la ventana de vigilancia que la dirección de DIGIT1 en memoria de código es 0x48A, mientras que la de DIGIT2 es 0x491.

Pero al comprobar su dirección en el array DIGITS, veo los valores 0X848A, y 0x8491 para DIGIT1 y DIGIT2 respectivamente.

No sé exactamente en qué me equivoqué. enter image description here

5voto

Graza Puntos 3474

Se supone que Digits[] es constante y contiene punteros a punteros constantes, ¿no? Tal vez la precedencia de * aquí podría ser un problema y tal vez

const BYTE * Digits[] = {DIGIT1,DIGIT2,DIGI3,DIGIT4,DIGIT5,DIGIT6};

debe ser

const BYTE (*Digits)[] const = {DIGIT1,DIGIT2,DIGI3,DIGIT4,DIGIT5,DIGIT6};

http://en.wikipedia.org/wiki/Const-correctness

También sugiero añadir ese segundo "const". No creo que ese sea el problema, pero si hay un error que intenta cambiar Digits entonces eso podría ayudarte a encontrarlo. (BTW, podría ser útil intentar diferenciar más los nombres de tus variables -- la palabra "digit" se usa de muchas formas y sería fácil para alguien [especialmente un extraño como yo] confundir una con otra).

Por cierto, creo que has cometido una errata (¿no debería ser ++ y no **?)

digit**;//incrememt pointer

La forma en que suelo escribir una interfaz de pantalla de 7 segmentos es algo así:

// Human-readable bit values
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80

// Number of available positions on display
#define NUM_DIGITS 4

// Map symbols to segments
#define SYMBOL_0 (BIT0 | BIT1 | BIT2)
#define SYMBOL_1 (BIT0 | BIT5)
// (these are just examples -- not real mappings) 

// function prototypes
void display_number(int number);    // calls display_digit once per digit
void display_digit(unsigned char symbol, unsigned char position);    // writes symbol to one of the 7-segment positions
void display_refresh();    // Scans through each digit and illuminates segments again

const unsigned char digit_map[] = { SYMBOL_0, SYMBOL_1, ...}
unsigned char digits_being_displayed[NUM_DIGITS];

// (in main)
int x = 1234;
display_number(x);
// ...
// (in polling/timer loop)
display_refresh();

// (in display_number)
// Note: need to handle signs, convert number, etc. this is just for illustration
// ...
for (int pos=0; pos < NUM_DIGITS; pos++) {
    int i, temp = number;
    // get corresponding digit (depending on how you number your digits, this could be different)
    for (i=1; i<(pos+1); i++)
        temp /= 10;
    temp %= 10;
    switch (temp) {
        case 0:
            digit = SYMBOL_0;
            break;
        case 1:
            digit = SYMBOL_1;
            break;
        // ...
    }

    display_digit(digit_map[digit], pos); 
}

// ...

// (in display_digit)
digits_being_displayed[position] = value;  // this value can get written periodically to the display with display_refresh()

Así que no estoy muy familiarizado con la sintaxis / estructuras que está utilizando (por ejemplo, BYTE = {}), pero espero que mis comentarios siguen siendo útiles. Si te gusta enum mejor que #define que está bien también, por supuesto.

3voto

Jim Paris Puntos 2310

Luego observo que en el reloj gana memoria de código es 0x48A, mientras que la de DIGIT2 es 0x491.

Pero al comprobar su dirección en la matriz DIGITS, veo los valores 0X848A, y 0x8491 para DIGIT1 y DIGIT2 respectivamente.

Esto es normal. El PIC no es un espacio de memoria plano, así que necesitas alguna forma de marcar el hecho de que la dirección 0x12 en la memoria de código no es la misma que la dirección 0x12 en la SRAM, por ejemplo. El compilador utiliza bits altos extra para denotar esto.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X