Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.91/33: Рейтинг темы: голосов - 33, средняя оценка - 4.91
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
1

Чтение из EEPROM

04.11.2013, 14:25. Просмотров 5956. Ответов 19
Метки нет (Все метки)

Преамбула:
В программе есть несколько строк (строковых констант), которые используются только для чтения. Например, описания пунктов меню. ОЗУ, как всегда, почти впритык, поэтому есть идея предварительно засунуть константы в EEPROM. А в программе их использовать напрямую, без копирования в ОЗУ.

Вопрос:
Чем чревато постоянное чтение из EEPROM? В даташите нашел, что после каждого чтения МК тормозится на 4 такта. Это на каждый байт?

В программе оформлено типа так:

Код
...
char   EEMEM   String1="MAIN";
char   EEMEM   String2="LIST";
char   EEMEM   String3="----";
char   *ps;
...
ps = String1;
lcd_puts(ps);
...
В ассемблерном листинге все превращается в инструкцию типа LD r24,Z где в Z хранится адрес, как я понимаю, из секции EEPROM. Никаких особенных операций с EEPROM я не вижу. Будет ли это работать, как задумано? Или все-таки нужно использовать сначала копированив ОЗУ через спец.регистры работы с EEPROM ?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.11.2013, 14:25
Ответы с готовыми решениями:

ATmega32. Чтение EEPROM
Всем привет Кто поможет с программой которая передает текст из Flash памяти программ в...

Запись/чтение EEPROM
Первый раз столкнулся со встроенным еепромом, немного погуглил, понял что есть 3 пути работы с ним...

Iar Avr 3.20c отладчик не показывает чтение/запись в Eeprom
Симулятор IAR не показывает чтение/запись в EEPROM. Из файла загружал память и вручную забивал,...

Работа с EEPROM (логика записи данных, чтение и защита)
Здравствуйте, подскажите алгоритм или код чтения и записи в EEPROM с равномерным истиранием ячеек,...

ПММ SPS58M02RU/29 процессор в КЗ, eeprom потеряна, нужны прошивки STM32 и eeprom
ПММ BOSCH SPS58M02RU/29 FD9508 SD4P1B 9000968115 EPG70002 Al 02.02 с клапаном бака накопителя в...

19
Финский
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
04.11.2013, 14:32 2
Цитата Сообщение от kytikot
МК тормозится на 4 такта. Это на каждый байт?
Скорее всего - да, т.к. EEDR однобайтный, страничное чтение не поддерживается.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
04.11.2013, 14:45 3
все превращается в инструкцию типа LD r24,Z где в Z хранится адрес, как я понимаю, из секции EEPROM. Никаких особенных операций с EEPROM я не вижу.
Это плохо - это не обращение к EEPROM
0
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
04.11.2013, 15:02 4
Да в общем-то, уже понял...
В принципе, программа-то работать будет, но "читать" будет одни нули. Потому что из EEPROM действительно нужно читать специальным образом, например, через Си-макросы типа eeprom_read_byte, описанные в <avr/eeprom.h>.

