Могу ли я получить доступ к объединению в моем source.c из main.c в PIC C18? - PullRequest
0 голосов
/ 05 декабря 2018

Я нахожусь в положении, в котором у меня есть анонимная структура, содержащая несколько элементов.Чтобы получить к ним доступ по индексу, я поместил их в объединение, например:

union
{
    struct
    {
        unsigned char COMMAND;      //STRUCT_ARRAY[0]
        unsigned char ADDR_H;       //STRUCT_ARRAY[1]
        unsigned char ADDR_M;       //STRUCT_ARRAY[2]
        unsigned char ADDR_L;       //STRUCT_ARRAY[3]
        unsigned char DATA;         //STRUCT_ARRAY[4]
        unsigned char CHECKSUM;     //STRUCT_ARRAY[5]
    };
    unsigned char STRUCT_ARRAY[6];
    //all of the struct members can be accessed from STRUCT_ARRAY by index
}MY_UNION;

Это объединение в настоящее время находится в файле source.c.Мне нужно получить к нему доступ с main.c.У меня есть заголовок, который включает оба файла, давайте назовем его header.h.

Как я могу прочитать значение, например, ADDR_H и ADDR_M в main.c, периодически изменяя его из источника.c?

Код работает примерно так:

source.c:

#include "header.h"

union
{
    struct
    {
        unsigned char COMMAND;      //STRUCT_ARRAY[0]
        unsigned char ADDR_H;       //STRUCT_ARRAY[1]
        unsigned char ADDR_M;       //STRUCT_ARRAY[2]
        unsigned char ADDR_L;       //STRUCT_ARRAY[3]
        unsigned char DATA;         //STRUCT_ARRAY[4]
        unsigned char CHECKSUM;     //STRUCT_ARRAY[5]
    };
    unsigned char STRUCT_ARRAY[6];
    //all of the struct members can be accessed from STRUCT_ARRAY by index
}MY_UNION;

void modify(void)
{
    MY_UNION.ADDR_H = somevalue;
    MY_UNION.ADDR_M = somevalue;
    MY_UNION.ADDR_L = somevalue;
}

В main.c:

#include "header.h"

void main(void)
{
    modify();
    print(MY_UNION.ADDR_H);    //custom function to print values to a screen
    print(MY_UNION.ADDR_M);
    print(MY_UNION.ADDR_L);
}

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Фундаментальный дизайн программы:

  • Никогда не объявляйте переменные в заголовочных файлах.
  • Никогда не используйте программирование спагетти с extern.
  • .такой как эта структура протокола вне модуля перевода, который обрабатывает протокол.Вы должны иметь слой абстракции между ними.

Быстрое и грязное решение:

  • Измените определение объединения в файле h на typedef:

    typedef union 
    {
        struct
        {
            unsigned char COMMAND;      //STRUCT_ARRAY[0]
            unsigned char ADDR_H;       //STRUCT_ARRAY[1]
            unsigned char ADDR_M;       //STRUCT_ARRAY[2]
            unsigned char ADDR_L;       //STRUCT_ARRAY[3]
            unsigned char DATA;         //STRUCT_ARRAY[4]
            unsigned char CHECKSUM;     //STRUCT_ARRAY[5]
        };
        unsigned char STRUCT_ARRAY[6];
        //all of the struct members can be accessed from STRUCT_ARRAY by index
    } MY_UNION;
    
  • Объявление фактической переменной локально в файле .c: static MY_UNION my_union;.

  • Доступ к переменной с помощью метода установки / получения, пример:

    uint8_t get_address_h (void)
    {
      return my_union.ADDR_H;
    }
    
    void set_address_h (uint8_t addr_h)
    {
      my_union.ADDR_H = addr_h;
    }
    

Правильное решение:

В правильной программе вы должны полностью скрывать внутренние части этого протокола от других файлов, включая typedef union.

Никто, кроме преобразователя протокола, не должен получить доступ к этому объединению.У вас будут такие функции, как set_address, set_data и т. Д., О которых звонящий может знать, не зная внутренних компонентов протокола.

0 голосов
/ 05 декабря 2018

Самый простой способ - определить объединение

в header.h

typedef union
{
    struct
    {
        ...
    };
    unsigned char STRUCT_ARRAY[6];
}MyUnionType;

extern MyUnionType MY_UNION;

Затем в source.c определить переменную

MyUnionType MY_UNION;

Эта переменная теперь может использоваться в любом исходном файле.(main.c и т. д.)

...