Ошибка при объявлении переменных в EEPROM

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 16
Зарегистрирован: Пн окт 19, 2015 09:19:16

Сообщение Auratos »

Добрый день. Имеется контроллер ATmega88 и среда разработки CodeVisionAVR v3.29. Работаю с проектом, созданным до меня. В нем есть 6 переменных, которые необходимо хранить в EEPROM. Объявлены и используются они только в файлах - Sharp.c, def.c и def.h.
Вот все строки кода, где они упоминаются:
def.h
Спойлер

Код: Выделить всё

#ifndef _DEF_INCLUDED_
#define _DEF_INCLUDED_

#include <mega88.h>
#include <string.h>
#include <stdio.h>
#include <delay.h>  
#include <stdlib.h>

#pragma used+
#pragma used-

#define Detector1_ADC_Ch    0b00
#define Detector2_ADC_Ch    0b01

#define ADC_VREF_TYPE       0x40      
#define POROG1_Def          110     // пороговое значение АЦП по умолчанию (1 канал)
#define POROG2_Def          110     // пороговое значение АЦП по умолчанию (2 канал) 
#define GESTEREZIS          3

//  код настройки параметров последовательного интерфейса:
//	Init_UART = скорость + количество бит + количество стоповых + проверка
//	скорость: 0 - 1200, 1 - 2400, 2 - 4800, 3 - 9600, 4 - 19200, 5 - 38400 , 6 - 76800, 7 - 115200;
//	количество бит: 0 - 8 бит, 128 - 9 бит;
//	количество стоповых: 0 - 1 стоповый бит, 64 - 2 стоповых;
//	проверка: 0 - нет, 32 - even, 48 - odd
#define Init_UART 0x03

typedef unsigned char BYTE;
typedef unsigned int UINT16;
typedef unsigned long UINT32;

//параметры настроек ИК
extern eeprom BYTE n_drebezgRAM;
extern eeprom BYTE n_periodRAM;
extern eeprom BYTE n_zalipanieRAM;
extern eeprom BYTE vremya_otkrytiyaRAM;
extern eeprom BYTE POROG1;
extern eeprom BYTE POROG2;

extern BYTE fl_NewMeasureCycle;
extern bit fl_Debug;
extern UINT16  Detector1_midle;
extern UINT16  Detector2_midle;

void Init(void);
UINT16 Read_ADC(BYTE adc_input);
void Setup_Adress(void);
#endif
def.c
Спойлер

Код: Выделить всё

#include "def.h"

bit     fl_Debug = 0;           // флаг DEBUG  
BYTE    fl_NewMeasureCycle;      // флаг "Новый цикл измерений"
UINT16  Detector1_midle = 0;
UINT16  Detector2_midle = 0; 

// настройки ИК-датчика
eeprom BYTE n_drebezgRAM;
eeprom BYTE n_periodRAM;
eeprom BYTE n_zalipanieRAM;
eeprom BYTE vremya_otkrytiyaRAM;
eeprom BYTE POROGSTART1;
eeprom BYTE POROGSTART2;

//  Инициализация Глобальных переменных
void Init(void)
{
    fl_Debug = 0;
    Init_Com0(Init_UART);   // настройка UART на 9600,1,n 
              
    if ((n_drebezgRAM == 0xFF) || (n_periodRAM == 0xFF) || (n_zalipanieRAM == 0xFF) || (vremya_otkrytiyaRAM == 0xFF))
    {
        n_drebezgRAM = 150;
        n_periodRAM = 150;
        n_zalipanieRAM = 10;
        vremya_otkrytiyaRAM = 10;
    }
    fl_NewMeasureCycle = 0;  
}

