AVR Урок 15. Внутренняя энергонезависимая память EEPROM. Часть 3

 

 

 

 

Урок 15

Часть 3

 

Внутренняя энергонезависимая память EEPROM

 

 

Продолжаем работать с внутренней памятью микроконтроллера Atmega8a — EEPROM.

В части 1 и части 2 урока мы познакомились с организацией данной энергонезависимой памяти, а также записали и считали туда данные в виде однобайтной величины, а также записали двухбайтную величину.

Теперь перед нами стоит задача — программно данную 2-х-байтную величину считать, а также записать функции чтения и записи 4-байтных величин, а также ещё написать функцию чтения и записи строк.

Давайте попробуем написать функцию записи 4-х-байтных значений в память EEPROM, или двойных слов. Также в памяти все 4 байта мы обязаны хранить в обратном порядке — от младшего к старшему, так как это принято повсеместно. Также, чтобы не писать функцию полностью, мы будем обращаться к функции записи обычных 2-х байтных слов. Слово — вообще понятие абстрактное. В разных случаях оно разное. Может быть и 2х-байтным, а может и 4х. Тогда в этом случае двухбайтное значение называется полусловом. Но это не суть важно, нам нужно сохранить в энергонезависимую память именно 4х-байтное значение. Пока откроем проект Test13 — это тот проект, где мы договорились в память EEPROM именно писать. Но пока мы сюда напишем все функции, а затем перенесём в проект Test14.

Напишем функцию записи 4х-байтных значений в EEPROM в самый низ файла eeprom.c

 

void EEPROM_write_dword(unsigned int uiAddress, uint32_t ucData)

{

  EEPROM_write_word(uiAddress, (uint16_t) ucData);

  uint16_t dt = ucData>>16;

  EEPROM_write_word(uiAddress+2, dt);

}

 

Здесь у нас происходит всё практически то же самое, что и в функции записи 2х-байтных величин, только величины двойной размерности. Второй входной параметр у нас будет 32-битный, сдвиг на 16 пунктов и и адрес увеличивается на 2, так как используем мы функцию записи 2х-байтных величин и у нас поэтому запись идёт в каждом вызове уже по 2 адресам.

Также напишем ещё функцию чтения 4х-байтной величины. То же самое пишем по аналогии с прошлой функцией чтения, но используем величины двойной размерности и функцию чтения 2х-байтных значений

 

uint32_t EEPROM_read_dword(unsigned int uiAddress)

{

  uint32_t dt = EEPROM_read_word(uiAddress+2)*65536;

  asm("nop");

  dt += EEPROM_read_word(uiAddress);

  return dt;

}

 

Ну и, раз так всё у нас хорошо наладилось с написанием различных функций, давайте также напишем функции и для строк.

Сначала функцию записи. Будет чуть посложнее, потому что мы ещё будем использовать не только значения но и указатели на данные значения. Но мы этого не боимся, с указателями мы уже работали, когда писали код записи строк в память DDRAM символьного дисплея в части 5 урока 12. Напишем сначала каркас функции записи строки в память EEPROM

 

void EEPROM_write_string(unsigned int uiAddress, char str1[])

{

}

 

Данная функция отличается от остальных указателем на строку во втором входном параметре.

Теперь напишем тело функции.

Добавим переменную, а затем в конечном цикле и пробежимся по адресам обычной оперативной памяти до тех пор, пока встретим ноль. Также в этом цикле мы будем встретившиеся значения писать в память EEPROM по адресу, смещённому на число n, которое будет у нас увеличиваться в цикле каждый раз на единицу. Таким образом мы перенесём строку, заканчивающуюся нулём из оперативной памяти в память EEPROM

 

void EEPROM_write_string(unsigned int uiAddress, char str1[])

{

  wchar_t n;

  for(n=0;str1[n]!='\0';n++)

  EEPROM_write(uiAddress+n,str1[n]);

}

 

Ну и давайте также напишем функцию чтения строки из памяти EEPROM в оперативную память по адресу, находящемуся в указателе на строковую переменную (или массив символов). Также мы в этот раз не будем отслеживать окончание строки нулём, а то вдруг его там не будет, а будем в качестве второго входного параметра в функцию передавать количество байтов или символов, которое мы собираемся считать из энергонезависимой памяти. Вот каркас функции

 

const char* EEPROM_read_string(unsigned int uiAddress, unsigned int sz)

{

}

 

Здесь мы возвращаем не сами символы, а указатель на строку символов в оперативной памяти.

 

 

Теперь тело.

Создадим сначала две переменные

 

const char* EEPROM_read_string(unsigned int uiAddress, unsigned int sz)

{

  unsigned int i;

  char* str1;

 

Затем вот такой вот выкрутас

 

char* str1;

str1 = (char *) realloc(NULL,sz);

 

Здесь мы выделим область оперативной памяти для такого количества байтов, сктолько символов мы хотим считать из памяти EEPROM. Для этого и существует функция realloc.

Дальше опять цикл. В нём мы считываем из памяти такое же количество байтов и записываем их уже по адресам оперативной памяти, смещённым на порядковый номер байта от адреса указателя, который мы потом и возвратим

 

  str1 = (char *) realloc(NULL,sz);

  for (i=0;i<sz;i++)

  str1[i] = EEPROM_read(uiAddress+i);

  return str1;

}

 

Создадим прототипы написанных нами новых функций в eeprom.h

 

uint16_t EEPROM_read_word(unsigned int uiAddress); //читаем 2х-байтную величину

void EEPROM_write_dword(unsigned int uiAddress, uint32_t ucData); //пишем 4х-байтную величину

uint32_t EEPROM_read_dword(unsigned int uiAddress);//читаем 4х-байтную величину

void EEPROM_write_string(unsigned int uiAddress, char str1[]); //пишем строку

const char* EEPROM_read_string(unsigned int uiAddress, unsigned int sz); //читаем строку

 

Ну и теперь давайте воспользуемся в функции main() всеми возможными функциями записи в EEPROM и запишем туда различные значения по разным адресам

 

int main(void)

{

  EEPROM_write(1, 120);

  EEPROM_write_word(3, 30000);

  EEPROM_write_dword(7, 0xFEDCBA98);

  EEPROM_write_string(16,"Hello World!");

  while(1)

 

nop попробуем не использовать, должно работать и без него.

Теперь давайте соберём код и прошьём контроллер и затем считаем память EEPROM из контроллера в файл и посмотрим его

 

image11

 

Как мы видим, всё у нас записалось. Мы не будем проверять строку по кодам символов, я думаю, там всё нормально. Мы её потом считаем функцией чтения и увидим воочию нашу строку в следующей части

 

Предыдущая часть Программирование МК AVR Следующая часть

 

Купить программатор можно здесь (продавец надёжный) USBASP USBISP 2.0

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

AVR Внутренняя энергонезависимая память EEPROM

2 комментария на “AVR Урок 15. Внутренняя энергонезависимая память EEPROM. Часть 3
  1. Дмитрий:

    Добрый день! Чё-то студия выдаёт ошибки на типы переменных wchar_t, uint_16_t, uint32_t. Версия студии последняя.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*