Наш канал в telegram

Управляющая программа для устройства копирования микросхем памяти серии 24Cxx

Представленная ниже программа предназначена для микроконтроллера PIC12F629, управляющего работой портативного устройства копирования микросхем памяти серии 24Cxx.

При написании программы использовались стандартные процедуры, позволяющие программно реализовать мастер-абонента шины I2C в режиме single-master. Единственное изменение, которое было сделано при их включении в нашу программу, — это клонирование всех процедур, работающих с линией DATA, для возможности работы с двумя независимыми линиями DATA. Таким образом, у нас получились процедуры, работающие с линией DATA микросхемы-источника (процедуры с индексом T: Data_T_One, Data_T_null и т.д.) и процедуры, работающие с линией DATA микросхемы приёмника (процедуры с индексом R: Data_R_One, Data_R_null и т.д.). Далее вся логика работы собрана из этих стандартных процедур, как из конструктора.

Поскольку алгоритмы стандартных процедур подробно разобраны в отдельной статье, то здесь мы их описывать не будем.

Алгоритм работы управляющей программы:

Алгоритм управления устройством копирования EEPROM

Текст программы под катом

 list    p = 12f629
__config 01FC4h
;*** Переменные ******************************************
CBLOCK 0x20   ; Начальный адрес блока пользовательской памяти
I2C_flags         ;                          20h
Bit_counter       ;                          21h
BTS               ; byte to send             22h
RDB               ; recieved byte            23h
Buf_counter       ; кол-во байт в буфере     24h
Page_counter_low  ; кол-во обработ-х страниц 25h   младший байт
Page_counter_high ; кол-во обработ-х страниц 26h   старший байт
Banks             ; адрес банка              27h
Counter1          ;                          28h
Counter2          ;                          29h
; дальше, по адресам с 2Ah по 31h, будем хранить буфер страницы из 8 байт
ENDC
;**** Константы / Адреса регистров ************************
Status equ  03h         ; выбор банка
Cmcon  equ  19h         ; Регистр Cmcon - компаратора (банк 0)
OSCCAL equ  10h         ; Регистр хранения калибровочной константы (банк 1)
INDF   equ  0h          ; Регистр косвенной адресации
FSR    equ  04h         ; Регистр адреса при косвенной адресации
;---------------------------
Port_reg    equ  05h    ; GPIO - управления защелками порта
Tris_reg    equ  05h    ; TrisIO - выбор направления работы выводов порта
Clock_line  equ  04h    ; GP4
Data_T_line equ  01h    ; GP1
Data_R_line equ  05h    ; GP5
;**********************************************************
; GP0 - светодиод, GP1 - Data трансмиттера, GP2 - вход JP1,
; GP3 - кнопка, GP4 - Clock, GP5 - Data приемника
; в каждом банке 24Сxx может быть максимум 32 (20h)
; страницы по 8 байт при однобайтном счётчике
; или 8192 (2000h) страницы по 8 байт при двухбайтном счётчике
;**********************************************************
 
