Чтение из EEPROM памяти данных
Процесс чтения значительно проще записи. Для этого лишь необходимо сбросить бит EEPGD в 0 – тем самым выбрав EEPROM память, и установить, бит RD в 1 – активировав чтение. Данные будут доступны, после 1 машинного цикла. Пример операции чтения представлен ниже:
; операция чтения из EERPOM памяти
; выбрать необходимый Банк
BANKSEL EEADR ; перейти в банк, где находиться управляющий
; регистр EEADR
; указание адреса
movlw ADDR ; загрузка адреса ячейки памяти в W
movwf EEADR ; загрузка адреса в регистр EEADR
; указание данных
BANKSEL EECON1 ; перейти в банк, где находиться управляющий
; регистр EECON1
BANKSEL EEDATA ; перейти в банк, где находиться управляющий
; регистр EEDATA
movfw value ; загрузка данных в W
movwf EEDATA ; запись данных в EEDATA
bcf EECON1, EEPGD ; выбрать EEPROM память данных
bsf EECON1, RD ; инициализировать чтение
movfw EEDATA ; считать данные, W = EEDATA
Попытайтесь считать, записанные в предыдущем примере данные. Если ничего не выходит, внимательно изучите код, возможно причиной неудачи служит тот факт, что вы не указали верный банк памяти.
Методические указания к выполнению лабораторной работы
Постановка задачи
Написать программу для работы с массивами расположенными, как во
внутренней, так и внешней памяти данных. Один из массивов полностью соответствует тому, что был в лабораторной работе № 5 – это массив № 1, расположен во внутреннем ОЗУ. Массив № 2 имеет структуру такую же, как и массив № 1, но расположен во внешнем ОЗУ. Алгоритм заполнения второго массива произвольный, любой по выбору автора. Массивы необходимо между собой поэлементно и побитно сложить по модулю 2, и поместить на место массива № 1. Работу с каждым из массивов (заполнение, вычисление) оформить в виде отдельной подпрограммы.
Блок-схема алгоритма
Код программы
; Lab_6
;-------------------------------
#include<p17С756А.inc> ; подключение заголовочного файла
; для МК 1886ВЕ2У 16F877
;-------------------------------
#define M D'6' ; кол-во строк
#define N D'5' ; кол-во стоблоц
array EQU 0x30 ; начало массива № 1
array_2 EQU 0x10 ; начало массива № 2 в EEPROM памяти
day EQU 0x50 ; день рождения
month EQU 0x51 ; месяц рождения
arr_size EQU 0x52 ; размер массива
t_val_1 EQU 0x53 ; вр. значения массива № 1
t_val_2 EQU 0x54 ;
status EQU 0x55 ; статус программ:
; бит 0:
; 0 - массив не заполнен
; 1 - массив заполнен
;-------------------------------
org 0x00 ; начало памяти программ (ПП)!
goto main ; произвести переход на метку 'main',
; с которой начнётся выполнение
; основной программы
org 0x05 ; адрес начала размещения кода в ПП
;-------------------------------; фунция расчёта 1-го уравнения
;------ Функции программы ------;
;-------------------------------;
;-------------------------------;
Init_Vars: ; функция инициализации переменных
I2: movlw 0x00 ;
I3: movwf arr_size ;
I4: movwf day ;
movwf month ;
I5: movwf status ;
return ;
;-------------------------------;
Load_Data: ; функция загрузки данных
; массива: размер, адрес начала
LD2: movlw (M*N) ; W = M * N, определить массив
movwf arr_size ; инициализировать размер массива
LD3: movlw array ; взятие адреса массива
movwf FSR ; загрузка адреса в регистр FSR
return ; команда возврата
;-------------------------------;
Load_Data_2: ; функция загрузки данных
; массива 2: размер, адрес начала
H2: movlw (M*N) ; W = M * N, определить маасив
movwf arr_size ; инициализировать размер массива
;------- Указание адреса -------; EEPROM
bcf STATUS,6 ; выбрать банк 00
bcf STATUS,5 ;
H3: movlw array_2 ; загрузка начала массива № 2 в W
BANKSEL EEADR ; перейти в банк, где находиться
; управляющий регистр EEADR
movwf EEADR ; загрузка адреса в регистр EEADR
return ; команда возврата
;-------------------------------;
Load_Vars: ; функция загрузки значений массива
LV2: movlw D'03' ;
movwf day ; день рождения
LV3: movlw D'11' ;
movwf month ; месяц рождения
return ; команда возврата
;-------------------------------;
Load_Vars_2: ; функция загрузки значений массива 2
;------- Указание данных -------; EERPOM
BANKSEL EEDATA ; перейти в банк, где находиться
; управляющий регистр EEDATA
movlw D'1' ; загрузка данных в W
movwf EEDATA ; запись данных в EEDATA
return ; команда возврата
;-------------------------------;
Fill_Arr: ; функция заполнения массива № 1
F2: movfw day ; загрузка 1-го элемента в W
movwf INDF ; запись 1-го элемента
F3: call Cntrl_Size ; контроль
F4: btfss status,0 ; массив заполнен ?
goto F5 ; нет - продолжить
return ; да - выход
F5: call Cntrl_Adr ; перейти к след. адресу
F6: call Wrt_Arr ; запись данных
goto F3 ; повторить заполнение
return ; команда возврата
;-------------------------------;
Fill_Arr_2: ; функция заполнения массива № 2
FA2: call Wrt_Arr_2 ; запись данных
FA3: call Cntrl_Size ; контроль размера
bcf STATUS,6 ; выбор банка 00
bcf STATUS,5 ;
FA4: btfss status,0 ; массив заполнен ?
goto FA5 ; нет - продолжить
return ; да - выход
FA5: call Cntrl_Adr_2 ; контроль адреса
BANKSEL EEDATA ; выбрать банк для EEDATA
FA6: incf EEDATA ; увеличить значение в рег. EEDATA
goto FA2 ; продолжить заполнение
return ; команда возврата
;-------------------------------;
Wrt_Arr: ; запись массива по алгоритму:
; 1-ый эл.: ДР
; 2-ой эл.: ДР + МР
; 3-ый эл.: 2-ой + МР
; 4-ый эл.: 3-ый + МР и т.д.
W2: addwf month,W ; нет продолжить заполнение!
; W = W + month
W3: movwf INDF ; запись элемента из W
return ; команда возврата
;-------------------------------;
Wrt_Arr_2: ; заполнение массива по алгоритму:
; 1-ый эл.: 1
; 2-ой эл.: 1-ый + 1
; 3-ый эл.: 2-ой + 1
; 4-ый эл.: 3-ый + 1 и т.д.
;------- Запись в EERPOM -------;
BANKSEL EECON1 ; перейти в банк, где находиться
; управляющий регистр EECON1
E3: bcf EECON1, EEPGD ; выбрать EEPROM память данных
bsf EECON1, WREN ; разрешить запись в EEPROM память
; данных
bcf INTCON, GIE ; запретить прерывания
; обязательные требования
E4: movlw 0x55 ; записать 55h в регистр EECON2
movwf EECON2 ;
movlw 0xAA ; записать AAh в регистр EECON2
movwf EECON2 ;
E5: bsf EECON1, WR ; инициализировать запись
bsf INTCON, GIE ; разрешить прерывания
bcf EECON1, WREN ; запретить запись в EEPROM
;--- Работа с EEPROM памятью ---;
E6:
BANKSEL EECON1 ; перейти в банк, где находиться
; управляющий регистр EECON1
btfsc EECON1, WR ; проверить завершение
goto $-1 ; операции записи
return ;
;-------------------------------;
Cntrl_Size: ; функция контроля массива:
; размещение в памяти, проверка
; границ
bcf STATUS,6 ;
bcf STATUS,5 ;
CS2: decf arr_size,f ; уменьшение размера на 1
CS3: btfss STATUS,Z ; заполнение завершено ?
return ; нет - выход
CS4: bsf status,0 ; заполнение завершено! Подтвердить!
return ; команда возврата
;-------------------------------;
Cntrl_Adr: ; функция увеличения адреса мас. № 1
CA2: incf FSR,f ; переход к след. адресу
return ; выход
;-------------------------------;
Cntrl_Adr_2: ; функция увеличение адреса мас. № 2
BANKSEL EEADR ; выбрать банк для EEADR
CB2: incf EEADR ; перейти к след. адресу
return ; команда возврата
;-------------------------------;
Read_Arr: ; функция чтения эл. мас. № 1
bcf STATUS,6 ; выбрать банк 0
bcf STATUS,5 ;
RA: movfw INDF ; загрузка эл. массива № 1
movwf t_val_1 ; сохранение
return ; команда возврата
;-------------------------------;
Read_Arr_2: ; функция чтения эл. мас. № 2
BANKSEL EECON1 ; выбор банка для EECON1
RD2 bsf EECON1, RD ; иниициализация чтения для EEPROM
BANKSEL EEDATA ; выбор банка для EEDATA
RD3: movfw EEDATA ; загрузка эл. массива № 2 из EEPROM
bcf STATUS,6 ; выбрать банк 00
bcf STATUS,5 ;
RD4: movwf t_val_2 ; сохранение
return ;
;-------------------------------;
Calc_Xor: ; функция сложения по модулю 2
bcf STATUS,6 ; выбрать банк 00
bcf STATUS,5 ;
CX2: call Init_Vars ; очистка перем.
CX3: call Load_Data ; загрузка данных для мас. № 1
CX4: call Load_Data_2 ; загрузка данных для мас. № 2
CX5: call Read_Arr ; чтение элемента мас. № 1
CX6: call Read_Arr_2 ; чтение элемента мас. № 2
CX7: xorwf t_val_1,W ; сложить "по модулю 2" эл. мас. № 1
; и эл. мас. № 2
CX8: movwf INDF ; записать результат на место мас. № 1
CX9: call Cntrl_Size ; контроль
CX10: btfss status,0 ; массив заполнен ?
goto CX11 ; нет - продолжить
return ; да - выход
CX11: call Cntrl_Adr ; увеличить адрес мас. № 1
CX12: call Cntrl_Adr_2 ; увеличить адрес мас. № 2
goto CX5 ; вернуться в начало для повтора
;-------------------------------;
main: ; начало основной программы
A2: call Init_Vars ; инициализация переменных
A3: call Load_Data ; загрузка данных для массива № 1
A4: call Load_Vars ; загрузка значений для массива № 1
A5: call Fill_Arr ; заполнить массив № 1
A6: call Init_Vars ; инициализация переменных
A7: call Load_Data_2 ; загрузка данных для массива № 2
A8: call Load_Vars_2 ; загрузка значений для массива № 2
A9: call Fill_Arr_2 ; заполнить массив № 2
A10: call Calc_Xor ; сложить мас. № 1,2 по мод. 2
goto main ; перейти на main
END