danilov_x51_p2
.pdf
1: Стирание Flash-памяти программ разрешено.
Bit0: PSWE: Разрешение записи памяти программ.
Установка этого бита разрешает запись байта данных во Flash-память программ, используя команду MOVX . Адресуемая в команде MOVX ячейка памяти должна быть стертой.
0:Запись во Flash-память программ запрещена.
1:Запись во Flash-память программ разрешена; команда записи MOVX обращается к Flash-памяти.
Таблица 5. Внутреннее устройство регистра FLKEY (регистр блокировки и ключевого кода Flash-памяти)
Доступность |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
Значение |
|
|
|
|
|
|
|
|
|
по сбросу |
Название |
|
|
|
|
|
|
|
|
00000000 |
Номер бита |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
|
|
|
|
|
|
|
|
Адрес SFR: |
0xB7 |
|
Таблица 6. Описание битов регистра FLKEY
Bits 7-0: Регистр блокировки и ключевого кода Flash-памяти.
Запись:
Чтобы можно было записывать или стирать Flash-память, необходимо сначала записать ключевые коды в этот регистр. Flash-память остается заблокированной до тех пор, пока в этот регистр не будет записана следующая последовательность ключевых кодов: 0xA5, 0xF1. Операции записи и стирания Flash-памяти автоматически запрещаются после завершения следующей операции записи или стирания. Flashпамять будет заблокирована до следующего системного сброса в том случае, если запись регистра FLKEY осуществлена некорректно или если попытка выполнить операцию записи или стирания Flash-памяти осуществлена до разрешения этой операции. Если приложение никогда не записывает Flash-память, то ее можно специально заблокировать, записав программным путем в регистр FLKEY значение,
отличающееся от 0xA5.
Чтение:
При чтении биты 1-0 показывают текущее состояние блокировки
Flash-памяти.
00: Flash-память заблокирована для операций записи/стирания. 01: Первый ключевой код записан (0xA5).
10:Flash-память разблокирована (операции записи/стирания разрешены).
11:Операции записи/стирания Flash-памяти запрещены до следующего системного сброса.
11
Таблица 7. Внутреннее устройство регистра FLSCL (регистр управления контроллером Flash-памяти)
Доступнос |
R/W R/W |
R/ |
R/W R/W R/W R/W R/W |
Значение |
ть |
W |
по сбросу |
Название |
Res |
Res |
Res |
FLRT |
Res |
Res |
Res |
Res |
00000011 |
Номер |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
|
бита |
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Адрес SFR: |
0xB6 |
|
Таблица 8. Описание битов регистра FLSCL
Bits 7-5: Зарезервированы. Читаются как 000b. В эти биты следует записать значение 000b.
Bit 4: FLRT: Время чтения Flash-памяти.
Этот бит должен быть запрограммирован минимально возможным значением, соответствующим системной тактовой частоте.
0:SYSCLK ≤ 25 МГц.
1:SYSCLK >25МГц.
Bits 3-0: Зарезервированы. В эти биты следует записать значение 0000b.
Таблица 9. Внутреннее устройство регистра PFE0CN (регистр управления механизмом упреждающей выборки)
Доступность |
R |
R |
R/W |
R |
R |
R |
R |
R/W |
|
Значение |
||
|
по сбросу |
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
Название |
|
|
|
PFEN |
|
|
|
|
FLBWE |
|
00100000 |
|
Номер бита |
|
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
|
|
|
|
|
|
|
|
|
|
|
|
Адрес SFR: |
0xE3 |
||
Таблица 10. Описание битов регистра PFE0CN |
|
|
|
|
|
|||||||
Bits 7-6: |
|
Не используются. Читаются как 00b. Запись не оказывает никакого |
||||||||||
|
|
влияния. |
|
|
|
|
|
|
|
|
|
|
Bit5: |
|
PFEN: Разрешение упреждающей выборки. |
|
|
|
|
||||||
|
|
Этот бит включает механизм упреждающей выборки. |
|
|||||||||
|
|
0: Механизм упреждающей выборки отключен. |
|
|
|
|||||||
|
|
1: Механизм упреждающей выборки включен. |
|
|
|
|||||||
Bits 4-1: |
|
Не используются. Читаются как 0000b. Запись не оказывает никакого |
||||||||||
|
|
влияния. |
|
|
|
|
|
|
|
|
|
|
Bit0: |
|
FLBWE: Разрешение записи блока Flash-памяти. |
|
|
|
|||||||
|
|
Этот бит разрешает операции записи блоков Flash-памяти из |
|
|||||||||
|
|
программы пользователя. |
|
|
|
|
|
|
||||
|
|
0: Каждый байт, записываемый во Flash-память из программы |
||||||||||
|
|
пользователя, записываетсяиндивидуально. |
|
|
|
|
||||||
|
|
1: Байты Flash-памяти записываются группами по два. |
|
|||||||||
12
3.Сведения, необходимые для работы с внешним ОЗУ и внутренней Flash-памятью при написании программ на языке C (с использованием кросс-компилятора C51 фирмы Keil Software, Inc.)
Компилятор C51 расширяет набор ключевых слов языка за счет спецификаторов типов памяти [5,6]:
∙data — внутренняя память данных, прямая адресация, адреса 0-127
∙idata — внутренняя память данных, косвенная адресация, адреса 0-255
∙bdata — внутренняя память данных, побитно-адресуемая область,
адреса 0x20-0x2F
∙xdata — внешняя память данных, адреса 0x0000-0xFFFF
∙code — память программ, адреса 0x0000-0xFFFF
3.1.Размещение переменных
Указание типа памяти для размещения переменных производится путем добавления спецификатора перед именем переменной:
char xdata a; |
// переменная типа char |
|
// располагается в области памяти xdata |
int idata b; |
// переменная типа int |
|
// располагается в области памяти idata |
Аналогично переменные, которые являются обобщенными указателями, могут быть размещены в различных областях памяти:
char * p1; |
// обобщенный указатель на переменную типа char; |
|
// сам указатель расположен по умолчанию; |
|
// расположение зависит от настроек проекта |
int * xdata p2; |
// обобщенный указатель на переменную типа int; |
|
// сам указатель размещается в области памяти xdata |
3.2.Указатели на данные
Чтобы задать область памяти, на которую будет указывать переменнаяуказатель, необходимо добавить спецификатор перед символом *:
13
char xdata * p3; // указатель на переменную типа char,
//которая располагается в области памяти xdata;
//сама переменная-указатель располагается
//в области памяти по умолчанию
//(зависит от настроек проекта)
char code * p4; // указатель на переменную типа char,
//которая располагается в области памяти code;
//сама переменная-указатель располагается
//в области памяти по умолчанию
Объявление указателя на конкретный тип памяти, который сам будет явно расположен в каком-то типе памяти:
char xdata * idata p; |
// указатель располагается в области idata, |
//указывает на переменную типа char,
//которая располагается в области xdata
3.3.Примеры функций на языке C для работы с внешним ОЗУ и внутренней Flash-памятью
На рис. 3 приведены примеры функций чтения/записи байта из/во внешнее ОЗУ микроконтроллера C8051F411.
На рис. 4 приведены примеры функций чтения/записи байта из/во встроенную Flash-память, а также пример функции стирания страницы Flashпамяти [3] микроконтроллера C8051F411.
// |
----------------------------------------------------------------------------- |
//XRAM_ByteWrite |
|
//----------------------------------------------------------------------------- |
|
// Возвращаемое значение: нет |
|
// Передаваемые параметры: |
|
// |
1) unsigned int addr – адрес ячейки внешнего ОЗУ , в которую |
// |
осуществляется запись ( должен находиться в |
// |
диапазоне от 0x0000 до 0xFFFF) . |
// |
2) char byte – значение записываемого байта . |
//
// Функция записывает байт <byte> в ячейку внешнего ОЗУ по адресу
//<addr>. //-----------------------------------------------------------------------------
void XRAM_ByteWrite (unsigned int addr, char byte)
{ |
|
char xdata * data write_ptr; |
// Указатель, используемый для записи |
|
// во внешнее ОЗУ |
write_ptr = (char xdata *) addr; |
|
|
14 |
*write_ptr = byte; |
// Записать байт <byte> в ячейку |
|
//внешнего ОЗУ по адресу <addr>, |
|
// хранящемуся в write_ptr |
} |
|
// |
----------------------------------------------------------------------------- |
// XRAM_ByteRead |
|
//----------------------------------------------------------------------------- |
|
// Возвращаемое значение: |
|
// |
unsigned char – байт , считанный из Flash - памяти |
// Передаваемые параметры: |
|
// |
1) unsigned int addr – адрес ячейки внешнего ОЗУ , из которой |
// |
осуществляется считывание ( должен находиться |
// |
в диапазоне от 0x0000 до 0xFFFF) . |
//
// Функция считывает байт <byte> из ячейки внешнего ОЗУ по адресу
<addr>. //-----------------------------------------------------------------------------
unsigned char XRAM_ByteRead (unsigned int addr)
{ |
|
char xdata * data read_ptr; |
// Указатель, используемый для чтения |
|
// из внешнего ОЗУ |
read_ptr = (char code *) addr; |
|
byte = * read_ptr; |
// Считать байт <byte> из ячейки внешнего |
//ОЗУ по адресу <addr>,
//хранящемуся в read_ptr
return byte;
}
Рис. 3. Примеры функций на языке C для работы с внешним ОЗУ
микроконтроллера C8051F411.
//-----------------------------------------------------------------------------
// FLASH_ByteWrite //-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc. // http://www.silabs.com
// Возвращаемое значение: нет // Передаваемые параметры:
// |
1) unsigned int addr – адрес ячейки Flash-памяти, в которую |
// |
осуществляется запись (должен находиться |
// |
в диапазоне от 0x0000 до 0x7DFE). |
// |
2) char byte – значение записываемого байта. |
// |
|
|
15 |
// Функция записывает байт <byte> в ячейку Flash-памяти по адресу
//<addr>. //-----------------------------------------------------------------------------
void FLASH_ByteWrite (unsigned int addr, char byte)
{ |
|
bit EA_SAVE = EA; |
// Переменная, хранящая состояние |
прерываний |
|
char xdata * data pwrite; |
// Указатель, используемый для записи |
|
// во Flash-память |
EA = 0; |
// Запретить прерывания |
VDM0CN = 0xA0; |
// Включить схему слежения за |
|
// напряжением питания (VDD-monitor) |
RSTSRC = 0x02; |
// Использовать VDD-monitor как |
|
// источник сброса МК |
pwrite = (char xdata *) addr; |
|
FLKEY = 0xA5; |
// Записать первый ключевой код в регистр |
|
// FLKEY: 0xA5 |
FLKEY = 0xF1; |
// Записать первый ключевой код в регистр |
|
// FLKEY: 0xF1 |
PSCTL |= 0x01; |
// PSWE = 1 (разрешение записи во |
|
// Flash-память) |
VDM0CN = 0xA0; |
// Включить схему слежения за |
|
// напряжением питания (VDD-monitor) |
RSTSRC = 0x02; |
// Использовать VDD-monitor как |
|
// источник сброса МК |
*pwrite = byte; |
// Записать байт <byte> в ячейку Flash- |
|
// памяти по адресу <addr>, |
|
// хранящемуся в pwrite |
PSCTL &= ~0x01; |
// PSWE = 0 (запрещение записи во Flash- |
|
// память) |
EA = EA_SAVE; |
// Восстановить состояние прерываний |
} |
|
//-----------------------------------------------------------------------------
// FLASH_ByteRead //-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc. // http://www.silabs.com
// Возвращаемое значение:
// unsigned char – байт, считанный из Flash-памяти
// Передаваемые параметры:
16
// 1) unsigned int addr – |
адрес ячейки Flash-памяти, из которой |
// |
осуществляется считывание (должен находиться |
// |
в диапазоне от 0x0000 до 0x7DFE). |
// |
|
// Функция считывает байт <byte> из ячейки Flash-памяти по адресу |
|
//<addr>. |
|
//----------------------------------------------------------------------------- |
|
unsigned char FLASH_ByteRead (unsigned int addr) |
|
{ |
|
bit EA_SAVE = EA; |
// Переменная, хранящая состояние |
прерываний |
|
char code * data pread; |
// Указатель, используемый для чтения |
|
// из Flash-памяти |
EA = 0; |
// Запретить прерывания |
pread = (char code *) addr; |
|
byte = *pread; |
// Считать байт <byte> из ячейки Flash- |
|
// памяти по адресу <addr>, |
|
// хранящемуся в pread |
EA = EA_SAVE; |
// Восстановить состояние прерываний |
return byte; |
|
} |
|
//-----------------------------------------------------------------------------
// FLASH_PageErase //-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc. // http://www.silabs.com
// Возвращаемое значение: нет // Передаваемые параметры:
// |
1) unsigned int addr – адрес ячейки Flash-памяти, содержащейся в |
// |
стираемой странице Flash-памяти |
// |
(должен находиться в диапазоне |
// |
от 0x0000 до 0x7DFE). |
//
//Функция стирает страницу Flash-памяти, содержащую ячейку с адресом
//<addr>. //-----------------------------------------------------------------------------
void FLASH_PageErase (unsigned int addr)
{ |
|
bit EA_SAVE = EA; |
// Переменная, хранящая состояние |
прерываний |
|
char code * data pread; |
// Указатель, используемый для чтения |
|
// из Flash-памяти |
EA = 0; |
// Запретить прерывания |
|
17 |
VDM0CN = 0xA0; |
// Включить схему слежения за |
|
// напряжением питания (VDD-monitor) |
RSTSRC = 0x02; |
// Использовать VDD-monitor как |
|
// источник сброса МК |
pwrite = (char xdata *) addr; |
|
FLKEY = 0xA5; |
// Записать первый ключевой код в регистр |
|
// FLKEY: 0xA5 |
FLKEY = 0xF1; |
// Записать первый ключевой код в регистр |
|
// FLKEY: 0xF1 |
PSCTL |= 0x03; |
// PSWE = 1; PSEE = 1 |
VDM0CN = 0xA0; |
// Включить схему слежения за |
|
// напряжением питания (VDD-monitor) |
RSTSRC = 0x02; |
// Использовать VDD-monitor как |
|
// источник сброса МК |
*pwrite = 0; |
// Стереть страницу Flash-памяти |
PSCTL &= ~0x03; |
// PSWE = 0; PSEE = 0 |
EA = EA_SAVE; |
// Восстановить состояние прерываний |
} |
|
Рис. 4. Примеры функций на языке C для работы со внутренней Flash-памятью микроконтроллера C8051F411.
18
4.Задачи
Полученные от преподавателя задания необходимо выполнить на языках Assembler и Си. Для полного освоения материала рекомендуется выполнить все предложенные задания.
4.1.Раздел 1
1.Записать константу в ячейку памяти 240h внешнего ОЗУ. Используя инкремент указателя данных, записать другую константу в ячейку памяти 241h внешнего ОЗУ. Сложить значение ячейки памяти 240h со значением ячейки 241h. Если результат получился больше, чем 0xFF, то определить наибольшее и наименьшее значения содержимого ячеек 240h
и241h и вычесть наименьшее из наибольшего. Результат поместить в ячейку 242h. Иначе сохранить значение суммы по адресу 243h. Проверить с различными константами.
2.Записать константу в ячейку памяти 350h внешнего ОЗУ. Используя инкремент указателя данных, записать другую константу в ячейку памяти 351h внешнего ОЗУ. Сложить значение ячейки памяти 350h со значением ячейки 351h. Если результат получился больше, чем 0xFA, то определить наименьшее значение содержимого ячеек 350h и 351h и вычесть его из 0xFA. Результат поместить в ячейку 352h. Иначе сохранить значение суммы по адресу 353h. Проверить с различными константами.
3.Записать константу в ячейку памяти 150h внешнего ОЗУ. Используя инкремент указателя данных, записать другую константу в ячейку памяти 151h внешнего ОЗУ. Вычесть значение ячейки памяти 151h из значения ячейки 150h. Если результат получился меньше, чем 0x0A, то определить наибольшее и наименьшее значения содержимого ячеек 150h
и151h и вычесть наименьшее из наибольшего. Результат поместить в R3 банка регистров №3. Иначе сохранить значение разности по адресу 153h. Проверить с различными константами.
4.Записать константу в ячейку памяти 220h внешнего ОЗУ. Используя инкремент указателя данных, записать другую константу в ячейку памяти 221h внешнего ОЗУ. Вычесть значение ячейки памяти 220h из значения ячейки 221h. Если результат получился меньше, чем 0x22, то определить наибольшее значение содержимого ячеек 220h и 221h и сложить его с 0x1C. Результат поместить в R0 банка регистров №2. Иначе сохранить значение разности по адресу 153h. Проверить с различными константами.
5.Записать константу в ячейку памяти 2Сh страницы 2 внешнего ОЗУ, используя регистр EMI0CN. Записать константу в ячейку памяти F0h внешнего ОЗУ, выделить 2,5,7 биты, в случае если все выделенные биты равны 1, умножить содержимое ячейки 2Сh страницы 2 на 3. Если нет,
19
сложить содержимое ячеек 2Сh страницы 2 и F0h. Результат поместить в ячейки памяти 2Сh, 2Dh страницы 3. Проверить с различными константами.
6.Записать константу в ячейку памяти 1Dh страницы 4 внешнего ОЗУ, используя регистр EMI0CN. Записать константу в ячейку памяти F1h внешнего ОЗУ, выделить 1,3,6,7 биты, в случае если все выделенные биты не равны 1, разделить содержимое ячейки 1Dh страницы 4 на 5. Если нет, сложить содержимое ячеек 1Dh страницы 4 и F1h. Результат поместить в ячейки памяти 2Сh, 2Dh страницы 3. Проверить с различными константами.
7.Записать константу в ячейку памяти 3Bh страницы 1 внешнего ОЗУ, используя регистр EMI0CN. Записать константу в ячейку памяти F2h внешнего ОЗУ, выделить 0,5,6 биты, в случае если хотя бы один выделенный бит равен 1, разделить содержимое ячейки 3Bh страницы 1 на 4. Если нет, сложить содержимое ячеек 3Bh страницы 1 и F2h. Результат оставить а А. Проверить с различными константами.
8.Записать константу в ячейку памяти 1Ah страницы 3 внешнего ОЗУ, используя регистр EMI0CN. Записать константу в ячейку памяти F3h внешнего ОЗУ, выделить 1,2,4 биты, в случае если хотя бы один выделенный бит равен 0, умножить содержимое ячейки 1Ah страницы 3 на 2. Если нет, сложить содержимое ячеек 1Ah страницы 3 и F3h. Результат оставить а А. Проверить с различными константами.
9.Записать константу в ячейку памяти 151h внешнего ОЗУ. Записать другую константу в ячейку памяти 150h внешнего ОЗУ. Вычесть значение ячейки памяти 151h из значения ячейки 150h. Если результат получился отрицательный, то организовать следующий цикл записи в ячейки внешнего ОЗУ: в ячейку 100h значение ячейки 150h, в ячейку 102h значение ячейки 150h плюс 1, в ячейку 104h значение ячейки 150h плюс 2 и т.д. до ячейки 110h. Иначе сложить младшую тетраду значения ячейки 150h со старшей тетрадой значения ячейки 151h, сдвинутой вправо на 4 бита и записать ответ в ячейку памяти 2Сh страницы 2 внешнего ОЗУ, используя регистр EMI0CN. Проверить с различными константами.
10.Записать константу в ячейку памяти 140h внешнего ОЗУ. Записать другую константу в ячейку памяти 150h внешнего ОЗУ. Вычесть значение ячейки памяти 140h из значения ячейки 150h. Если результат получился неотрицательный, то организовать следующий цикл записи в ячейки внешнего ОЗУ: в ячейку 100h значение ячейки 140h, в ячейку 101h значение ячейки 150h, в ячейку 102h значение ячейки 140h плюс 1, в ячейку 103h значение ячейки 150h плюс 1 и т.д. до ячейки 114h. Иначе сложить младшую тетраду значения ячейки 150h со старшей тетрадой значения ячейки 140h, сдвинутой вправо на 4 бита и записать ответ в ячейку памяти 14h страницы 4 внешнего ОЗУ, используя регистр EMI0CN. Проверить с различными константами.
20
