Свежие обсуждения
Микроконтроллеры

Ликбез по программированию PIC

1 80 99

Zandy: SAK: А если написать: org 0x2105 ?
Процедура не будет осуществлена. В директиве org 0x2100, 0x2100 - не номер ячейки, а программный вектор

Тогда как понимать комментарий к примерам из MPASM Help:

PIC16 Application Example - de
#include p16f877a.inc ;Include standard header file for the selected device.
org 0x2100 ;The absolue address 2100h is mapped to the 0000 location of EE data memory.
;You can create a data or character table starting from any address in EE data memory.

 

Zandy: Наверное не WR, а EEIF

Да, конечно. Невнимательно посмотрел

Zandy: Т.е. программа перейдет по вектору org4? А как это? Ведь GIE = 0 при записи.

Да, перейдёт. GIE = 0 только во время инициализации процесса записи:


BSF STATUS, RP0 ; Bank 1
BSF EECON1, WREN ; Enable write
BCF INTCON, GIE ; Disable INTs.
MOVLW 55h ;
MOVWF EECON2 ; Write 55h
MOVLW AAh ;
MOVWF EECON2 ; Write AAh
BSF EECON1,WR ; Set WR bit
; begin write
BSF INTCON, GIE ; Enable INTs.

Это из даташита, в последней строчке GIE возвращается в 1.

Zandy: Если мне надо по ходу программы сразу после записи разрешить прерывания, ну например по таймеру? Я не могу этого делать, пока не возникло прерывание по завершению записи? Делать паузу?

Я думаю, это уже прояснилось

 

SAK: You can create a data or character table starting from any address in EE data memory.
Если честно, то хрен его знает. Ведь директива org указывает адрес счетчика команд PC.

В описании к MPASMу написано, что директива org 0x2100 инициализирует запись в EEPROM.
Дальше ведь идет еще одна директива DE

 

Zandy: директива org указывает адрес счетчика команд PC
На самом деле у этой директивы более общее назначение - она указывает по какому адресу должна расположиться следующая за ней команда. А этой командой может быть команда процессора, объявление регистровой переменной или объявление некоторых данных в EEPROM.

 

AHTOXA: BSF INTCON, GIE ; Enable INTs.
Я читал даташит. Там написано, что это необязательная процедура. Ну в принципе понятно. Если разрешили прерывания, то в обработчике надо сначала проверять, от чего эти прерывания, так? А уж какое прерывание первым случится, это не известно.

А вот еще вопрос. Если EEIE в PIE1 равен 0 и я не проверяю флаг EEIF в PIR1, могу ли я сразу после записи в EEPROM написать команду "sleep"? Или я должен организовать цикл с проверкой флага EEIF и только удостоверившись, что EEIF=1,сбросить его и продолжить программу командой "sleep"? И нужно ли вообще сбрасывать EEIF, если EEIE=0 и я не хочу проверять, была ли запись? Ну доверчивый я такой.

 

Zandy: Я читал даташит. Там написано, что это необязательная процедура.

Не обижайтесь, Zandy! Я же этого не знаю, вот и пишу всё подробно.

Но, похоже, мы читаем разные даташиты Вот что в моём (на pic16f6xx):

We strongly recommend that interrupts be disabled during this code segment. A cycle count is executed during the required sequence. Any number that is not equal to the required cycles to execute the required sequence will cause the data not to be written into the EEPROM.

Переведу на всякий случай:
Мы настоятельно рекомендуем запрещать прерывания при выполнении этого сегмента кода. При выполнении последовательности ведётся подсчёт числа циклов. Любое число циклов кроме положенного приведёт к тому, что данные не запишутся в ЕЕПРОМ.

О как! То есть, если написать:


MOVLW 55h ;
MOVWF EECON2 ; Write 55h
MOVLW AAh ;
MOVWF EECON2 ; Write AAh
,
то запишется, а если:

MOVLW 55h ;
MOVWF EECON2 ; Write 55h
NOP
MOVLW AAh ;
MOVWF EECON2 ; Write AAh
,
то уже нет.

