Память ЕЕРRОМ микроконтроллеров АVR
Многие микроконтроллеры АVR оборудованы встроенной памятью ЕЕРRОМ — электрически перезаписываемой энергонезависимой памятью. Хотя эта память и допускает запись, она редко используется для хранения программных переменных, поскольку, во-первых, медленнодействующая, и, во-вторых, имеет ограниченный (хотя и довольно большой) цикл перезаписи.
Учитывая вышесказанное, память ЕЕРRОМ используют, преимущественно, для хранения данных, которые не должны быть потеряны даже при потере питания. Это очень удобно, к примеру, при калибровке измерительных приборов, работающих под управлением микроконтроллеров, у которых в памяти ЕЕРRОМ в процессе настройки сохраняются параметры корректировки. Благодаря этому, в большинстве случаев полностью отпадает необходимость в настроечных потенциометрах и триммерах.
В отличие от флэш-памяти, для записи/чтения памяти ЕЕРRОМ нет необходимости в специальном программаторе — эти операции доступны программно и допускают побайтную передачу данных с помощью регистра управления ЕЕСR, регистра данных ЕЕDR. и регистровой пары ЕЕАRL, ЕЕАRН, определяющей адрес ячейки памяти (см. табл. 1.1).
В Code Vision AVR чтобы определить константы, хранящиеся во FLASH-памяти, следует использовать ключевые слова flash или const.
Чтобы определить константы, хранящиеся в EEPROM, следует использовать ключевое слово eeprom.
Чтобы определить константы, находящиеся в регистрах, следует использовать ключевое слово register.
Константные выражения автоматически определяются в течение компиляции.
Пример:
/* эти константы будут расположены в EEPROM */
eeprom int int_const1=12-7;//Целая константа int_const1будет равна 5
eeprom char char_const=’b’;//Символьная константа char_const будет равна числовому
//ASCII символа ‘b’, т. е. 0x62
/* Эти константы будут расположены во FLASH-памяти */
flash long long_int_const=136L;//целая длинная константа
//long_int_const будет равна 136
flash int int_array[10]={9,16};// этот целочисленный массив имеет 10 членов,
//причем первые два это 9 и 16, а остальные нули
const int int_const2=0123;//Целая константа int_const2 будет равна 123
/* Эта константа будет расположена в регистре */
register int int_const3=0x10;
/* эти константы будут расположены в SRAM */
int int_const4=0b10;
char string_const[]=”HELLO”;// это строковая константа
Константы НЕ МОГУТ быть объявлены в функциях.
Рисунок 3 – Модель схемы в Proteus
Рекомендации
Для настройки UART рекомендуется использовать встроенный в CodeVision генератор кода CodeWizard. Для этого необходимо запустить генератор кода (рис.3), выбрать закладку управления USART (рис.4), выполнить настройку UART на требуемую скорость и режим, а затем запустить предварительный просмотр кода (рис.5). В открывшемся окне отыскать и скопировать фрагмент программы инициализации UART.
Рисунок 4 – Значок генератора кода
Для корректного вывода по UART переменных типа float необходимо выбрать соответствующую опцию компилятора (рис.6). В случае недостатка памяти увеличить размер стека.
Рисунок 5 – Вид закладки USART
Рисунок 6 – Выбор предварительного просмотра кода
Рисунок 7 – Выбор типов выдаваемых по UART данных
Таблица 2 – Поддерживаемые символы типа преобразования для функций вывода. (Лебедев М.Б. CV пособие для начинающих. С. 256-260)
ВАЖНО! Для правильной работы необходимо изменить скорость обмена данными компонента «Виртуальный терминал» в соответствии с заданием.
Задание
1. Вывести Ф.И.О.
2. Вывести построчно:
X1=100; (Х1 переменная типа unsigned char)
Y1=1000; (Y1 переменная типа unsigned short)
Z1=100000; (Z1 переменная типа unsigned long)
F1=3,1416. (F1 переменная типа float)
X2= –100; (Х2 переменная типа signed char)
Y2= –1000; (Y2 переменная типа signed short)
Z2= –100000; (Z2 переменная типа signed long)
F2= –40,23 0С.
3. Задать массив целых байтовых чисел из пяти элементов MAS[5] и байтовую переменную Х. Массив разместить в памяти программ. Обработать массив MAS, результат обработки поместить в переменную Y. Выполнить заданную операцию между переменными X и Y, результат поместить в переменную Z. Выдать результаты по UART. Формат выдачи: X=__; Y=__; Z=__. Варианты заданий приведены в таблице 3.
4. Переслать текст Ф. И. О. студента выполняющего лабораторную работу из Flash-памяти (фамилия) из EEPROM (имя отчество) в оперативную память SRAM. Текст из SRAM выдать на UART оператором printf. В первой программе не должно быть указателей, во второй нужно использовать указатели.
Таблица 3 – Варианты заданий
Вариант | Обработка MAS | Операция X?Y | Скорость UART, Бод |
Min Max Sum Min Max Sum Min Max Sum Min Max Sum Min Max Sum Min Max Sum Min Max | X + Y X & Y X | Y X ^ Y X – Y X + Y X & Y X | Y X ^ Y X – Y X + Y X & Y X | Y X ^ Y X – Y X + Y X & Y X | Y X ^ Y X – Y |
Пример 1.Форматированный вывод по UART переменных различных типов.
#include <mega8515.h>
#include <stdio.h>
//Функция начальной инициализации ********************************************************
Void setup()
{
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x2F;
}
//***************************************************************************************
Void main(void)
{
char *W="Primer";
unsigned char ux=100;
signed char sx=-100;
unsigned short uy=1000;
signed short sy=-1000;
unsigned long uz=100000;
signed long sz=-100000;
float pi=3.1416;
setup();
printf("Start\r");
printf("%s\r",W);
printf("ux=%u\r",ux);
printf("sx=%d\r",sx);
printf("uy=%u\r",uy);
printf("sy=%d\r",sy);
printf("uz=%lu\r",uz);
printf("sz=%ld\r",sz);
printf("pi=%f\r",pi);
while (1);
}
Рисунок 8 – Результат работы программы
Пример 2.Работа с памятью различных типов
/* В программе нет указателей*/
#include<90s8515.h>
#include <stdio.h>
flash char char_const[] = "bcdef";//Массив "bcdef" расп. программ. пам. FLASH
unsigned char memr[5];
char k;
void main (void)
{
/* Включение передатчика UART*/
UCR=0x08;
/* скорость передачи 9600 бод */
UBRR=0x19;
for(k=0;k<=4;k++)//Цикл вывода массива MEMR на UART
{memr[k]=char_const[k];
printf(" %c",memr[k]);
}
printf("\r");//перевод строки
while(1);
}
/* Пример программы, выполняющей теже функции с использованием указателей*/
#include<90s8515.h>
#include <stdio.h>
flash unsigned char char_const[] = {'b','c','d','e','f','\0'};//Массив "bcdn
//flash char char_const[] ="bcdef";
unsigned char memr[6];
char k;
unsigned char z;
unsigned char *pam;// Указатель на переменную типа unsigned char, находящуюся
// в SRAM
flash unsigned char *pam1;//Указатель на переменную типа unsigned char,
находящуюся // во Flash-памяти
void main (void)
{
unsigned char *pam;// Указатель на переменную типа unsigned char, находящуюся
// в SRAM
flash unsigned char *pam1;//Указатель на переменную типа unsigned char,
находящуюся // во Flash-памяти
/* Включение передатчика UART*/
UCR=0x08;
/* скорость передачи 9600 бод */
UBRR=0x19;
for(k=0;k<=5;k++)//Цикл вывода массива MEMR на UART
{
z=*pam1++;
*pam=z;
printf("%c ",*pam++);//вывод содержимого memr по указателю на UART
}
printf("\r");//перевод строки
while(1);
}