Перейти к содержанию
    

Ошибка компиляции

Помогите разобраться с ошибкой.

При чтении данных с EEPROMa в переменную, данные оказываются в RAM по другому адресу.

 

Описание проблемы:

В main.c, по флагу вызывается функция, которая читает

данные из EEPROMa в глобальную переменную.

    if(DevFlag.ReadDataEE) {
    ReReadDataEE();
    }

Флаг вызова ф-ии устанавливается в прерывании.

Структура(флаги) объявлена main.c:

typedef struct
    {
    volatile u_char
    Regim12        :1,    //
    ...
    ReadDataEE    :1,    //считать с EEPROMa
    ...
    }dev_fl;

dev_fl        DevFlag;

u_int ContrValueData, ContrValueTest;

 

В функции очищается флаг вызова функции и читаются данные.

Если флаг очищается сразу после входа в функцию, то данные пишутся по другому адресу.

Если если перед выходом из ф-ии, то по адресу переменной(правильно).

 

В чем ошибка?

Функция чтения данных:

void ReReadDataEE(void)
{
//если сброс флага здесь, то ошибка в адресе записи в RAM
    __disable_interrupt();
    DevFlag.ReadDataEE = 0;
    __enable_interrupt();

    if(!DevFlag.Regim12) {
    ContrValueData = ReadIntDataEE(ADR_DATA1_EE);
    ContrValueTest = ReadIntDataEE(ADR_DATA2_EE);
    }
    else {
    ContrValueData = ReadIntDataEE(ADR_DATA12_EE);
    }

//если сброс флага здесь, то ошибки нет
/*    __disable_interrupt();
    DevFlag.ReadDataEE = 0;
    __enable_interrupt();        */
}

Расположение переменных из map файла:

ContrValueTest                  DATA 0000007E
ContrValueData                   DATA 0000007C
TimerData                        DATA 0000007A

//------------------------------------------------------------------------------

Листинг 1, с ошибкой:

    312          void ReReadDataEE(void)
   \                     ReReadDataEE:
    313          {
   \   00000000   93AA               ST      -Y, R26
    314                  //если сброс флага здесь, то ошибка в адресе записи в RAM
    315              __disable_interrupt();
   \   00000002   94F8               CLI
    316              DevFlag.ReadDataEE = 0;
   \   00000004   ....               LDI     R26, (TimerData + 8) & 0xFF
   \   00000006   910C               LD      R16, X
   \   00000008   ....               LDI     R26, (TimerData) & 0xFF
   \   0000000A   7F07               ANDI    R16, 0xF7
   \   0000000C   930C               ST      X, R16
    317              __enable_interrupt();    
   \   0000000E   9478               SEI
    318          
    319              if(!DevFlag.Regim12) {
   \   00000010   910C               LD      R16, X
   \   00000012   FD00               SBRC    R16, 0
   \   00000014   C009               RJMP    ??ReReadDataEE_0
    320              ContrValueData = ReadIntDataEE(ADR_DATA1_EE);
   \   00000016   E007               LDI     R16, 7
   \   00000018   ....               RCALL   ReadIntDataEE
   \   0000001A   ....               LDI     R26, (TimerData - 6) & 0xFF    //вот здесь задается ошибочный адрес
   \   0000001C   930D               ST      X+, R16
   \   0000001E   931C               ST      X, R17
    321              ContrValueTest = ReadIntDataEE(ADR_DATA2_EE);
   \   00000020   E003               LDI     R16, 3
   \   00000022   ....               RCALL   ReadIntDataEE
   \   00000024   ....               LDI     R26, (TimerData - 4) & 0xFF
   \   00000026   C003               RJMP    ??ReReadDataEE_1
    322              }
    323              else {
    324              ContrValueData = ReadIntDataEE(ADR_DATA12_EE); //
   \                     ??ReReadDataEE_0:
   \   00000028   E00B               LDI     R16, 11
   \   0000002A   ....               RCALL   ReadIntDataEE
   \   0000002C   ....               LDI     R26, (TimerData - 6) & 0xFF
   \                     ??ReReadDataEE_1:
   \   0000002E   930D               ST      X+, R16
   \   00000030   931C               ST      X, R17
    325              }
    326          }
   \   00000032   91A9               LD      R26, Y+
   \   00000034   9508               RET

 

Листинг 2, без ошибки:

    312          void ReReadDataEE(void)
   \                     ReReadDataEE:
    313          {
   \   00000000   93AA               ST      -Y, R26
    314              if(!DevFlag.Regim12) {
   \   00000002   ....               LDI     R26, (TimerData + 8) & 0xFF
   \   00000004   910C               LD      R16, X
   \   00000006   FD00               SBRC    R16, 0
   \   00000008   C009               RJMP    ??ReReadDataEE_0
    315              ContrValueData = ReadIntDataEE(ADR_DATA1_EE);
   \   0000000A   E007               LDI     R16, 7
   \   0000000C   ....               RCALL   ReadIntDataEE
   \   0000000E   ....               LDI     R26, (TimerData + 2) & 0xFF
   \   00000010   930D               ST      X+, R16
   \   00000012   931C               ST      X, R17
    316              ContrValueTest = ReadIntDataEE(ADR_DATA2_EE);
   \   00000014   E003               LDI     R16, 3
   \   00000016   ....               RCALL   ReadIntDataEE
   \   00000018   ....               LDI     R26, (TimerData + 4) & 0xFF
   \   0000001A   C003               RJMP    ??ReReadDataEE_1
    317              }
    318              else {
    319              ContrValueData = ReadIntDataEE(ADR_DATA12_EE); //
   \                     ??ReReadDataEE_0:
   \   0000001C   E00B               LDI     R16, 11
   \   0000001E   ....               RCALL   ReadIntDataEE
   \   00000020   ....               LDI     R26, (TimerData + 2) & 0xFF
   \                     ??ReReadDataEE_1:
   \   00000022   930D               ST      X+, R16
   \   00000024   931C               ST      X, R17
    320              }
    321                  //если сброс флага здесь, то ошибки адреса нет
    322              __disable_interrupt();
   \   00000026   94F8               CLI
    323              DevFlag.ReadDataEE = 0;
   \   00000028   ....               LDI     R26, (TimerData + 8) & 0xFF
   \   0000002A   910C               LD      R16, X
   \   0000002C   ....               LDI     R26, (TimerData) & 0xFF
   \   0000002E   7F07               ANDI    R16, 0xF7
   \   00000030   930C               ST      X, R16
    324              __enable_interrupt();    
   \   00000032   9478               SEI
    325          }
   \   00000034   91A9               LD      R26, Y+
   \   00000036   9508               RET

 

Компилятор IAR 5.30, контроллер tiny26. Оптимизация максимальная, по скорости.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

листинги нечитаемые.

 

ну а по проблеме - дело скорее всего в том, что надо обеспечить атомарность для всего байта структуры в который попал флаг ReadDataEE (модифицируемый в прерывании).

либо ReadDataEE сделать байтом, а не битом в структуре, потому как пока он бит, то все операции записи этого флага делаются как Read-Modify-Write для БАЙТА и затрагивают еще 7 бит вашей структуры.

 

PS: Никакой ошибки компиляции тут нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...