org 0
;*********************************************************
;*** КОНФИГУРИРОВАНИЕ КОНТРОЛЛЕРА ************************
;*** Калибровка Генератора *******************************
start  bsf    Status,5
Call   3FFh        ; Загрузить калибровочную константу в w
movwf  OSCCAL
;*** Установка направления работы ног ********************
main   bcf    Status,5    ; перейти в банк 0
clrf   Port_reg    ; инициализация защелок (все выходы равны нулю)
movlw  .7          ; биты 0..2 поднять
movwf  Cmcon       ; компаратор выключен, GP0, GP1, GP2 - цифровые вх/вых
bsf    Status,5    ; Перейти в 1-й банк
movlw  b'00111110' ; настройка выходов,
; GP3 - вход, Clock и обе Datы сначала ставим на вход)
movwf  Tris_reg
bcf    Status,5    ; перейти в банк 0
;*** РАБОЧАЯ ЧАСТЬ ***************************************
clrf   I2C_flags
;--- Читаем джампер -------------------
btfsc  Port_reg,2  ; если JP1 замкнут - на входе 0 (однобайтный адрес)
bsf    I2C_flags,1 ; флаг 1 будет хранить выбранный тип адресации
;--- Инициализируем банки -------------
movlw  0A0h        ; сначала пишем в первый банк
movwf  Banks
;-----------------------------------
work   btfsc  Port_reg,3  ; если вх.кнопки=0 -> значит она нажата
goto   work
;------------------------------------
;--- Инициализация адреса первой микрухи ------
no_ack1
call   Start_T_uslovie  ; старт
movlw  0A0h
movwf  BTS
call   Send_T_Byte  ; посылаем А0 - передача
btfsc  I2C_flags,0
goto   no_ack1
movlw  .0
movwf  BTS
call   Send_T_Byte  ; посылаем начальный адрес
movlw  .0
movwf  BTS
btfsc  I2C_flags,1
call   Send_T_Byte  ; если флаг адресации=1, - шлём второй байт адреса
call   Stop_T_uslovie
;------------------------------------
next_bank
clrf   Page_counter_low
clrf   Page_counter_high
;--- Чтение из микрухи 1 ------------
next_page
call   Start_T_uslovie   ; старт
movlw  0A1h
movwf  BTS
call   Send_T_Byte       ; посылаем А1 - приём
;-----------------------
movlw  .7
movwf  Buf_counter
movlw  2Ah
movwf  FSR
;-----------------------
next_byte_rt
call   Recieve_T_Byte   ; принимаем байт
movf   RDB,0
movwf  INDF             ; и сохраяем его по адресу FSR
incf   FSR,1
decfsz Buf_counter,1
goto   next_byte_rt
bsf    I2C_flags,0
call   Recieve_T_Byte   ; дочитываем последний байт страницы
movf   RDB,0
movwf  INDF             ; и сохраяем его по адресу FSR
Call   Stop_T_uslovie   ; стоп
;------------------------------------
;------------------------------------
;--- Запись в микруху 2 -------------
call   Start_R_uslovie  ; старт
movf   Banks,0
movwf  BTS
call   Send_R_Byte      ; посылаем заявку на передачу в нужный банк
btfsc  I2C_flags,0
goto   no_bank          ; если нет ответа - значит этот банк отсутствует
movf   Page_counter_high,0
movwf  BTS
call   Send_R_Byte      ; посылаем начальный адрес
movf   Page_counter_low,0
movwf  BTS
btfsc  I2C_flags,1
call   Send_R_Byte      ; если флаг адресации=1, - шлём второй байт адреса
;-----------------------
movlw  .7
movwf  Buf_counter
movlw  2Ah
movwf  FSR
;-----------------------
next_byte_tr
movf   INDF,0           ; читаем байт из буфера
movwf  BTS
call   Send_R_Byte      ; шлём байт
incf   FSR,1
decfsz Buf_counter,1
goto   next_byte_tr
movf   INDF,0           ; читаем байт из буфера
movwf  BTS
call   Send_R_Byte      ; шлём последний байт страницы
Call   Stop_R_uslovie   ; стоп
;--- Ждём окончания записи -------------
no_ack2
call   Start_R_uslovie  ; старт
movlw  0A0h
movwf  BTS
call   Send_R_Byte      ; посылаем A0 - запись
btfsc  I2C_flags,0
goto   no_ack2
call   Stop_R_uslovie
;------------------------------------
btfsc  I2C_flags,1      ; если 1 байт адреса - пропустить следующ.команду
goto   extended_address
movlw  .8
addwf  Page_counter_high,1
btfss  Status,2         ; если счетчик=0, - мы скопировали банк целиком
goto   next_page
goto   no_bank
;------------------------------------
;--- для двухбайтного счётчика ------
extended_address
movlw  .8
addwf  Page_counter_low,1
btfsc  Status,2            ; если счётчик не=0 - следующ. команда пропуск.
incf   Page_counter_high,1 ; увеличить старший байт адреса
movf   Page_counter_low,0
iorwf  Page_counter_high,0
btfss  Status,2            ; если оба счётчика=0, - скопирован весь банк
goto   next_page
;--- Проверяем, во все ли банки мы скопировали ---
no_bank
movlw  .2
addwf  Banks,1
movlw  0B0h
xorwf  Banks,0
btfss  Status,2    ; если скопировали все банки - идём дальше
goto   next_bank
;------------------------------------
;************************************
lamp_signal
bsf    Port_reg,0
call   short_pause
bcf    Port_reg,0
call   long_pause
goto   lamp_signal
;************************************
;------------------------------------
Clock_null
bcf    Port_reg, Clock_line
bsf    Status,5
bcf    Tris_reg, Clock_line
bcf    Status,5
return
Clock_one
bsf    Status,5
bsf    Tris_reg, Clock_line
bcf    Status,5
return
Data_T_null
bcf    Port_reg, Data_T_line
bsf    Status,5
bcf    Tris_reg, Data_T_line
bcf    Status,5
return
Data_T_one
bsf    Status,5
bsf    Tris_reg, Data_T_line
bcf    Status,5
return
Data_R_null
bcf    Port_reg, Data_R_line
bsf    Status,5
bcf    Tris_reg, Data_R_line
bcf    Status,5
return
Data_R_one
bsf    Status,5
bsf    Tris_reg, Data_R_line
bcf    Status,5
return
;------------------------------------
Start_T_uslovie
call   Clock_one
call   Data_T_null
call   Clock_null
return
Stop_T_uslovie
call   Data_T_null
call   Clock_one
wait_clock_p
btfss  Port_reg, Clock_line
goto   wait_clock_p
call   Data_T_one
return
;------------------------------------
Start_R_uslovie
call   Clock_one
call   Data_R_null
call   Clock_null
return
Stop_R_uslovie
call   Data_R_null
call   Clock_one
wait_clock_p1
btfss  Port_reg, Clock_line
goto   wait_clock_p1
call   Data_R_one
return
;------------------------------------
Send_T_Byte
bcf    I2C_flags,0    ; посылка байта микрухе источнику
movlw  .8
movwf  Bit_counter
next_bit_st
btfsc  BTS,7
Call   Data_T_one
btfss  BTS,7
call   Data_T_null
call   Clock_one
wait_clock_st1
btfss  Port_reg, Clock_line 
goto   wait_clock_st1
call   Clock_null
rlf    BTS,1
decfsz Bit_counter,1 
goto   next_bit_st
call   Data_T_one
call   Clock_one
wait_clock_st2
btfss  Port_reg, Clock_line 
goto   wait_clock_st2
btfsc  Port_reg, Data_T_line 
bsf    I2C_flags,0
call   Clock_null 
return
;------------------------------------
Recieve_T_Byte
clrf   RDB
movlw  .8
movwf  Bit_counter
next_bit_rt
bcf    Status,0
rlf    RDB,1
call   Data_T_one
call   Clock_one
wait_clock_rt1
btfss  Port_reg, Clock_line
goto   wait_clock_rt1
btfsc  Port_reg, Data_T_line
bsf    RDB,0
call   Clock_null
decfsz Bit_counter,1
goto   next_bit_rt
btfss  I2C_flags,0
call   Data_T_null
btfsc  I2C_flags,0
call   Data_T_one
call   Clock_one
wait_clock_rt2
btfss  Port_reg, Clock_line
goto   wait_clock_rt2
call   Clock_null
return
;---------------------------------
Send_R_Byte
bcf    I2C_flags,0    ; посылка байта микрухе приёмнику
movlw  .8
movwf  Bit_counter
next_bit_sr
btfsc  BTS,7
Call   Data_R_one
btfss  BTS,7
call   Data_R_null
call   Clock_one
wait_clock_sr1
btfss  Port_reg, Clock_line 
goto   wait_clock_sr1
call   Clock_null
rlf    BTS,1
decfsz Bit_counter,1 
goto   next_bit_sr
call   Data_R_one
call   Clock_one
wait_clock_sr2
btfss  Port_reg, Clock_line 
goto   wait_clock_sr2
btfsc  Port_reg, Data_R_line 
bsf    I2C_flags,0
call   Clock_null 
return
;---------------------------------
Recieve_R_Byte
clrf   RDB
movlw  .8
movwf  Bit_counter
next_bit_rr
bcf    Status,0
rlf    RDB,1
call   Data_R_one
call   Clock_one
wait_clock_rr1
btfss  Port_reg, Clock_line
goto   wait_clock_rr1
btfsc  Port_reg, Data_R_line
bsf    RDB,0
call   Clock_null
decfsz Bit_counter,1
goto   next_bit_rr
btfss  I2C_flags,0
call   Data_R_null
btfsc  I2C_flags,0
call   Data_R_one
call   Clock_one
wait_clock_rr2
btfss  Port_reg, Clock_line
goto   wait_clock_rr2
call   Clock_null
return
;************************************
short_pause
movlw  .100
movwf  Counter1
cikl1  movlw  .255
movwf  Counter2
cikl2  nop
nop
decfsz Counter2,1
goto   cikl2
decfsz Counter1,1
goto   cikl1
return
;-------------------------
long_pause
movlw  .250
movwf  Counter1
cikl3  movlw  .255
movwf  Counter2
cikl4  nop
nop
decfsz Counter2,1
goto   cikl4
decfsz Counter1,1
goto   cikl3
return
end
;---------------------------------

[свернуть]

Скачать готовую прошивку и asm-файл

Добавить комментарий