void Setup_Adress(void)
{       
    BYTE temp = 0;
    BYTE adress = 0;
    fl_Debug = !Dip1;
    if (fl_Debug)
    { 
        POROG1 = 0;
        POROG2 = 0;  
        temp = PINB;                   
        temp &= 0x02;         
        if (!temp) //режим автокалиброки
        {
            Detector1_midle = Read_ADC(Detector1_ADC_Ch);
            Detector1_midle += Read_ADC(Detector1_ADC_Ch);
            Detector1_midle += Read_ADC(Detector1_ADC_Ch);
            Detector1_midle += Read_ADC(Detector1_ADC_Ch);
            Detector1_midle += Read_ADC(Detector1_ADC_Ch); 
            Detector1_midle /= 5;  
            if ((Detector1_midle > 100) && (Detector1_midle < 250)) POROG1 = Detector1_midle;   
                    
            Detector2_midle = Read_ADC(Detector1_ADC_Ch);
            Detector2_midle += Read_ADC(Detector1_ADC_Ch);
            Detector2_midle += Read_ADC(Detector1_ADC_Ch);
            Detector2_midle += Read_ADC(Detector1_ADC_Ch);
            Detector2_midle += Read_ADC(Detector1_ADC_Ch); 
            Detector2_midle /= 5;         
            if ((Detector2_midle > 100) && (Detector2_midle < 250)) POROG2 = Detector2_midle;
                    
            while(1)
            {
                #asm("wdr")     // сброс WDT 
                Led1_On;
                Led2_On;
            }
        }
    }
}
Sharp.c
Спойлер

Код: Выделить всё

#include "def.h"
BYTE a = 0;

void main(void)
{
    InitMK();               // инициализация МК
    Init();                 // Инициализация переменных        

    while (1)
    {
        #asm("wdr")     // сброс WDT 
        if (fl_NewMeasureCycle) //если наступил новый цикл измерений. Цикл кратен 1ms
        {
            Detector1_midle = Read_ADC(Detector1_ADC_Ch);
            Detector2_midle = Read_ADC(Detector2_ADC_Ch);    
                                  
            if (Detector1_midle > (POROG1 + GESTEREZIS)) a++;
            if (Detector1_midle < (POROG1 - GESTEREZIS)) a++;            
            if (Detector2_midle > (POROG2 + GESTEREZIS)) a++;
            if (Detector2_midle < (POROG2 - GESTEREZIS)) a++;
            
            fl_NewMeasureCycle = 0; //сбрасываем флаг 
        }
    };
}
Так вот, когда делаю сборку проекта, компилятор говорит о наличии 2 ошибок (external 'POROG1' declared, but never defined) в строках:

Код: Выделить всё

extern eeprom BYTE POROG1;
extern eeprom BYTE POROG2;
Текст ошибки я понял, но не пойму, почему эта ситуация возникла, и как ее исправить. Почему ругается именно на эти два параметра, а первые 4 пропустил? Подскажите, пожалуйста, варианты решения
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

а на что они ссылаются? например в def.c они вроде не объявлены, зато объявлены порогстарт..
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Сообщение viiv »

[uquote="Auratos",url="/forum/viewtopic.php?p=3291381#p3291381"]Текст ошибки я понял, но не пойму, почему эта ситуация возникла, и как ее исправить.[/uquote]
Вы точно поняли текст? Тогда ткинте меня носом в то место, где определяются переменные POROG1 и POROG2. Скорей всего Вы не понимаете разницы между декларацией и определением переменной.

Код: Выделить всё

extern eeprom BYTE POROG1;
Декларация: эй, компилятор. Когда встретишь POROG1, не ругайся - тип переменной BYTE, она будет определена гдето еще (в другом файле). Ее адрес будет определен на этапе линковки.

Код: Выделить всё

eeprom BYTE POROG1;
Определение: компилятор, зарезервируй место в eeprom, размером соответсвующему типу BYTE. Сделай данную переменную глобальной, чтобы линкер мог подставить адрес этой области во всех местах (в том чиосле и других файлах), где исползуется данная переменная.
Родился
Сообщения: 16
Зарегистрирован: Пн окт 19, 2015 09:19:16

Сообщение Auratos »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3291392#p3291392"]а на что они ссылаются? например в def.c они вроде не объявлены, зато объявлены порогстарт..[/uquote]
Вы не поверите, но я реально не заметил этот косяк. Я раз сто проходил мимо, перепроверил все: от eeprom до BYTE, но не увидел, что имена разные у переменных :))
Реклама
Эиком - электронные компоненты и радиодетали
Ответить

Вернуться в «AVR»