Урок 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 с адаптером можно здесь USBASP USBISP 3.3 с адаптером
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Добрый день!
А как сделать чтобы мы получали данные при считывании в том виде в котором мы их записали?
Точнее как быть если я хочу int сохранять а не char
Извиняюсь вопрос сформулирован по идиотски.
Я хочу вывести в терминал в протеусе число например «120»
При этом выводится «x» который соответствует числу 120
Как мне вывести числа а не символы которые им соответствуют?
Заранее спасибо
Здравствуйте!
А вот эта статья, мне помогла реализовать мой проект. За что Вам огромное СПАСИБО!!!