Урок 15
Часть 4
Внутренняя энергонезависимая память EEPROM
Продолжаем работать с внутренней памятью микроконтроллера Atmega8a — EEPROM.
В части 1, части 2 и части 3 урока мы познакомились с организацией данной энергонезависимой памяти, а также записали туда данные в различных видах, а также считали однобайтную величину.
Теперь нам предстоит ещё и считать программно с помощью средств МК все эти типы данных.
Но, так как мы договорились разделить проекты для чтения и записи памяти EEPROM, то, соответственно, мы перенесём полностью весь код из файлов eeprom.c и eeprom.h проекта Test13 в одноимённые файлы проекта Test14.
Теперь можно продолжать писать код в функции main().
Но прежде чем писать его, мы создадим ещё ряд глобальных переменных, хотя и не обязательно их делать глобальными, но нам сейчас разницы нет. Переменные эти будут для хранения величин разной разрядности и указатель на адрес строки в оперативной памяти. Но указатель строки мы не будем делать глобальным, а попробуем его сделать локальным в функции main, но с атрибутом const, что позволит ему «жить» даже тогда, когда мы уйдём куда-то из функции main(), хотя куда мы из неё денемся. По большому счёту, мы всю «жизнь» нашей программы в ней и находимся. Вот наши глобальные переменные (переменную dtt переименуем просто в dt)
unsigned char dt;
uint16_t dt16;
uint32_t dt32;
Также исправим dtt в dt и в main()
dt = EEPROM_read_word(1);
USART_Transmit(dt);
Дальше считаем переменную 16-разряюную из EEPROM с адреса 3. Затем, прежде чем передать данную переменную через интерфейс USART, мы применим битовые сдвиги, так как данный интерфейс в нашем МК умеет передавать только 1-байтные данные
USART_Transmit(dt);
dt16 = EEPROM_read_word(3);
USART_Transmit((unsigned char) (dt16>>8)); //старшая часть
USART_Transmit((unsigned char) dt16); //младшая часть
Аналогичным образом мы поступим и с 32-битным значением
USART_Transmit((unsigned char) dt16); //младшая часть
dt32 = EEPROM_read_dword(7);
USART_Transmit((unsigned char) (dt32>>24)); //самая старшая часть
USART_Transmit((unsigned char) (dt32>>16)); //следующий байт (на 1 моложе)
USART_Transmit((unsigned char) (dt32>>8)); //-//-
USART_Transmit((unsigned char) dt32); //самая младшая часть
Как мы видим, мы начинаем со старших частей и движемся к младшей, хотя в памяти EEPROM у нас хранится всё наоборот.
Ну, и теперь пришло время поработать со строкой. Вопреки тому, что это кажется сложнее. чем работать с целыми величинами, на практике. если мы обладаем подобающими знаниями по работе с указателями памяти, то нам это ничего не будет стоить. Напишем вот такой код
USART_Transmit((unsigned char) dt32); //самая младшая часть
const char * buff = EEPROM_read_string(16,12);
Здесь мы считываем 12 байт в оперативную память по определенному адресу. Ровно столько занимает вместе с восклицательным знаком наша строка.
Осталось нам лишь только отправить её в USART. Когда-то в далёком будущем мы напишем функцию передачи цепочки байтов в USART, а сейчас воспользуемся элементарным циклом for
const char * buff = EEPROM_read_string(16,12);
for (int i=0;i<12;i++)
{
USART_Transmit(buff[i]);
}
Соберём код и запустим терминальную программу. Настройки у нас там для отображения различных величин будут вот такие
Нажмём кнопку Connect в терминальной программе и прошьём контроллер. Должна быть вот такая картина
Вроде всё правильно. Все величины у нас именно те, которые мы и заносили. Поэтому считаю, что задание наше выполнено, цели достигнуты. Мы умеем работать с энергонезависимой памятью EEPROM, что в будущем позволит нам хранить в ней даннные различных типов и с успехом ими пользоваться. Когда-то мы дойдём до возможности передавать через USART даже данные плавающего типа, но до этого ещё далеко. А на данном этапе, я считаю, что мы уже достигли очень хороших результатов за такое небольшое количество уроков.
Предыдущая часть Программирование МК AVR Следующий урок
Купить программатор можно здесь (продавец надёжный) USBASP USBISP 2.0
Смотреть ВИДЕОУРОК (нажмите на картинку)
Добрый день!
А как сделать чтобы мы получали данные при считывании в том виде в котором мы их записали?
Точнее как быть если я хочу int сохранять а не char
Извиняюсь вопрос сформулирован по идиотски.
Я хочу вывести в терминал в протеусе число например «120»
При этом выводится «x» который соответствует числу 120
Как мне вывести числа а не символы которые им соответствуют?
Заранее спасибо
Здравствуйте!
А вот эта статья, мне помогла реализовать мой проект. За что Вам огромное СПАСИБО!!!