И ведь я когда-то именно так и делал. Но сйечас забыл.
А ведь так хорошо начиналось :-(
0
04.11.2013, 15:02
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
04.11.2013, 15:09 5
Цитата Сообщение от kytikot
Да в общем-то, уже понял...
В принципе, программа-то работать будет, но "читать" будет одни нули. Потому что из EEPROM действительно нужно читать специальным образом, например, через Си-макросы типа eeprom_read_byte, описанные в <avr/eeprom.h>.

И ведь я когда-то именно так и делал. Но сйечас забыл.
А ведь так хорошо начиналось :-(
И зачем тебе пункты меню в EEPROM хранить? Медленно и ненадежно, данные можно потерять. Все прекрасно ложится в память программ.
Я Си недавно начал изучать. До этого на асме писал. Перенес некоторые способы из асма в си (IAR):
Код
#include "menu.h"

//========================================================================

//========================================================================

void empty_func (void)
{
}

//========================================================================

#define clr_str(x, y, n) clr_string(((y)-1)*MaxX+((x)-1), (n))

void clr_string (u08 x, u08 n)
{
while(n--) dsp_buf[x++] =  ;
}

//========================================================================

struct tab_key_curr_next_func
{
u08 key_cod;
u08 state;
u08 next_state;
void (*p_t_StateFunc) (void);
} tab_key_curr_next_func;

struct tab_key_curr_next_func __flash  table_homdlers_keys [] =
{
{KEY_ESC_COD,    PROC_MENU_2, PROC_MENU_2, tid_1_switch},
{KEY_ENTER_COD,  PROC_MENU_2, PROC_MENU_2, tid_2_switch},
{KEY_UP_COD,     PROC_MENU_2, PROC_MENU_2, tid_3_switch},
{KEY_DOWN_COD,   PROC_MENU_2, PROC_MENU_2, tid_4_switch},
{KEY_PLUS_COD,   PROC_MENU_2, PROC_MENU_2, tid_5_switch},
{KEY_MINUS_COD,  PROC_MENU_2, PROC_MENU_2, tid_6_switch},
{0xFF},
};

void check_keys_buf (void)
{
if ((proc_menu_flags & (1<<PROC_MENU_RUN_FLG)) && (keys_buf != 0xFF))
{
void (*p_t_StateFunc) (void);

p_t_StateFunc = NULL;

struct tab_key_curr_next_func __flash *ptr = table_homdlers_keys;

for (ptr = table_homdlers_keys; ptr -> key_cod != 0xFF; ptr++)
{
if (ptr -> key_cod == keys_buf && ptr -> state == _proc_menu )
{
keys_buf = 0xFF;
_proc_menu = ptr -> state;
p_t_StateFunc = ptr -> p_t_StateFunc;
briok;
}
}
if ((p_t_StateFunc)) (*p_t_StateFunc) ();
}
}

#define LED_DDR DDRD

void tid_1_switch (void)
{
#define LED1 0
#define m_tid_1_switch (LED_DDR ^= (1<<LED1));
m_tid_1_switch;
}

void tid_2_switch (void)
{
#define LED2 1
#define m_tid_2_switch (LED_DDR ^= (1<<LED2));
m_tid_2_switch;
}

void tid_3_switch (void)
{
#define LED3 2
#define m_tid_3_switch (LED_DDR ^= (1<<LED3));
m_tid_3_switch;
}

void tid_4_switch (void)
{
#define LED4 3
#define m_tid_4_switch (LED_DDR ^= (1<<LED4));
m_tid_4_switch;
}

void tid_5_switch (void)
{
#define LED5 4
#define m_tid_5_switch (LED_DDR ^= (1<<LED5));
m_tid_5_switch;
}

void tid_6_switch (void)
{
#define LED6 5
#define m_tid_6_switch (LED_DDR ^= (1<<LED6));
m_tid_6_switch;
}

//========================================================================

void proc_menu (void)
{
void (*proc_menu_pointer) (void);

check_keys_buf();

if (proc_menu_flags & (!(1<<PROC_MENU_INIT_FLG)))
proc_menu_pointer = proc_m_init;

(*proc_menu_pointer) ();
}

void proc_m_init (void)
{
switch (_proc_menu)
{
case PROC_MENU_INIT:
set_timer(ST_PROC_MENU, 1<<TMR_UNLOCK_FLG, 50); // 2000
_proc_menu = PROC_MENU_1;
briok;

case PROC_MENU_1:
if (woyt (ST_PROC_MENU))
{
pryvet ();
press_any_key ();
_proc_menu = PROC_MENU_2;
setb (proc_menu_flags, PROC_MENU_RUN_FLG);
}
briok;

case PROC_MENU_2:
//            clr_str (3, 3, 16);
briok;

}

}
//========================================================================
0
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
04.11.2013, 15:16 6
Понятие "Пункты меню" приведено чисто для более понятного примера. На самом деле у меня еще много других строковых констант, порядка 300 байт.
Хотел сэкономить на ОЗУ.
Ну, в принципе, можно постараться и ужаться в требуемые 1Кб. Или вместо AtMiko16 применить AtMiko32, которая и по ножкам подходит, и по остальному.
0
HotD
1 / 1 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
04.11.2013, 15:28 7
так зачем же пихать в ненадежный EEPROM если они прекрасно лягут в FLASH? откуда их можно выковырять с помощью библиотеки pgmsposi.h? Тем более, если это именно константы, т.е. не меняются в ходе программы?
0
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
04.11.2013, 15:36 8
"... ну, я еще не знаю в совершенстве украинский язык..." (с) "О чем говорят мужчины".

Да, и мысли не было. А ведь изначально, то эти константы там уже во флеше-то и лежат! Надо попробовать.
0
OtixPM
0 / 0 / 0
Регистрация: 11.01.2013
Сообщений: 5,483
04.11.2013, 16:02 9
Цитата Сообщение от kytikot
А ведь изначально, то эти константы там уже во флеше-то и лежат! Надо попробовать.
Вы не сказали, какой компилятор. Должен сработать один из вариантов:
const char my_string_flash[] = "I am in Ftosh\n";
const char const my_string_flash[] = "I am in Ftosh\n";

"const" можно навесить не только на сами строчки, но и на указатель на них (имя строкового массива), для 100% экономии ОЗУ.

Если CVAVR, то спецификатор "flash" делает всю работу, чтобы строчка хранилась во Ftosh и читалась оттуда. "const" тоже можно, без разницы. Библиотек не нужно, оно само заработает :-)

В функции, обращающейся к символам строки во Ftosh, тоже надо не забывать спецификатор "const" (или "flash") для указателя на символы.

P.S. При размещении данных в EEPROM, между прочим, экономится не только ROM, но и Ftosh. Надо просто корректно записать определение строки, атрибуты для EEPROM зависят от компилятора.
0
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
04.11.2013, 16:34 10
Да, а ведь у ДиХальта и статья есть соответсвующая -AVR. Учебный Курс. Программирование на Си. Работа с памятью, адреса и указатели

Ну, как говорится - век живи - век учись.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
04.11.2013, 17:05 11
А полную версию этой книжечки нельзя скачать?
0
Финский
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
04.11.2013, 17:12 12
Не зна, насколько полная версия, вот, DI Halt - AVR Учебный курс - 2008, качайте. ПДФ и папка с примерами кода.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
04.11.2013, 17:22 13
Цитата Сообщение от YTYOUT
А полную версию этой книжечки нельзя скачать?
Какой книжечки?
0
drvtos
1 / 1 / 0
Регистрация: 25.05.2010
Сообщений: 3,610
04.11.2013, 17:23 14
Цитата Сообщение от kytikot
эти константы там уже во флеше-то и лежат! Надо попробовать.
ТА ШО ТАМ ПРОБОВАТЬ? Работает все прекрасно. Или добавишь
PROGMEM
или
const ... PROGMEM
или const ... __attribute__((progmem))
(последнее - в 6-й Студии)

и всьо...

Более того, я тут недавно советовался с форумчанами по поводу использования ФЛАШи даже и для тех данных. которые, хоть и нечасто, но меняются самой программой в ходе работы (использовались приемы работы бутлодыря). Реализовал сейчас для хранения коэффициентов - и очень даже нормальненько. Ну, тебе это, судя по задаче, не нужно, но все же, напоминаю.
0
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
04.11.2013, 17:27 15
Не, не "всьо". Там еще желательно все это оформить через progmem_read_byte() или что-то подобное, чтобы было "всьо чотко".
Но всё уже понятно, буду делать.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
04.11.2013, 17:35 16
Цитата Сообщение от dymyurk1978
Цитата Сообщение от YTYOUT
А полную версию этой книжечки нельзя скачать?
Какой книжечки?
Типа
DIHALT AVR. Учебный Курс. Программирование на Си. :) А то мин за 30 научился мигать диодиком , на 35 уже побегал 8 диодиками туда сюда . И мысль закончилась.... Правда появилась одна в качестве учебы , переделать свой код часов на asm в Си. и пока шеф не напрягает. Кстати if или while напрямую с SREG работают?