Zandy: Если разрешили прерывания, то в обработчике надо сначала проверять, от чего эти прерывания, так?

Да.

Zandy: Если EEIE в PIE1 равен 0 и я не проверяю флаг EEIF в PIR1, могу ли я сразу после записи в EEPROM написать команду "sleep"?

А как тогда просыпаться? И я не знаю, работает ли запись в спячке. (По идее, должна)

Для SLEEP больше подходит второй из приведённых мной вариантов. Разрешить прерывание EEIE, дать команду на запись - и спать. По завершении записи возникает прерывание, просыпаемся, пишем след. байт...

 

Zandy: И нужно ли вообще сбрасывать EEIF, если EEIE=0 и я не хочу проверять, была ли запись? Ну доверчивый я такой.

Я бы сбросил Вряд ли он сбрасывается сам, при записи следующего байта. Получится, что все байты кроме первого запишутся "мгновенно"...
Или проверяйте WR, про него написано, что он сбрасывается аппаратно при завершении записи.

 

Я использовал вот такие процедуры проц. PIC16F628 (делал таймер с ЖКИ и уставки записывал в ЕЕPROM)
;------------------------------------
; Подпрограмма чтения ЕЕPROM ;
; в W адрес читаемой ячейки памяти ;
; после чтения данные в W ;
;------------------------------------
Read_EEPROM ;
Bank_1 ; Переходим на банк памяти №1
movwf EEADR ; Загружаем адрес ячейки
bsf EECON1,RD ; Начинаем чтение
movfw EEDATA ; Значение в W
Bank_0 ; Переходим на банк памяти №0
return ; Выход
;------------------------------------
;сохраняем время в EEPROM
;------------------------------------
Save_EEPROM
movlw b'00000000' ; Запрещаем все прерывания
movwf INTCON ;
movfw Reg_HOUR ; загружаем данные(часы)
Bank_1 ; Переход на банк памяти №1
movwf EEDATA ;
movlw 0x00 ; Записываем адрес ячейки EEPROM
movwf EEADR ;
bsf EECON1,WREN ; Разрешаем запись
movlw 0x55 ;
movwf EECON2 ; Записываем 55h
movlw 0xAA ;
movwf EECON2 ; Записываем AAh
bsf EECON1,WR ; Запускаем запись
Wr_hour btfsc EECON1,WR ; Ждем завершения
goto Wr_hour ; записи
Bank_0 ; Переход на банк памяти №0
movlw b'10100000' ; Разрешаем прерывание от
movwf INTCON ; ТМR0

При записи в EEPROM (по крайней мере у меня) данные в память заносились не корректно. Удалось избавиться
введением контроля бита WR (как только бит сбрасывается то запись завершена).

С прерываниями от EEPROM и выходом из SLEEP по завершении записи, не работал (не требовалось пока)

 

AHTOXA: MOVLW 55h ;MOVWF EECON2 ; Write 55hMOVLW AAh ;MOVWF EECON2 ; Write AAh
это т.н. "магическая последовательность". Сделано специально, чтобы предотвратить случайную запись в ЕЕПРОМ (например, при сбое программы). Поэтому и рекомендуют отключать прерывание, чтобы в штатном режиме оно вдруг не зозникло, при выполнении этой магической последовательности.

AHTOXA: Я бы сбросил
чесно говоря, я точно не помню, сбрасывал его или нет , но приведеный мною выше пример работает нормально.

 

AlexAlcoa: Удалось избавиться
введением контроля бита WR (как только бит сбрасывается то запись завершена).

Вот уже второй раз. Так как все-таки надо проверять окончание записи? Почему нельзя проверять взведение флага EEIF в PIR1, а именно сброс WR в EECON1. В чем разница?
Ведь флаг прерывания взводится независимо от того, разрешено глобальное прерывание (GIE=1) или нет (GIE=0). Или я не прав?
А потом, если я EEIF не сбросил, то впоследствии при глобальном разрешении прерываний, я ж уйду по org4, а мне допустим этого не надо?...