Работа модуля
MSSP по интерфейсу I2C, в режиме ведущего. Учебное устройство записи
массива байтов в 24С64.
1
По большому счету, Иван сработал как "таран" (кстати, на свой страх и риск), что
внушает и уважение, и большой оптимизм, ведь я доподлинно знаю, что было раньше
и что есть сейчас, а также и могу предположить, что будет в будущем.
Прошу учесть, что информация раздела, посвященного модулю MSSP, базируется на
работе Ивана Шевченко, которую я, поставив себя на место Ивана, буду объяснять (в
меру своей испорченности и своих возможностей) поэтапно.
Не исключено "углубление и расширение" (выяснится по ходу дела).
А теперь ближе к делу.
Итак, последовательный интерфейс SPI в расчет не беру (будем считать, что "дедушка
дожил до дембеля").
Соответственно, количество "управленцев" резко сократилось.
Уже значительно легче ("бюрократия страшнее атомной войны").
Почти все оставшиеся "управленцы окопались" в управляющих регистрах модуля MSSP:
- в регистре статуса модуля MSSP: SSPStat,
- и еще в 2-х управляющих регистрах: SSPCon и SSPCon2.
В рассматриваемом случае, интерес представляют только те их биты, которые
"привязаны" к интерфейсу I2C.
После ознакомления с технической документацией (работаю с PIC16F873A), выясняется,
что модуль MSSP может работать в двух режимах:
- ведущего ("мастера") или
- ведомого ("помощника").
Теперь, в соответствии с принципом "разделяй и властвуй", нужно определиться, к
какому из этих режимов "прислониться".
На мой взгляд, изначально, выгоднее "раскрутить" режим ведущего.
Итак, ПИК, по интерфейсу I2C, чем-то будет "рулить".
Не буду особо мудрить, а в качестве "раба", применю то, что было использовано
ранее, то есть, м/схему EEPROM памяти 24С64.
Окончательно формулирую конкретную задачу: необходимо, с помощью модуля MSSP
PIC16F873A, работающего в режиме ведущего, записать массив из, например, 5-ти
байтов данных, в первые 5 ячеек памяти м/схемы 24С64.
Теперь нужно "обратить взор" на управляющие регистры модуля MSSP, и с учетом
того, что режим SPI не используется, и того, что модуль MSSP работает в режиме
ведущего, "выбраковать" те их биты, которые, в данном случае, не используются.
То, что останется после этой "чистки", и будет "сухой осадок" (это и есть "сужение
сектора обстрела"). Получилось вот что:
3
Состояние бита CKP, в данном случае (режим ведущего), не имеет значения.
Биты WCOL и SSPOV - биты "непонимаек".
Если на шине I2C находятся только 2 устройства (как в рассматриваемом случае),
действия производятся строго последовательно/"штатно" и скорость обмена не
"задрана", то об этих битах можно "забыть".
Биты ACKDT и ACKEN нужны для обеспечения формирования ведущим сигнала ACK,
выдаваемого на линию SDA после принятия байта данных от ведомого (при чтении из
24С64).
В данном случае, "их услуги" не требуются (чтения не производится).
Так как модуль MSSP расчитан на работу по протоколу I2C, имеют место быть
выходные каскады с открытым коллектором, и поэтому линии SCL и SDA должны
быть "подтянуты" резисторами к плюсу источника питания, что Вы и видите.
;********************************************************************************
; WR_I2C.asm Запись байтов данных в м/схему памяти 24C64, с использованием
; модуля MSSP м/контроллера PIC16F873A
; (учебная программа)
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах"
; (http://ikarab.narod.ru) karabea@Lipetsk.ru
6
;================================================================================
; Автор: И.Н.Шевченко (RW1ZK) 08.08.2007, г.Заозерск Мурманская обл.
; (PIC18F252, 24C16).
; Е.А.Корабельников: перевод c PIC18F252 на PIC16F873A, с 24С16 на 24С64
; и объяснение работы.
;================================================================================
; Записывается 5 байтов, но это количество можно изменить.
; Линии SCL и SDA "подтянуты" к +5V через резисторы 4,7 Ком.
; Кварц 4 Мгц.
;================================================================================
; Функции выводов порта С:
; RC3 - линия SCL - вывод №6 24C64,
; RC4 - линия SDA - вывод №5 24C64,
; остальные выводы порта С не используются.
; Выводы портов А и В не используются.
;-----------------------------------------
; Объем программы: 55 команд.
;********************************************************************************
LIST p=16F873A ; используется PIC16F873A.
__CONFIG 3F71h ; Включено: XT-генератор, PWRT, сброс BOR.
; Выключено: защита, WDT, LVP, DEBUG.
;================================================================================
; Регистры специального назначения.
;================================================================================
Status equ 03h ; Регистр Status.
IndF equ 00h ; Доступ к памяти через FSR.
FSR equ 04h ; Регистр косвенной адресации.
SSPStat equ 14h ; Регистр статуса модуля MSSP (банк 1).
SSPCon equ 14h ; Регистр управления модуля MSSP.
SSPCon2 equ 11h ; Регистр управления модуля MSSP (банк 1).
SSPAdd equ 13h ; Регистр управления скоростью обмена
; (банк 1).
SSPBuf equ 13h ; Регистр приемо-передающего буфера.
PIR1 equ 0Ch ; Регистр флагов прерываний
; от периферийных модулей.
;================================================================================
; Регистры общего назачения.
;================================================================================
Temp1 equ 20h ; Регистры
Temp2 equ 21h ; хранения
Temp3 equ 22h ; байтов,
Temp4 equ 23h ; предназначенных
Temp5 equ 24h ; для записи.
Byte equ 25h ; Счетчик байтов.
;================================================================================
; Присвоение битам названий.
;================================================================================
RP0 equ 5 ; Бит выбора банка.
SSPIF equ 3 ; Флаг прерывания от модуля MSSP.
SEN equ 0 ; Бит включения "Старта".
PEN equ 2 ; Бит включения "Стопа".
ACKSTAT equ 6 ; Бит подтверждения от ведомого.
SMP equ 7 ; Бит управления длительностью фронта.
;================================================================================
org 0 ; Начать выполнение программы
; с 0-го адреса PC.
;********************************************************************************
;********************************************************************************
; НАЧАЛО ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
movlw 11H ; Загрузка
movwf Temp1 ; байтов
7
movlw 22H ; данных,
movwf Temp2 ; предназначенных
movlw 33H ; для записи
movwf Temp3 ; в 24С64
movlw 44H ; (в данном
movwf Temp4 ; случае,
movlw 55H ; 5 байтов).
movwf Temp5 ; ---"---
;--------------------------------------------------------------------------------
; Инициализация модуля MSSP
; (работа по I2C, режим ведущего, тактовая частота 100 Кгц).
;--------------------------------------------------------------------------------
; Все не задействованные модули отключены по умолчанию.
; Выводы всех портов, по умолчанию, работают на вход. По этой причине, не нужно
; подтверждать обязательную, в данном случае, настройку выводов RC3 (SCL)
; и RC4 (SDA) на работу "на вход".
; Все регистры SSP... , по умолчанию, сброшены в ноль. Прерывания запрещены.
;--------------------------------------------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movlw 9 ; Установка стандартной скорости обмена:
movwf SSPAdd ; Fosc/{4*(SSPAdd+1)}=4Мгц/40=100 Кгц.
bsf SSPStat,SMP ; Управление длительностью фронта выключено,
; (выбрана стандартная скорость 100 Кгц.).
bcf Status,RP0 ; Переход в 0-й банк.
9
В этой программе всего 55 слов.
А без учета 10-ти команд "загрузки" байтов данных в Temp1 … Temp5, команды goto $,
и того меньше.
Можно сделать и еще меньше, если использовать PIC18Fxx (минус "банковские"
переходы).
Иван так и поступил ("зер гут"!!!), но я пока "привязался" к PIC16F873A, а "разборки" с
PIC18Fxx будут устроены позднее (нужно быть последовательным).
Примечание: PIC18Fxx и "фантастишь" это одно и то же (управляемый стек, 2 вектора
прерываний и т.д.). Бог даст, доберусь и до них.
Ниже Вы видите блок – схему "вышележащей" программы:
Работа программы.
В начале программы, в регистры оперативной памяти общего назначения Temp1 …
Temp5, последовательно записываются числовые значения пяти байтов данных,
которые, в дальнейшем, нужно записать в память м/схемы 24С64.
Далее, производится инициализация (настройка) модуля MSSP.
А как же без этого?
;--------------------------------------------------------------------------------
; Инициализация модуля MSSP
; (работа по I2C, режим ведущего, тактовая частота 100 Кгц).
;--------------------------------------------------------------------------------
; Все не задействованные модули отключены по умолчанию.
; Выводы всех портов, по умолчанию, работают на вход. По этой причине, не нужно
; подтверждать обязательную, в данном случае, настройку выводов RC3 (SCL)
; и RC4 (SDA) на работу "на вход".
; Все регистры SSP... , по умолчанию, сброшены в ноль. Прерывания запрещены.
;--------------------------------------------------------------------------------
10
bsf Status,RP0 ; Переход в 1-й банк.
movlw 9 ; Установка стандартной скорости обмена:
movwf SSPAdd ; Fosc/{4*(SSPAdd+1)}=4Мгц/40=100 Кгц.
bsf SSPStat,SMP ; Управление длительностью фронта выключено,
; (выбрана стандартная скорость 100 Кгц.).
bcf Status,RP0 ; Переход в 0-й банк.
;********************************************************************************
; Формирование условия "START".
;================================================================================
bcf PIR1,SSPIF ; Сброс флага перерываний от модуля MSSP.
11
В соответствии с "вышележащей" последовательностью действий, сначала сбрасывается
флаг SSPIF.
В данном случае, его можно и не сбрасывать, так как он сброшен по умолчанию, но в
тех случаях, когда происходит "закольцовка" на начало "стартовой" процедуры, сброс
флага SSPIF, перед началом формирования условия "START", нужен.
Процедура формирования стартового бита "запускается" установкой бита SEN в
единицу.
После этого отрабатывается классическая "плавающая" задержка, работающая с
флагом SSPIF.
По окончании формирования стартового бита, флаг SSPIF аппаратно поднимается, что
приводит к выходу рабочей точки программы из "плавающей" задержки.
Начинается передача байтов:
;================================================================================
; Передача режимного байта.
;================================================================================
movlw b'10100000' ; Передача режимного байта: 1010 - код
call WR_I2C ; функциональности, 000 - адрес м/схемы,
; 0 - режим записи.
;--->Возврат по стеку из ПП WR_I2C
;================================================================================
; Передача байтов адреса той ячейки 24C64, в которую будет записан 1-й байт
; массива. В данном случае, запись начнется с 1-й ячейки (адрес 00h).
;================================================================================
movlw 0 ; Передача старшего
call WR_I2C ; байта адреса.
;--->Возврат по стеку из ПП WR_I2C
movlw 0 ; Передача младшего
call WR_I2C ; байта адреса.
;--->Возврат по стеку из ПП WR_I2C
;================================================================================
; Запись массива байтов в 24С64.
;================================================================================
; Стандартная процедура косвенной адресации.
;-------------------------------------------
movlw 5 ; Задание количества
movwf Byte ; записываемых байтов.
movlw Temp1 ; Сначала передается байт, "лежащий" в
movwf FSR ; Temp_1, а за ним, в порядке увеличения
SNOVA movf IndF,W ; числового значения адреса, и все остальные.
12
call WR_I2C ; Запись в 24C64 текущего байта данных.
;--->Возврат по стеку из ПП WR_I2C
incf FSR,F ; FSR + 1 = ...
decfsz Byte,F ; Записаны все байты данных или не все ?
goto SNOVA ; Если не все, то переход на запись
; следующего байта.
; Если все, то программа исполняется далее.
;================================================================================
; Формирование условия "STOP".
;================================================================================
bcf PIR1,SSPIF ; Сброс флага перерываний от модуля MSSP.
При этом, имеет место быть полная аналогия с формированием условия "START".
Отличие только в том, что в единицу устанавливается не бит SEN, а бит PEN.
Следует учесть то, что эти биты устанавливаются программно, а сбрасываются
аппаратно.
То есть, программно сбрасывать биты SEN и PEN не нужно.
Модуль MSSP их автоматически сбросит и без Вашего участия.
Вот такой приятный "сервис".
У флага SSPIF все наоборот: он устанавливается аппаратно, а сбрасывается
программно.
Цикл передачи массива байтов закончен.
Теперь:
goto $ ; "Вечное, мертвое кольцо" (вместо него
; может быть продолжение программы).
после чего - "уход в вечное кольцо" (программа одноцикловая).
;================================================================================
; ПП передачи байта и анализа отклика ведомого.
;================================================================================
POVTOR bcf Status,RP0 ; Переход в 0-й банк.
WR_I2C movwf SSPBuf ; Загрузка буфера байтом любой
; функциональности
; (начало передачи текущего байта).
bcf PIR1,SSPIF ; Сброс флага перерываний от модуля MSSP.
;....................................................
; Сюда, в случае необходимости, можно "врезать"
; "линейный" или "условно линейный кусок" программы.
;....................................................
btfss PIR1,SSPIF ; Передача текущего байта завершена или нет?
goto $-1 ; Если нет, то ожидание.
13
; Если завершено, то программа
; исполняется далее.
;------------------------------------
; Анализ отклика ведомого.
;------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
btfsc SSPCon2,ACKSTAT; Подтверждение от ведомого (ACK)
; принято или нет?
goto POVTOR ; Если нет, то повтор передачи
; текущего байта.
bcf Status,RP0 ; Если принято, то переход в 0-й банк,
return ; после чего - возврат по стеку.
Итак, модуль MSSP работает по принципу "Вы меня только грамотно запустите в
работу, а я ее сделаю в лучшем виде (без Вас), да еще и отчитаюсь о
результате".
Короче, мечта конструктора …
Но при одном условии: конструктор должен быть грамотным.
То есть, он должен четко представлять себе последствия включения/выключения того
или иного "рубильника".
15
16