03.03.2018, 15:12
|
|
Гражданин KAZUS.RU
Регистрация: 02.06.2003
Адрес: Челябинск
Сообщений: 545
Сказал спасибо: 10
Сказали Спасибо 341 раз(а) в 202 сообщении(ях)
|
Re: <avr/eeprom.h>
Сообщение от DPANYTA
|
Вопрос:
Если я переменную делаю не EEMEM ( uint16_t freq1e; ) - всё ОК.
А если ( uint16_t freq1e EEMEM; ), то "multiple".
Всё, разница в пять букв.
|
Для начала маленькая подсказка: какая программа выдает это сообщение - компилятор или линкер?
|
|
|
|
03.03.2018, 15:17
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: <avr/eeprom.h>
ой-ой-оййййй. Топикстартер, не читайте у Bill-а, это, извините, жопа, при всем уважении. Экстернов и дефайнов столько, что хоть жопой ешь. Какая тут к собакам, модульность, какие тут заголовочники? Тут все равно что в одном файле. Это тупиковый путь.
Топикстартер, ну блин, ну нарисована же схема выше на прошлой странице. Создавайте пары файлов .c и .h и подключайте их по стрелочкам.
Последний раз редактировалось NewWriter; 03.03.2018 в 15:23.
|
|
|
Сказали "Спасибо" NewWriter
|
|
|
03.03.2018, 15:26
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,897
Сказал спасибо: 498
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: <avr/eeprom.h>
Сообщение от NewWriter
|
то это будет чисто логически неправильно.
|
А фактически это будет неважно, если вы не делаете этого.
Сообщение от NewWriter
|
Зачем вы сами себя то обманываете? Сами же говорите, что это низкоуровневый язык, и тут многое зависит от программиста. Так сам программист зачем же будет сам себя заставлять делать лажу, если есть возможность ее не делать?
|
Я не вижу тут ничего, заставляющего делать лажу.
Если человек пишет "кашу", при которой вызовы функций из одних модулей хаотично и перекрёстно разбросаны по другим, то ничем ему не поможет более строгий язык, в котором, прежде чем вызвать функцию, надо объявить ее в интерфейсе - все равно он точно так же будет выносить в интерфейсы все подряд и вызывать откуда попало.
Если следует советам (вот вашему в том числе) структурировать программу - не будет такого и при возможности вызвать что угодно откуда угодно без объявления.
Я себя не обманываю. Низкоуровневый язык на то и низкоуровневый, что позволяет делать всё, что хотите. Хотите изолировать функции и переменные - есть способ. Хотите к статичной переменной, изолированной,локальной, внутри функции, получить доступ извне - пожалте, и тут есть способ. Хотите вылезти за пределы массива - вам это позволено (но вы должны понимать, что делаете). Хотите ран-тайм проверку на такой выход за пределы массива - пишете ее сами.
В условиях ограниченных ресурсов ("ресурсы всегда ограничены" (с)) есть возможность нестандартных решений. Нет надобности в них - обходимся стандартными. Как вы думаете, почему не прижились на МК всякие там Паскали?
Вот на то, что в си есть указатели вы не ругаетесь же? А это вообще задница с точки зрения "можно запутаться и совершить неявную ошибку" - компилятору фиолетово, куда он указывает, и с чем вы совершили операцию - с указателем или с тем, на что он указывает. Но удобно ведь!)))
Статичные библиотеки, кстати, это не обходной путь. Это самый, что ни на есть, прямой путь, задуманный изначально.
Сообщение от NewWriter
|
Для примера - посмотрите в даташитах flowchart-ы и схемы состояний. Там нет конкретного кода на конкретном языке. Там - очень абстрактрые кружочки, ромбики и стрелочки.
|
В атмеловских даташитах (и не только), например, не стесняясь, писали примеры кода на си и асме. Да и православный СТМ32... вон в приложенном файлике как бы тоже пример из рефмануала.
Флоучарты и схемы состояний тоже суть псевдокод. Графический. Для кого-то наглядней, для кого-то нет. Тут дело личных предпочтений и этак безапелляционно обобщать я бы не стал. Лично я никогда не рисую ромбики-квадратики. Я списки иногда пишу. Почему-то мне так удобнее. А еще чаще ничего не пишу, "в голове" абстракция таки работает, и в проекте при написании "сверху вниз" структура сразу и создается. А возможность вызвать что угодно откуда угодно прекрасно помогает проверять и отлаживать "низкоуровневые" модули.
А кому-то и в Algoritnm builder-е было удобно писать)))
Последний раз редактировалось AR_Favorit; 03.03.2018 в 15:45.
|
|
|
|
03.03.2018, 17:21
|
|
Прописка
Регистрация: 25.11.2008
Сообщений: 114
Сказал спасибо: 3
Сказали Спасибо 9 раз(а) в 9 сообщении(ях)
|
Re: <avr/eeprom.h>
Сообщение от Bill
|
компилятор или линкер?
|
Вы щас с кем разговаривали?
Вот:
и вот:
не то?
|
|
|
|
03.03.2018, 17:30
|
|
Прописка
Регистрация: 25.11.2008
Сообщений: 114
Сказал спасибо: 3
Сказали Спасибо 9 раз(а) в 9 сообщении(ях)
|
Re: <avr/eeprom.h>
Сообщение от AR_Favorit
|
А кому-то и в Algoritnm builder-е было
|
Ха.
Почему было?
Мне! Есть, а не было!
Я - заклятый Билдерщик. "Засидевшийся ассемблерщик."
Вот прям щас, прям здесь (с Вашей помощью) пытаюсь убедить себя, что С лучше.
|
|
|
Сказали "Спасибо" DPANYTA
|
|
|
03.03.2018, 18:17
|
|
Гражданин KAZUS.RU
Регистрация: 02.06.2003
Адрес: Челябинск
Сообщений: 545
Сказал спасибо: 10
Сказали Спасибо 341 раз(а) в 202 сообщении(ях)
|
Re: <avr/eeprom.h>
Сообщение от DPANYTA
|
не то?
|
Значит так. Пусть имеется некоторая переменная var. Любая переменная должна быть определена до обращения к ней. Стало быть, ее сначала нужно определить. Обычно (хотя и необязательно) это делается в начале программного модуля (файла): При объявлении переменной компилятор выделяет (резервирует) место в памяти для этой переменной:
Код:
|
public var
var: ds 2 |
Ключевое слово public говорит о том, что данная переменная является глобальной, т.е. доступна всем остальным модулям проекта. Пусть эта переменная определена в модуле 1.с.
Допустим далее, что обращение к этой переменной происходит в другом модуле, например 2.c Но и в этом модуле компилятору также требуется "знать" как обращаться с этой переменной. Ее можно попробовать определить так же как и в модуле 1.c, т.е. Компилятор скомпилирует все без ошибок. Кажется все ОК. Но проблема возникнет на этапе сборки программы, когда линкер обнаружит две глобальных метки с одинаковым именем. Поэтому он выдаст сообщение об ошибке, что-вроде multiple definition of lable "var".
Чтобы этого не произошло, переменную нужно определить только один раз, в нашем случае - в модуле 1.c А как определить эту же переменную в модуле 2.c. Здесь нужно иметь в виду, что по отношению к данному модулю переменная var является внешней ( external). Стало быть, ее нужно так и описать: Для внешних переменных память не выделяется, поэтому сборка программы будет сделана без ошибок.
А как быть если к переменной обращаются из 2-х, 3-х, и т.д. модулей? Можно, конечно, описать переменную n-раз во всех модулях. Но это очень неудобно. Поэтому чаще всего для этой цели как раз и используются заголовочные файлы.
Последний раз редактировалось Bill; 03.03.2018 в 19:46.
|
|
|
|
03.03.2018, 20:47
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.05.2008
Адрес: Мурманск
Сообщений: 1,300
Сказал спасибо: 461
Сказали Спасибо 526 раз(а) в 273 сообщении(ях)
|
Re: <avr/eeprom.h>
Сообщение от DPANYTA
|
не то?
|
Вообще-то русские буквы в названиях папок компиляторы не любят, да и очень длинные пути (path) и пробелы тоже. У вас там c:\Дима\Серега\С генератор\... Разве нельзя назвать по человечески? Или C:\Dima\Serega\C_generator\
|
|
|
|
04.03.2018, 10:36
|
|
Прописка
Регистрация: 25.11.2008
Сообщений: 114
Сказал спасибо: 3
Сказали Спасибо 9 раз(а) в 9 сообщении(ях)
|
Re: <avr/eeprom.h>
РЕШЕНО.
Методом околонаучного тыка (другого, похоже нет ) пришёл к такому -
В начале 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; |
Работает.
Ещё раз уточню: никакого множественного объявления нет и НЕ БЫЛО. Я, конечно начинающий, но...
|
|
|
|
24.01.2020, 15:04
|
|
Частый гость
Регистрация: 01.09.2005
Адрес: Саратов
Сообщений: 10
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: <avr/eeprom.h>
Подниму тему как на изиэлектрониксе.
Юзаю ATtiny24A. Инициализирую переменную в EEPROM. При запуске МК должен считать её значение... Не считывает. Проверяю условием с подсвечиванием св.диода.
Код:
|
#include ‹avr/io.h›
#include ‹avr/eeprom.h›
#include "main.h"
#include "mcu_init.h"
/************************************************** *****/
/* Defines and Declarations */
/************************************************** *****/
uint8_t LightLevel = 0;
uint8_t EEMEM LightLevelMem = 5;
/************************************************** *****/
int main(void)
{
MCU_initialization();
/// Чтение данных о яркости подсветки
LightLevel = eeprom_read_byte( &LightLevelMem );
if( LightLevel == 5 ) {
LED3_ON;
}
/* Replace with your application code */
while (1)
{
}
} |
Среда AtmelStudio7. Заношу сначала во Flash, потом в EEPROM. Фьюзы:
p/s/ Разве правильно писать uint8_t Var EEMEM = 5; , а не uint8_t EEMEM Var = 5;? В первом случае Студия Var никак синтаксически не выделяет цветом, а во втором выделяет как переменную. При компиляции первого варианта не отругивается, как и для второго.
|
|
|
|
24.01.2020, 15:19
|
|
Гуру портала
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 19,121
Сказал спасибо: 2,569
Сказали Спасибо 11,944 раз(а) в 5,991 сообщении(ях)
|
Re: <avr/eeprom.h>
Хотя бы тут
https://chipenable.ru/index.php/prog...ponent&print=1
А вообще - есть мануалы, хелпы... Даже примеры.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 22:06.
|
|