.
Запись в память программ.
Процесс записи данных в память программ отличается от чтения, хотя и используется подобная TBLRD инструкция для табличной записи - TBLWT. Так же имеет несколько разновидностей, это:
По выполнению команд TBLWT содержимое регистра TABLAT переносится в промежуточный регистр. Три младших разряда регистра (указателя) TBLPTR определяют в какой (из восьми), промежуточный регистр будет записано значение. По заполнению всех восьми регистров можно начать процесс записи.
В операции стирания и записи необходимо задействовать два регистра специального назначения:
Рекомендованная последовательность действий для записи блока Flash памяти программ:
Из практики можно сказать: " То что рекомендовано разработчиком лучше соблюдать". Так или иначе, рекомендации возникают не на пустом месте... По этому, мы не будем отступать от "правил"? , но есть уточнения ...
Очень многие допускают ошибку, предполагая что раз написано 64 байта значит ни больше не меньше записывать нельзя. На самом деле это не так. Записывать можно разное количество блоков по 8 байт (хоть один). А вот процедура стирания действительно блоками по 64 байта. Опять же не стоит путать табличную процедуру стирания с процедурой стирания памяти программ. В табличной процедуре стираются только по 8 байт. Единственное "неудобство" при табличной записи, необходимо следить за расположением таблицы, которая должна начинаться по адресу кратным "8", т.е. 0,8,16,32 и т.д. до 248.
В примере, после записи необходимых данных, выполним ПП проверки записанных данных в память программ.
Хотя запись и производится блоками по 8 байт, при желании можно записать всего один байт, верней изменить один байт из восьми, и записать блок обратно в память программ. . В этом примере мы разберем таблицу из 64 байт, которую скопируем в память данных (ОЗУ) и внесем изменения в значения некоторых регистров. После внесенных изменений запишем весь блок (64 байта) в память программ, соответственно в то же место. А после записи проверим на ошибку. Кроме всего, мы еще получим возможность применения данной подпрограммы в своих приложениях, практически без изменения кода, за исключением некоторых переменных.
Очень важно не "наехать" и не стереть программный код (саму программу). На стадии разработки и отладки MBLAB выдаст вам ошибку, а вот в процессе эксплуатации" программы такое возможно. Для исключения такой ситуации желательно работать с метками, особенно для новичков, метки (названия) таблиц , необходимо располагать в конце программного кода, с учетом сказанного выше (кратность 0,8...) тем самым исключается возможность "наезда". Конечно, это относится к изменению таблиц с данными и если есть необходимость в изменении программного кода, то здесь сам программист должен предусмотреть все возможные ситуации.
Приступим к реализации :
В качестве примера рассмотрим ситуацию, когда необходимо переписать 15 байт в таблице данных "TEST". Естественно можно применить другое название таблицы и другое количество данных.
{showhide title="Смотреть код ПП" template="strong" changetitle="Свернуть код ПП" mousetitleistitle=true closeonclick=true titleasspan=true}
;------------------------------------- ; ПП предварительной записи в ОЗУ необходимых ; данных, с последующей записью в таблицу ; в примере изменяются значения 15 байтов. ;------------------------------------- ZAP_data lfsr FSR0,0x0107 ; Адрес первого регистра для изменения. movlw .14 ; Всего 14 байт movwf Temp ; clrf INDF0 ; Очистить регистр movf POSTINC0 ; Увеличиваем адрес FSR0L на 1 decfsz Temp ; Все очищены? bra $-.6 ; нет,следующий lfsr FSR0,0x013C ; Адрес регистра для изменения. clrf INDF0 ; Очистить регистр return ; Да, возврат из ПП {/showhide}
В результате в ОЗУ у нас будут вот такие данные:
Т.е. мы изменили значения 15 регистров (сбросили в "0") и теперь перезапишем в таблицу "TEST" блоками по 8 байт. Сначала "короткая" запись в промежуточные регистры (8 байт)..
;----------------------------------- ; Короткая запись 8 байт ;----------------------------------- Counter_8 movlw 8 ; Задание количества movwf Counter ; байтов в одном блоке. nop movf POSTINC0,0 ; =Копируем в W значение регистра. movwf TABLAT ; в регистр TABLAT= tblwt*+ ; Запись в защелку decfsz Counter ; Все байты блока записаны? bra $-.8 ; нет,следующий.
Далее , записываем блок в память программ ( "длинная" запись).
;----------------------------------- ; Длинная запись ;----------------------------------- bsf EECON1,EEPGD ; Работа с Flash-памятью программ. bcf EECON1,CFGS ; Обращение к Flash памяти программ bsf EECON1,WREN ; Разрешение записи. bcf INTCON,GIE ; Запрет прерывания movlw 055h ; = movwf EECON2 ; Обязательная movlw 0AAh ; процедура. movwf EECON2 ; = bsf EECON1,WR ; Инициализация цикла записи. nop ; bsf INTCON,GIE ; Разрешение прерывания. decfsz Count_Blok ; Кол-во блоков по 8 байт call Counter_8 ; bcf EECON1,WREN ; Запрет записи. return ; Возврат из прерывания
Для записи более одного блока (8 байт) повторяем процедуру записи столько раз, сколько необходимо записать блоков. В данном примере 8 блоков или 64 байта. После завершения записи проверяем значение соответствующего регистра памяти программ со значением в ОЗУ, тем самым проверяем на ошибку. Если хоть один записанный в памяти программ байт не совпадет с содержимым соответствующих регистров в ОЗУ, установится флаг ошибки (Flag,0).
{showhide title="Смотреть код ПП записи в память программ" template="strong" changetitle="Свернуть код ПП записи в память программ" mousetitleistitle=true closeonclick=true titleasspan=true}
list p=18F252 ; Используется микроконтроллер PIC18F252. #include p18F252.inc ; Подключение INC-файла PIC18F252. ;*************************************************************************** ; Конфигурирование. ;*************************************************************************** CONFIG OSC=XT ; кварц.резонатор CONFIG BOR=OFF ; Сброс по снижению питания выключен CONFIG WDT=OFF ; WDT выключен. CONFIG LVP=OFF ; Режим низковольтного програм. выкл. ;----------------------------------- ; Регистры общ. назначения ;----------------------------------- cblock 00h ; Flag ; Флаг ошибки R_Bute_L ; младший байт кол-ва данных таблицы. R_Bute_H ; старший байт кол-ва данных таблицы. ProvEE_L ; младший байт ProvEE_H ; младший байт Temp ; Counter ; количество байт (всегда 8) Count_Blok ; количество блоков по 8 байт endc ; org 0 ; goto START ; ;----------------------------------- START call W_DATA ; Вызов ПП clrf Flag ; Сброс флага ошибки goto START ; зацикливаем. ;----------------------------------- ; ПП записи в память программ. ;----------------------------------- W_DATA movlw .8 ; movwf Count_Blok ; количество байт (всегда 8) call Ukaz_1 ; TBLPTR на начало таблицы movlw .8 ; количество блоков по 8 байт MULWF Count_Blok ; высчитаваем общее количество байт movff PRODH,R_Bute_H ; Кол-во байт (старший, для коп. в ОЗУ movff PRODL,R_Bute_L ; Кол-во байт (младший),для коп. в ОЗУ movff PRODH,ProvEE_H ; Кол-во байт (старший) для проверки записи movff PRODL,ProvEE_L ; Кол-во байт (младший) для проверки записи incf R_Bute_H ; Коррекция. incf ProvEE_H ; Коррекция. call Ukaz_1 ; TBLPTR на начало таблицы call R_DATA ; Вызов ПП чтения. call ZAP_data ; Тестовая - для демонстрации (удалить) call Ukaz_1 ; TBLPTR на начало таблицы movlw .8 ; =Коррекция subwf TBLPTRL,F ; = movlw 0 ; = subwfb TBLPTRH,F ; = call Counter_8 ; Запись новых данных call Ukaz_1 ; TBLPTR на начало таблицы call PROV_EE ; Проверка записи return ;----------------------------------- ; проверка записи ;----------------------------------- PROV_EE TBLRD*+ ; Чтение байта +1 адрес movf POSTINC0,0 ; CPFSEQ TABLAT ; bsf Flag,0 ; Флаг ошибки. decfsz ProvEE_L ; Все прочитаны? bra PROV_EE ; нет,следующий decfsz ProvEE_H ; Все прочитаны? bra PROV_EE ; нет,следующий return ; Да, возврат из ПП ;----------------------------------- ; Короткая запись 8 байт ;----------------------------------- Counter_8 movlw 8 ; Задание количества movwf Counter ; байтов в одном блоке. nop movf POSTINC0,0 ; =Копируем в W значение регистра. movwf TABLAT ; в регистр TABLAT= tblwt*+ ; Запись в защелку decfsz Counter ; Все байты блока записаны? bra $-.8 ; нет,следующий. ;----------------------------------- ; Длинная запись ;----------------------------------- bsf EECON1,EEPGD ; Работа с Flash-памятью программ. bcf EECON1,CFGS ; Обращение к Flash памяти программ bsf EECON1,WREN ; Разрешение записи. bcf INTCON,GIE ; Запрет прерывания movlw 055h ; = movwf EECON2 ; Обязательная movlw 0AAh ; процедура. movwf EECON2 ; = bsf EECON1,WR ; Инициализация цикла записи. nop ; bsf INTCON,GIE ; Разрешение прерывания. decfsz Count_Blok ; Кол-во блоков по 8 байт call Counter_8 ; bcf EECON1,WREN ; Запрет записи. return ; Возврат из прерывания ;------------------------------------- ; Указаталь TBLPTR на начало таблицы ; FSR0,0x0100 ; Начальный адрес В ОЗУ ;------------------------------------- Ukaz_1 clrf TBLPTRU ; Cбрасываем верхний байт movlw high (TEST); =Задание адреса "TEST" movwf TBLPTRH ; старшего байта= movlw low (TEST); =Задание адреса "TEST" movwf TBLPTRL ; младшего байта= lfsr FSR0,0x0100 ; Начальный адрес В ОЗУ return ;------------------------------------- ; ПП чтения данных из памяти программ ;------------------------------------- R_DATA TBLRD*+ ; Чтение байта +1 адрес movff TABLAT,INDF0 ; Результат в ОЗУ movf POSTINC0 ; Увеличиваем адрес FSR0L на 1 decfsz R_Bute_L ; Все прочитаны? bra R_DATA ; нет,следующий decfsz R_Bute_H ; Все прочитаны? bra R_DATA ; нет,следующий return ; Да, возврат из ПП ;------------------------------------- ; ПП предварительной записи в ОЗУ необходимых ; данных, 15 байт. ПРИМЕР !!! ;------------------------------------- ZAP_data lfsr FSR0,0x0107 ; Адрес первого регистра для изменения. movlw .14 ; Всего 14 байт movwf Temp ; clrf INDF0 ; Очистить регистр movf POSTINC0 ; Увеличиваем адрес FSR0L на 1 decfsz Temp ; Все очищены? bra $-.6 ; нет,следующий lfsr FSR0,0x013C ; Адрес регистра для изменения. clrf INDF0 ; Очистить регистр return ; Да, возврат из ПП ;-------------------------------------------------------- ;ТАБЛИЦА ДАННЫХ 64 БАЙТА (ПРИМЕР) ;-------------------------------------------------------- org 0100h ; размещение таблицы начиная с 0100h TEST db 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, db 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x06, 0x0F, 0x10, db 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, db 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, db 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, db 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x06, 0x0F, 0x10, db 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, db 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, end
{/showhide}
Все права принадлежат ChipMK.ru. При копировании материала ссылка обязательна. 2011-2021 © ChipMK.ru
![]() |
|