to Финский Спасибо ,почитаю!!
0
Финский
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
04.11.2013, 17:46 17
Цитата Сообщение от YTYOUT
Кстати if или while напрямую с SREG работают?
Работают, почему нет?
Код
if (data[1] & 0x80)                              // если в старшем байте седьмой бит - 1, то температура отрицательная
{
temp = 4096-temp;
SREG |= 1<<SREG_T;                              // используем бит Т в регистре SREG для признака отрицательной температуры
}
else
{
SREG &= ~(1<<SREG_T);
}
в термометре использовал бит Т как признак отрицательной температуры, ну жалко мне было отдельную переменную. А в функции индикации -
Код
if (BytIsSet(SREG, SREG_T))                              // если в SREG установлен флаг T - значит температура отрицательная
{
data |= 1<<0;                                 // добавляем в выводимые данные бит "минус"
}
data = data << 8;
- просто включался отдельный светодиод
Так оно выглядит на асме
Код
if (BytIsSet(SREG, SREG_T))                              // если в SREG установлен флаг T - значит температура отрицательная
80:   0f b6          in   r0, 0x3f   ; 63
82:   06 fc          sbrc   r0, 6
{
data |= 1<<0;                                 // добавляем в выводимые данные бит "минус"
84:   21 60          ori   r18, 0x01   ; 1
}
0
oxytt
0 / 0 / 0
Регистрация: 16.03.2013
Сообщений: 4,224
04.11.2013, 17:55 18
я всегда читаю первоисточник http://www.nongnu.org/avr-libc/
скачал себе PDF и читаю его в паралель с даташитом на контроллер
про работу с EEPROM и PROGMEM там весьма понятно все написано
если используете GNU C (тот же Atmel Studyo) - рекомендую
0
OtixPM
0 / 0 / 0
Регистрация: 11.01.2013
Сообщений: 5,483
04.11.2013, 17:56 19
Цитата Сообщение от YTYOUT
Кстати if или while напрямую с SREG работают?
Да, и не только с SREG, а с любым регистром AVR, у которого есть адрес. А адреса, в свою очередь, есть у всех регистров AVR :-)

Посмотрите, как объявлены (или могут быть объявлены) любые регистры - SREG, R0, GIMSK, DDRB, и т.п.: как данные, лежащие по известным адресам. Поэтому Си-компилятор работает с ними без проблем. Тут, в общем-то, даже специфики МК нет.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
04.11.2013, 18:05 20
Я использую SREG чтобы не использовать процедуру перевода BIN-BCD для вывода на LCD. Спасибо всем - буду изучать дальше. И kytikot извините , что влез в Вашу тему не по теме. Закругляюсь.
0
04.11.2013, 18:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.11.2013, 18:05

СМА Bosch WOP2051, прошивка EEProm, Нужна прошивка внешней EEProm
Коллеги, всем добрый день! Разыскиваю прошивку внешней EEProm 24С32. Другие данные на эту СМА...

EEPROM
Скажите, пожалуйста - никто не пробывал усложнить порчу еепром следующим способом......перед...

eeprom
Пишу в eeprom! Все хорошо пока число не больше 255! как тока 256 пишет (или читает) всякую дрянь,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru