Наш магазин на eBay Наш магазин на AliExpress Наш канал в 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-файл

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