Перейти к содержанию

    

Шина I2C проблемка

;*******************************************************************************

****************

; RD_I2C.asm Чтение байтов данных из м/схемы памяти 24C64, с использованием

; модуля MSSP м/контроллера PIC16F873A

; (учебная программа)

;*******************************************************************************

****************

; "Практикум по конструированию устройств на PIC контроллерах"

; (http://ikarab.narod.ru) karabea@Lipetsk.ru

;===============================================================================

================

; Автор: И.Н.Шевченко (RW1ZK), г.Заозерск Мурманская обл.

; (PIC18F252, 24C16).

; Е.А.Корабельников: перевод c PIC18F252 на PIC16F873A, с 24С16 на 24С64

; и объяснение работы.

;===============================================================================

================

; Из 24С64 читается 5 байтов, но это количество можно изменить.

; Считанные байты записываются в первые 5 ячеек EEPROM памяти данных PIC16F873A.

; Линии SCL и SDA "подтянуты" к +5V через резисторы 4,7 Ком.

; Кварц 4 Мгц.

;===============================================================================

================

; Функции выводов порта С:

; RC3 - линия SCL - вывод №6 24C64,

; RC4 - линия SDA - вывод №5 24C64,

; остальные выводы порта С не используются.

; Выводы портов А и В не используются.

;-----------------------------------------

; Объем программы: 84 команды.

;*******************************************************************************

****************

LIST p=16F876A ; Задание типа микроконтроллера.

__CONFIG 3F71h ; Включено: XT-генератор, PWRT, сброс BOR.

; Выключено: защита, WDT, LVP, DEBUG.

;===============================================================================

===================

; Регистры специального назначения.

;===============================================================================

===================

Status equ 03h ; Регистр Status.

SSPStat equ 14h ; Регистр статуса модуля MSSP (банк 1).

SSPCon equ 14h ; Регистр управления модуля MSSP.

SSPCon2 equ 11h ; Регистр управления модуля MSSP (банк 1).

SSPAdd equ 13h ; Регистр управления скоростью обмена (банк 1).

SSPBuf equ 13h ; Регистр приемо-передающего буфера.

PIR1 equ 0Ch ; Регистр флагов прерываний от периферийных модулей.

 

 

PortA equ 05h ; Регистр защелок порта A.

TrisA equ 85h ; Регистр выбора направлений работы выводов порта A (банк 1).

;--------------------------------------------

; Регистры управления EEPROM памятью данных.

;--------------------------------------------

EEAdr equ 0Dh ; Регистр адреса (банк 2).

EEData equ 0Ch ; Регистр данных (банк 2).

EECon1 equ 0Ch ; Управляющий регистр (банк 3).

EECon2 equ 0Dh ; Регистр, обеспечивающий защиту

; от случайной записи (банк 3).

;===============================================================================

================

; Регистры общего назачения.

;===============================================================================

================

Temp equ 20h ; Регистр временного хранения считанных байтов.

Byte equ 21h ; Счетчик байтов (он же - указатель адреса).

;===============================================================================

================

; Присвоение битам названий.

;===============================================================================

================

Z equ 2 ; Флаг нулевого результата.

RP0 equ 5 ; Бит выбора банка.

RP1 equ 6 ; Бит выбора банка.

SSPIF equ 3 ; Флаг прерывания от модуля MSSP.

SEN equ 0 ; Бит включения "Старта".

PEN equ 2 ; Бит включения "Стопа".

ACKSTAT equ 6 ; Бит подтверждения от ведомого.

SMP equ 7 ; Бит управления длительностью фронта.

RCEN equ 3 ; Бит разрешения/запрета приема.

ACKEN equ 4 ; Бит подтверждения ведущим приема байта.

;===============================================================================

================

org 0 ; Начать выполнение программы с 0-го адреса PC.

;*******************************************************************************

****************

 

 

;*******************************************************************************

****************

; НАЧАЛО ПРОГРАММЫ.

;*******************************************************************************

****************

; Инициализация модуля MSSP (работа по I2C, режим ведущего, скорость 100 Кгц).

;===============================================================================

================

; Все не задействованные модули отключены по умолчанию.

; Выводы всех портов, по умолчанию, работают на вход. По этой причине, не нужно подтверждать

; обязательную, в данном случае, настройку выводов RC3 (SCL) и RC4 (SDA) на работу "на вход".

; Все регистры SSP... , по умолчанию, сброшены в ноль. Прерывания запрещены.

; Обязательный, в данном случае, нулевой уровень отклика (сигнала АСК) на прием ПИКом байта,

; считанного из 24С64 (ACKDT=0), установлен по умолчанию.

;-----------------------------------------------------------------------------------------------

bsf Status,RP0 ; Переход в 1-й банк.

movlw 9 ; Установка стандартной скорости обмена:

movwf SSPAdd ; Fosc/{4*(SSPAdd+1)}=4Мгц/40=100 Кгц.

bsf SSPStat,SMP ; Управление длительностью фронта выключено,

; т.к. выбрана стандартная скорость (100 Кгц.).

 

movlw b'00000000'

movwf TrisA

 

 

bcf Status,RP0 ; Переход в 0-й банк.

 

clrf Byte ; Сброс счетчика байтов.

movlw b'00101000' ; Включение модуля MSSP (SSPEN=1),

movwf SSPCon ; в режиме I2C-ведущего (SSPM3..SSPM0=1000).

;*******************************************************************************

****************

; Начало передачи массива байтов.

;*******************************************************************************

****************

; Формирование условия "START".

;===============================================================================

================

bsf PortA,5

call START ; Начало формирования условия "START".

;--->Возврат по стеку из ПП START

;===============================================================================

================

; Передача режимного байта.

;===============================================================================

================

movlw b'10100000' ; Передача режимного байта: 1010 - код функциональности,

call WR_I2C ; 000 - адрес м/схемы, 0 - режим записи.

;--->Возврат по стеку из ПП WR_I2C

;===============================================================================

================

; Передача байтов адреса той ячейки 24C64, из которой будет считан 1-й байт массива

; В данном случае, считывание начнется с 1-й ячейки (адрес 00h).

;===============================================================================

================

movlw 0 ; Передача старшего

call WR_I2C ; байта адреса.

;--->Возврат по стеку из ПП WR_I2C

movlw 10h ; Передача младшего

call WR_I2C ; байта адреса.

;--->Возврат по стеку из ПП WR_I2C

;===============================================================================

================

; Формирование условия "STOP".

;===============================================================================

================

call STOP ; Начало формирования условия "STOP".

;--->Возврат по стеку из ПП STOP

;===============================================================================

================

; Формирование условия "START".

;===============================================================================

================

call START ; Начало формирования условия "START".

;--->Возврат по стеку из ПП START

;===============================================================================

================

; Передача режимного байта.

;===============================================================================

================

movlw b'10100001' ; Передача режимного байта: 1010 - код функциональности,

call WR_I2C ; 000 - адрес м/схемы, 1 - режим чтения.

;--->Возврат по стеку из ПП WR_I2C

;===============================================================================

================

; ПП приема байта и формирования отклика ведущего на принятый байт.

;===============================================================================

================

; Прием байта.

;-------------------------------------

RD_I2C bsf Status,RP0 ; Переход в 1-й банк.

bsf SSPCon2,RCEN ; Разрешение приема текущего байта

; от 24С64 (начало приема).

bcf Status,RP0 ; Переход в 0-й банк.

 

bcf PIR1,SSPIF ; Сброс флага перерываний от модуля MSSP.

 

btfss PIR1,SSPIF ; Прием текущего байта завершен или нет?

goto $-1 ; Если нет, то ожидание.

; Если завершен, то принятый байт аппаратно копируется

; в SSPBuf и программа исполняется далее.

movf SSPBuf,W ; Копирование принятого байта

movwf Temp ; из SSPBuf в Temp.

;++++++++++++++++++++++++++++++++++

; Принятый байт скопирован в Temp.

;----------------------------------------------------

; Формирование отклика ведущего.

;----------------------------------------------------

bsf Status,RP0 ; Переход в 1-й банк.

bsf SSPCon2,ACKEN ; Формирование подтверждения (АСК) принятого байта.

bcf Status,RP0 ; Переход в 0-й банк.

 

bcf PIR1,SSPIF ; Сброс флага перерываний от модуля MSSP.

 

btfss PIR1,SSPIF ; 9-й импульс закончился или нет?

goto $-1 ; Если нет, то ожидание.

; Если закончился, то программа исполняется далее.

;===============================================================================

================

; Запись принятого байта в одну из ячеек EEPROM памяти данных PIC16F873A.

;===============================================================================

================

; Анализ количества записываемых байтов.

;----------------------------------------------------

movlw .16 ; Задание количества записываемых байтов.

subwf Byte,W ; Byte - 5 = ...

btfsc Status,Z ; Записаны все 5 байтов или не все?

goto FINAL ; Если все, то запись заканчивается.

; Если не все, то программа исполняется далее.

;----------------------------------------------------

; Процедура записи в EEPROM память данных PIC16F873A.

;----------------------------------------------------

bcf Status,RP0 ; Переход

bsf Status,RP1 ; во 2-й банк.

movf Byte,W ;

movwf EEAdr ; Byte --> EEAdr.

movf Temp,W ;

movwf EEData ; Temp --> EEData.

bsf Status,RP0 ; Переход в 3-й банк.

 

bcf EECon1,7 ; Выбор режима записи в EEPROM память данных.

bsf EECon1,2 ; Разрешение записи.

 

movlw 55h ; Обязательная

movwf EECon2 ; процедура.

movlw 0AAh ; ---"---

movwf EECon2 ; ---"---

bsf EECon1,1 ; Инициализация записи.

bcf EECon1,2 ; Запрет записи.

 

btfsc EECon1,1 ; Запись завершена или нет?

goto $-1 ; Если нет, то ожидание.

bcf Status,RP0 ; Если завершена, то

bcf Status,RP1 ; переход в 0-й банк.

;----------------------------------------------------

; Подготовка к обработке следующего байта.

;----------------------------------------------------

incf Byte,F ; Byte + 1 = номер/адрес текущего байта.

goto RD_I2C ; Переход на начало обработки следующего байта.

;===============================================================================

================

; Формирование условия "STOP".

;===============================================================================

================

FINAL call STOP ; Начало формирования условия "STOP".

;--->Возврат по стеку из ПП STOP

;------------------------------------

; "Закончен бал, погасли свечи".

;------------------------------------

bcf PortA,5

goto $ ; "Вечное, мертвое кольцо" (вместо него

; может быть продолжение программы).

;===============================================================================

================

; ПП передачи байта и анализа отклика ведомого.

;===============================================================================

================

POVTOR bcf Status,RP0 ; Переход в 0-й банк.

WR_I2C movwf SSPBuf ; Загрузка буфера байтом любой функциональности

; (начало передачи текущего байта).

bcf PIR1,SSPIF ; Сброс флага перерываний от модуля MSSP.

 

btfss PIR1,SSPIF ; Передача текущего байта завершена или нет?

goto $-1 ; Если нет, то ожидание.

; Если завершено, то программа исполняется далее.

;------------------------------------

; Анализ отклика ведомого.

;------------------------------------

bsf Status,RP0 ; Переход в 1-й банк.

btfsc SSPCon2,ACKSTAT; Подтверждение от ведомого (ACK) принято или нет?

goto POVTOR ; Если нет, то повтор передачи текущего байта.

bcf Status,RP0 ; Если есть, то переход в 0-й банк,

return ; после чего - возврат по стеку.

;===============================================================================

================

; ПП формирования условия "START".

;===============================================================================

================

START bcf PIR1,SSPIF ; Сброс флага перерываний от модуля MSSP.

 

bsf Status,RP0 ; Переход в 1-й банк.

bsf SSPCon2,SEN ; Начало формирования условия "START".

bcf Status,RP0 ; Переход в 0-й банк.

 

btfss PIR1,SSPIF ; Формирование условия "START" завершено или нет?

goto $-1 ; Если нет, то ожидание.

; Если завершено, то программа исполняется далее.

return ; Возврат по стеку.

;===============================================================================

================

; ПП формирования условия "STOP".

;===============================================================================

================

STOP bcf PIR1,SSPIF ; Сброс флага перерываний от модуля MSSP.

 

bsf Status,RP0 ; Переход в 1-й банк.

bsf SSPCon2,PEN ; Начало формирования условия "STOP".

bcf Status,RP0 ; Переход в 0-й банк.

 

btfss PIR1,SSPIF ; Формирование условия "STOP" завершено или нет?

goto $-1 ; Если нет, то ожидание.

; Если завершено, то программа исполняется далее.

return ; Возврат по стеку.

;*******************************************************************************

****************

end ; Конец программы.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Честно говоря, не очевидна проблема! Автор, сформулируйте, в чем проявляется проблемка.

Но на первый беглый взгляд видно, что в комментариях речь идет про один контроллер, а в коде обозначается другой (может это не сильно принципиально, но все ж, комментарии должны соответствовать телу кода).

; Е.А.Корабельников: перевод c PIC18F252 на PIC16F873A, с 24С16 на 24С64

 

; Считанные байты записываются в первые 5 ячеек EEPROM памяти данных PIC16F873A.

 

LIST p=16F876A ; Задание типа микроконтроллера.

 

Второе, что мне кинулось в глаза - начало программы располагается директивой ORG 0 и далее поехали...

org 0 ; Начать выполнение программы с 0-го адреса PC.

bsf Status,RP0 ; Переход в 1-й банк.

movlw 9 ; Установка стандартной скорости обмена:

movwf SSPAdd ; Fosc/{4*(SSPAdd+1)}=4Мгц/40=100 Кгц.

...

А как же ветор прерывания, который должен располагаться по адресу 0x04?

ИМХО Должно быть что-то вроде этого:

org      0              ; Начать выполнение программы с 0-го адреса PC.
        goto Start
Start    bsf Status,RP0 ; Переход в 1-й банк.
        movlw 9        ; Установка стандартной скорости обмена:
        movwf SSPAdd   ; Fosc/{4*(SSPAdd+1)}=4Мгц/40=100 Кгц.
...

И тогда компилятор переместит этот участок кода туда куда можно, чтобы не наехать на подпрограмму обработки прерывания. Или, если необходимо жестко указать где должен располагаться код, то перед меткой Start добавить, например, org 0x200

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо Всем за участие. Разобрался. Плохо почитал материал.После считывания последнего байта не нужно формировать АСК должно быть Стоп.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
После считывания последнего байта не нужно формировать АСК должно быть Стоп.
Должно быть NO ACK, а уж затем STOP.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация