Easyelectronics.ru

Электроника для всех
Текущее время: 14 дек 2018, 08:16

Часовой пояс: UTC + 5 часов




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
 Заголовок сообщения: <avr/eeprom.h>
СообщениеДобавлено: 04 мар 2018, 04:05 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 17 сен 2011, 11:02
Сообщения: 30
Откуда: Бурятия
Кто-нибудь использовал <avr/eeprom.h>? В Atmel Studio. Если конкретно - 7я.

Суть проблемы:
Библиотека подключена в main.h ( #include <avr/eeprom.h> ).

Если объявляю переменные EEMEM в main.c ( uint16_t freq2e EEMEM; //= 5000; ), то всё работает.
Но работает только в main.c и не работает в другом файле проекта: " 'freq2e' undeclared (first use in this function) ".

Если объявляю переменные EEMEM в main.h ( uint16_t freq2e EEMEM; //= 5000; ), то ругается на мультиопределение: " multiple definition of `freq2e' ".
Уточняю, - никакого собственно "мульти" нет. Если тупо затереть в объявлении EEMEM ( uint16_t freq2e; //= 5000; ) - всё ровно.

Вопрос:
Как правильно работать с <avr/eeprom.h> и переменными EEMEM ? В многофайловом проекте.

Я на другом форуме был... Там, похоже одни STMщики. Может здесь ещё не все забыли как выглядят восемь бит? :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: <avr/eeprom.h>
СообщениеДобавлено: 04 мар 2018, 09:09 
Старожил
Аватара пользователя

Зарегистрирован: 17 апр 2010, 08:38
Сообщения: 4865
Откуда: Усинск, республика Коми
Как и со всеми другими переменными. Это не особенности конкретно AVR, это особенности объявления переменных. Для более глубокого познания курить тему "Область видимости переменных в языке С".

_________________
хаос это непознанный порядок


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: <avr/eeprom.h>
СообщениеДобавлено: 04 мар 2018, 09:45 
Старожил
Аватара пользователя

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 577
Курим ключевое слово extern.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: <avr/eeprom.h>
СообщениеДобавлено: 04 мар 2018, 10:01 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2585
Тут дело не в восьми битах, а вообще в подходе.
На том форуме вроде ж вам поясняли, что у вас множественные определения, и искать их надобно в неправильных подключениях.
Разбирая скрин ошибок с третьей страницы той темы, видим, что у вас freq2e первый раз прописан в файле adc.c Кстати, а как там обстоит дело с русскими буквами и пробелами в пути файла??? Лучше бы от них избавиться. Положите проект в C:\Projects\ чтобы устранить лишние сомнения. Давно пора уже уяснить, что пробелы и национальные алфавиты в путях - гиблое дело.
Далее, эта же переменная встречается в файле eeprom.c, и еще раз в encoders.c
Вам же на том форуме -дцать раз рассказали, что надо либо писать extern перед объявлением переменной, либо один раз прописать ее в заголовке и подключать заголовки. Ну а чеж вы не догоняете чтоль?

По первому скрину в теме вы помещаете эти переменные в файл main.h, и вероятно его подключаете к main.c.
.... И вообще, помоему, вам там очень доходчиво объяснили, чего и как должно быть с подключениями.
Уберите банально дублирование переменных, ебенский бох! Либо уберите их из main.h, и поместите их в main.c, а в остальных .c файлах объявите используемые переменные как extern uint16_t freq1 , либо... ну блин, еще раз расписывать то, что вам подробно расписали уже, чтоль?

Ну или выложите целиком все файлы, это будет лучше, чем по скринам. Так будет легче отыскать, где именно вы надублировали.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: <avr/eeprom.h>
СообщениеДобавлено: 04 мар 2018, 11:39 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 17 сен 2011, 11:02
Сообщения: 30
Откуда: Бурятия
РЕШЕНО.
Методом околонаучного тыка (другого, похоже нет :) ) пришёл к такому -

В начале main.c объявляем freq1e, p_lene и freq2e в EEPROM:
Код:
//--------------------------------------------------------------
#include "main.h"
//—————————————-
uint16_t freq1e EEMEM = 500;
uint16_t p_lene EEMEM = 1000;
uint16_t freq2e EEMEM = 5000;
//----------------------------------------------------------------------
//—————————————-
void port_ini(void)
{
   PORTD=0b00000011;
    DDRD=0b11111100;
   PORTC=0b00111100;
    DDRC=0b00000000;
}
//—————————————-
//=============================================================
int main(void)
{
   //=============================================================
   port_ini(); //Инициализируем порты
   LCD_ini(); //Инициализируем дисплей
   clearlcd();//очистим дисплей
   


В начале main.h объявляем их же в RAM:
Код:
//-------------------------------------------
#ifndef MAIN_H_
#define MAIN_H_
//=============================================================
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/eeprom.h>
//--------------------------------------
#include "lcd.h"
#include "timers.h"
#include "adc.h"
#include "encoders.h"
//#include "eeprom.h"
//-------------------------------------------------------------
#define e1 PORTD|=0b00001000 // установка линии E в 1
#define e0 PORTD&=0b11110111 // установка линии E в 0
#define rs1 PORTD|=0b00000100 // установка линии RS в 1 (данные)
#define rs0 PORTD&=0b11111011 // установка линии RS в 0 (команда)
//-------------------------------------------------------------------
int EncValue11; int EncValue2; int EncValue3;
uint16_t freq1;
uint16_t p_len;
uint16_t freq2;
uint16_t freq1e;
uint16_t p_lene;
uint16_t freq2e;
int adc1; int adc2; int adc3;


Работает.

Ещё раз уточню: никакого множественного объявления нет и НЕ БЫЛО. Я, конечно начинающий, но... :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: <avr/eeprom.h>
СообщениеДобавлено: 04 мар 2018, 12:04 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2585
Мдя.... Судя по всему, программирование - не ваш конек, раз даже с -дцатого раза ничего не поняли.
Вы закомментили #include "eeprom.h", вот и заработало. Чеж тут непонятного то. Сравните со своим первым вариантом, где #include "eeprom.h" есть


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: <avr/eeprom.h>
СообщениеДобавлено: 04 мар 2018, 13:08 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2536
Откуда: Санкт-Петербург
Это, простите, хуета.
Как только вы описали переменную в h-файле и включили его в несколько c-файлов - вы имеете две разные переменные с одним именем в разных файлах. Поэтому привыкните сразу: в h-файлах переменные описываются _только_ со словом extern, а потом описание переменной дублируется в c-файле.

А что на PROGMEM линкер ругнулся, в то время как на обычные переменные нет - это вам повезло. Судя по всему, PROGMEM-переменные по умолчанию являются глобальными (как функции; к слову, для функций это можно отключить ключом компилятора).

В общем, не выпендривайтесь, пишите, как положено: extern в h-файле плюс просто запись в c.
Если переменной задаётся значение - это делать только в c-файле.
extern uint16_t freq2e EEMEM; //h
uint16_t freq2e EEMEM= 5000; //c
Нужны _обе_ строчки. Первая говорит просто, что переменная существует - эту строчку можно повторять сколько угодно раз (что и происходит при подключении h-файла).
Вторая должна существовать ровно один раз - она реально создаёт переменную.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: <avr/eeprom.h>
СообщениеДобавлено: 04 мар 2018, 13:15 
Старожил
Аватара пользователя

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 577
Код:
#ifndef MAIN_H
#define MAIN_H

#include <stdint.h>

#ifdef MAIN_CPP
  uint8_t x=1;
#else
  extern uint8_t x;
#endif //MAIN_CPP

#endif //MAIN_H

Дарю :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: <avr/eeprom.h>
СообщениеДобавлено: 04 мар 2018, 13:38 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2536
Откуда: Санкт-Петербург
VladislavS, да ну... Лишний ifdef только ради того, чтобы втащить обе строчки в один файл?
Да и #define MAIN_CPP наверняка забудет (да и нафиг он нужен?)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: <avr/eeprom.h>
СообщениеДобавлено: 04 мар 2018, 13:49 
Старожил
Аватара пользователя

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 577
aamonster писал(а):
VladislavS, да ну... Лишний ifdef только ради того, чтобы втащить обе строчки в один файл?

Зато в хидере полностью описан интерфейс модуля. Переменная может быть далеко не одна, лишний ifdef тут погоду не делает. И это же не только main может быть, это общий подход к модулям. Если нужно использовать модуль, то достаточно подключить его хидер и всё. Так ошибок будет сильно меньше.

aamonster писал(а):
Да и #define MAIN_CPP наверняка забудет (да и нафиг он нужен?)

Ну если ССЗБ, то компилятор напомнит.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB