Драйвер ЖК-дисплея на отечественных деталях. Принцип работы ЖК-индикатора. Диаграммы напряжений на электродах ЖК-индикатора

Страницы работы

Фрагмент текста работы

Распространяемые в Internet библиотеки зачастую также имеют подробные комментарии и файлы описаний,

ЛИСТИНГ ПРОГРАММЫ ДРАЙВЕРА ЧАСОВ

Программа управления часами-термометром с

жидкокристаллическим индикатором

Использованные компоненты схемы:

Микроконтроллер - PIC16F84 04I/P

Часы реального времени - DS1307

Термометр - DS1621

Индикатор - ИЖЦ21 -4/7

Регистры индикатора - КР1533ИР24 (4шт)

Используемые выводы микроконтроллера:

АО (17) - строб записи в регистры , 

А1 (18) - данные для индикации

A2(1) -SCL

A3 (2) - SDA

А4 (3) - вход 4кГц для таймера

B1       (7) - вход кнопки "+минута"

B2       (8) - вход кнопки "+час"

B3       (9) - подложка для LCD индикатора

list p=16F84

#include <pl 6F84.inc>

_CONFIG _CP_OFF&_ WDT_OFF & _ PWRTE_ON &_XT_OSC

w_temp        EQU 0x0C               ; переменная для временного хранения

status_temp            EQU 0x0D   ; переменная для временного хранения

count 1         EQU ОхОЕ ; рабочий счетчик

count2          EQU OxOF ; рабочий счетчик

count3          EQU 0x10  ; рабочий счетчик

count4          EQU Ox 11  ; рабочий счетчик

flags   EQU Ox 12               ; переменная для хранения флаг-битов

work data     EQU Ox 13   ; рабочая переменная

digit 1 EQU 0x14                ; значение для первого знакоместа

digit2 EQU 0x15                ; значение для второго знакоместа

digit3 EQU Ox 16              ; значение для третьего знакоместа

digit4 EQU Ox 17              ; значение для четвертого знакоместа

digitemp       EQU 0x18    ; промежуточное значение знакоместа

disp    EQU Ox 19              ; счетчик времени отображения

bin      EQU 0x1 А             ; рабочая переменная

tens_and_ones   EQU Ox IB ; рабочая переменная для перекодировки

hundreds      EQU Ox 1С ; рабочая переменная для перекодировки

timelenght   EQU 0x06 ; длительность индикации времени, сек

templenght  EQU 0x06 ; длительность индикации температуры, сек  Импортированные переменные для подпрограмм работы с шиной I2C

STATU           EQU   20     ; Переменная состояния

FLAG  EQU   21                ; Переменная флагов общего назначения

I2CDEV          EQU   22    ; Битовый буфер

ERCODE        EQU   23    ; Код ошибки (для индикации занятости линии)

ADDR EQU   24                ; Переменная адреса

DATAI EQU   25                ; Переменная для хранения входных данных

DATAO          EQU   26    ; Переменная для хранения выходных данных

DATAI_1        EQU    27   ; Переменная для хранения входных данных

DATAO 1       EQU    28   ; Переменная для хранения выходных данных

SLAVE EQU   29                  ; Адрес устройства (YYYYxxx0)

TXBUF           EQU   2А       ; Буфер передачи

RXBUF           EQU   2В       ; Буфер приема

COUNT          EQU   2С       ; Счетчик битов

Битовые переменные (флаги) подпрограмм работы с шиной I2C

ERR1            EQU    0        ; Флаг-бит ошибки (здесь не используется)

SDA              EQU    3        ; RA3, вход/выход данных (SDA)

SLC               EQU    2        ; RA2. тактовая частота (SCL)

DI                 EQU    7        ; Входной бит подпрограммы I2C

DO               EQU    6        ; Выходной бит подпрограммы I2C

ORG 0x000

goto main

ORG   0x000                     ; вектор прерывания

movwf    w. temp            ; сохранение текущего значения W

movf STATUS.w        ; перенос содержимого STATUS в W

movwf statusjemp   ; сохранение содержимого регистра STATUS

clfr     TMR0               ; очистка таймера

bcf INTCON,T0IF       ; сброс флага прерывания

btfsc flags, 1              ; если flags<1>=0 отображаем время

goto tempread         ; если flags< 1 >= 1 отображаем температуру

timeread callclock    ; чтение текущего значения времени

btfss flags, 0              ; разделитель включен?

goto d_point             ; если нет,

bsf digit2, 7               ; то включаем разделичелъ

bcf flags, 0                ; сбрасываем флаг разделителя

goto gohome           ; и выходим из подпрограммы

d_point  bcf digit2, 7   ; иначе выключаем разделитель

bsf lags, 0                 ; устанавливаем флаг разделителя

decfsz disp, f           ; уменьшаем на 1 время индикации. Время истекло?

goto gohome          ; нет, продолжаем отображать часы

bsf flags, 1               ; иначе устанавливаем флаг индикации  температуры

movlw templenght    ; и загружаем в disp

movwf disp                 ; длительность ее отображения

goto gohome

tempread call celsio; чтение текущего значения температуры

btfss flags, О

goto zerot

bcf flags, 0

goto gohome

zerot  bsf flags, 0

decfsz disp, f    ;уменьшаем на 1 время индикации. Время истекло?

goto gohom     ; нет, продолжаем отображать термометр

bcf flags, 1        ; если да, сбрасываем флаг индикации температуры

movlw timelenght  ; и устанавливаем длительность отображения                                                                         времени

movwf disp

movlw 0x9E     ; обращаемся к термометру

movwf SLAVE

movlw 0x9E     ; с командой начать новое измерение

movwf ADDR

call WRCOM

gohome movf status_temp,w  ; чтение копии регистра STATUS

movwf STATUS                ; восстановление значения регистра STATUS swapf w_temp,f

swapf w_temp,w             ; восстановление значения аккумулятора W

retfie                                   ; возврат из прерывания

main      clrf PORTA

clrf PORTB

clrf flags

movlw timelenght

movwf disp

clrwdt                       ; очистка WDT и пределителя

bsf STATUS, RPO   ; bank 1

movhvb '01110010';

movwf OPTION_REG

movlw   b'l 1110000'

movwf PORTA

movlw   b’11110111’

movwf PORTB

bcf STATUS, RPO, bank 0

инициализация часов (DS1307) и термометра (DS1621)

movlw 0х9Е         ; записываем в SLAVE адрес термометра

movwf SLAVE

movlw 0хАС        ; адрес регистра конфигурации термометра

movwf ADDR

movlw 0x0B        ; режимы термометра: POL-high, ISHOT-yes

movwf DATAO

call WRBYTE        ; подпрограмма записи байта

nop                       ; защитный интервал

movlw 0x9E        ; обращение к термометру

movwf SLAVE

movlw 0xEE        ; команда начать измерение температуры

movwf ADDR

call WRCOM       ; запись команды в термометр

nop                      ; защитный интервал

movlw 0xD0       ; проверка пропадания питания

movwf SLAVE     ; установили адрес часов

movlw 0x00        ; установили адрес регистра состояния

movwf ADDR

call RDBYTE         ; считываем регистр состояния

btfss DATAI,7      ; если питание не пропадало, обходим инициализацию

goto okay            ; и начинаем отображать время и температуру

movlw 0xD0       ; иначе - инициализируем часы

movwf SLAVE

clrw

movwf ADDR      ; кварцевый генератор включен

movwf DATAO   ; счетчик секунд сброшен

call WRBYTE      ; запись байта

nop

movlw 0xD0       ; адрес для обращения к часам

movwf SLAVE

movlw 0x01

movwf ADDR

movlw 0x00       ; обнуление счетчика минут

movwf DATAO

call WRBYTE

nopmovlw 0xD0      ; адрес для обращения к часам

movwf SLAVE

movlw 0x02

movwf ADDR

movlw 0x00       ; обнуление счетчика часов

movwf DATAO

call WRBYTE

nop

movlw 0xD0      ; адрес для обращения к часам

movwf SLAVE

movlw 0x07      ; адрес контрольного регистра

movwf ADDR    ; устанавливаем режим отображения 24 часа

movlw    0x91   ; и частоту 4кГц на выходе Tout

movwf DATAO

call WRBYTE

nop;

okay clrf   TMR0         ; очищаем таймер

movlw   b'10100000'

movwf   INTCON       ; разрешаем прерывание no TMR0

repeat btfss PORTB, 1     ; нажата кнопка "+минута"?

call mninc               ; если да, увеличить значение минут

call ind_LCD           ; иначе обновить значение на индикаторе

btfss PORTB, 2      ; нажата кнопка "+час"?

call hrinc                ; если да, увеличить значение часов

call ind_LCD          ; иначе обновить значение на индикаторе

goto repeat

чтение текущего времени из часов

clock movlw 0xD0

movwf SLAVE

movlw 0x01

movwf ADDR

call    RDBYTEN                ; чтение двух байтов: 01H, 02Н

movf DATAI,W

andlw 0x0F

call    convert                   ; табличная перекодировка

movwf digit4

swapf DATAI,F

movf DATAI,W

andlw 0x07

call   convert                    ; табличная перекодировка

movwf digit3

movf DATAI_1,W

andlw 0x0F

call    convert                   ; табличная перекодировка

movwf digit2

swapf DATAI_1,F

movf DATAI_1,W

andlw 0x03

btfsc STATUS,Z

movlw 0x0A

call    convert                    ; табличная перекодировка

movwf   digit 1

return

чтение значения температуры из термометра

celsio movlw  

b’00000000’                              ; гасим первое знакоместо

movwf   digit 1                           ;

movlw   b'01100011'                ; символ "градус"

movwf   digit4                             ; в четвертое знакоместо

movlw 0х9Е

movwf SLAVE

movlw 0xAA

movwf ADDR

call   RDBYTEN                            ; MSB-LSB

movlw   b'01000000'                 ; символ минус

btfss DATAI.7                              ; если бит 7= 1, то температура отрицательная

goto rotate

decf DATAI,f

movwf   digit 1                           ; записали символ минус в первое знакоместо

movlw 0xFF

xorwf DATAI,F

rotate movf DATAI,W

movwf bin

bcf bin,7

call   binary_to_bcd                  ; подпрограмма конвертации

movf tens_and_ones,W

andlw  0x0F

call convert

movwf digit3

swapf tens_and_ones,F

movf tens_and_ones,W

andlw 0x0F

call convert

movwf   digit 2

xorlw 0x3F

btfss STATUS, Z

return                                         ;если в 2-м знакоместе незначащий ноль

movf digit3, w                          ; то для лучшей читаемости значения

movwf digit2                         ; переносим значение из 3-го знакоместа в 2-е

clrf digit4                                   ; гасим 4-е знакоместо

movlw b'01100011'                ;символ "С"

movwf digit3                            ; в третье знакоместо

movf digit2, w

xorlw 0x3F

btfss STATUS, Z                        ; если температура ноль градусов,

return

clrf   digit 1                                ; то символ "плюс/минус" не отображаем

return

подпрограмма отображения 4 символов на ЖК-индикаторе

indJXDbcfPORTB,3                             ; уровень на подложке в 0

movf digit 1, w                                   ; первая цифра в аккумуляторе

movwf digitemp

call loader                                           ; выгрузили биты в индикатор

movf digit2, w                                    ; вторая цифра в аккумуляторе

movwf digitemp

call loader                                           ; выгрузили биты в индикатор

movf digit 3, w                                   ; третья цифра в аккумуляторе

movwf digitemp

call loader                                           ; выгрузили биты в индикатор

movf digit4,w                                     ; четвертая цифра в аккумуляторе

movwf digitemp

call loader                                           ; выгрузили биты в индикатор

call delay                                             ; все данные выгружены, держим   …. . .                                                             ;данные на индикаторе

bsfPORTB,3                                         ; уровень на подложке в 1

movf digitl,w                                      ; первая цифра в аккумуляторе

xorlw 0xFF                                          ; инверсия всех битов

movwf digitemp

call loader                                           ; выгрузили биты в индикатор

movf digit2, w                                    ; вторая цифра в аккумуляторе

xorlw 0xFF                                          ; инверсия всех битов

movwf digitemp

call loader                                          ; выгрузили биты в индикатор

movf digit3, w                                   ; третья цифра в аккумуляторе

xorlw 0xFF                                          ; инверсия всех битов

movwf digitemp

call loader                                          ; выгрузили биты в индикатор

movf digit4,w                                    ; четвертая цифра в аккумуляторе

xorlw 0xFF                                          ; инверсия всех битов

movwf digitemp

call loader                                           ; выгрузили биты в индикатор

call delay                                             ; все данные выгружены, держим   …. . .                                                            ;данные на индикаторе

return

подпрограмма табличной конвертации

принимает и возвращает данные в w

convert addwfPCL, f

retlw  b’00111111’

retlw  b’00000110’

retlw  b’01011011’

retlw  b’01001111’

retlw  b’01100110’

retlw  b’01101101’

retlw  b’01111101’

retlw  b’00000111’

retlw  b’01111111’

retlw  b’01101111’

retlw  b’00000000’

retlw  b’01000000’

retlw  b’00111001’

retlw  b’01011110’

retlw  b’01111001’

подпрограмма выгрузки знакоместа в регистры,

данные в переменной digitemp

loader movlw 0x08

movwf count3

nextbit   bcf PORTA, 0                                  ; строб в 0

btfss digitemp, 7                                ; проверяем старший бит

bcf PORTA, 1                           ; установили порт А1 в 0, если текущий бит=0

btfsc digitemp, 7

bsf PORTA, 1                           ; установили порт А1 в 1, если текущий бит=1

bsf PORTA, 0                                       ; строб в 1, бит записан в регистр

rlf digitemp, f                                      ; сдвиг данных

decfsz count3, f

goto nextbit

return

подпрограмма обработки кнопки "+час"

hrinc clrf   INTCON                                        ; запрещаем все прерывания

bcf flags, 1

movlw timelenght  ;переустанавливаем время работы в режиме «часы»

movwf disp

movlw 0xD0                                        ; читаем текущее время

movwf SLAVE

movlw 0x02

movwf ADDR

call RDBYTE

swapf DATAI, w

andlw0x0F

movwf digitemp                           ; выделили старший полубайт в digitemp

btfss digitemp, 1                               ; если старший разряд не равен 2  

goto high 1                                         ; уходим на другой фрагмент

movf DATAI, w

andlw 0x0F                                         ; выделяем младший полубайт

addlw0x01

movwf w_temp

btfsc w_temp, 2

clrf w_temp                    ; если младший разряд часов =4 обнуляем его

movf w_temp, f

btfsc STATUS, Z

clrf digitemp                   ; и обнуляем старший разряд, получили  00 часов

goto sethr

highl movf DATAI, w

andlw 0x0F                     ;выделяем младший полубайт

addlw0x01

movwf w_temp

sublw 0х0А

btfsc STATUS, Z

clrf w_temp                    ; если младший разряд часов больше 9 обнуляем

btfsc STATUS, Z

incf   digitemp, f             ; прибавляем 1 в старший разряд

sethr swapf digitemp, f

movf digitemp, w

iorwf w_temp, f         ; соединили старший и младший разряды в w_temp

movlw 0xD0

movwf SLAVE

movlw 0x02

movwf ADDR

movf w_temp, w

movwf DATAO

call WRBYTE                  ; записали новое значение в часы

call clock                        ; читаем новое значение времени

bsfdigit2, 7                    ; разделитель постоянно включен

movlw 0x10

movwf count4

reindh call ind_LCD                ; выполняем задержку в 10h циклов индикации

decfsz count4, f

goto reindh

clrf TMR0                      ; очищаем таймер

movlw b’10100000’

movwf INTCON           ; разрешаем прерывание по TMR0

return

подпрограмма обработки кнопки "+минута"

mninc clrf INTCON

bcf flags, 1

movlw timelenght      ; увеличиваем время работы в режиме "часы"

movwf disp

movlw 0xD0                ; читаем текущее время

movwf SLAVE

movlw 0x01

movwf ADDR

call RDBYTE

swapf DATAI, w

andlw 0x0F

movwf digitemp       ; выделили старший полубайт в перем. digitemp

sublw 0x05

btfss STATUS, Z                 ; если старший разряд не равен 5    

goto high4                         ; уходим на другой фрагмент

movf DATAI, w

andlw 0x0F                        ; выделяем младший полубайт

addlw 0x01

movwf w_temp

sublw 0x0A

btfsc STATUS, Z

clrf w_temp                     ; если младший разряд минут =10 обнуляем его

btfsc STATUS, Z

clrf digitemp                    ; и обнуляем старший разряд, получили 00 минут

goto setmin

high4 movf DATAI, w

andlw 0x0F                      ; выделяем младший полубайт

addlw 0x01

movwf w_temp

sublw 0x0A

btfsc STATUS, Z

clrf w_temp                 ; если младший разряд минут больше 9 обнуляем

btfsc STATUS, Z

incf   digitemp, f         ; прибавляем 1 в старший разряд

setminswapf digitemp, f

movf digitemp, w

iorwf w_temp, f        ; соединили старший и младший разряды  в w_temp

movlw 0xD0

movwf SLAVE

movlw    0x01

movwf ADDR

movf w_temp, w

movwf DATAO

call WRBYTE             ; записали новое значение в часы

call clock                                ; читаем новое значение времени

bsfdigit2,7                             ; разделитель постоянно включен

movlw 0x10

movwf count4

reindm   call ind_LCD

decfsz    count4, f

goto reindm

clrf   TMRO                            ; очищаем таймер

movlw b'10100000'

movwf   INTCON                  ; разрешаем прерывание по  TMRO

return

подпрограмма задержки

delay movlw 0x10

movwf count 1

loop2 movlw 0xA0

movwf count2

loopl decfsz count2,1

goto loop 1

decfsz count 1,1

goto loop2

return

ИМПОРТИРОВАННЫЕ ПОДПРОГРАММЫ

Запись одного байта данных в устройство I2C

Входные данные: DATAO = байт данных для записи

ADDR - адрес назначения (в устройстве)

SLAVE = адрес устройства в схеме (1010xxx0)

WRBYTE

MOVF  SLAVE,W                  ; Переносим адрес устройства

MOVWF TXBUF                   ; в буфер передачи

CALL  BSTART                       ; Генерируем бит START

CALL  ТХ                                ; Передаем адрес устройства

MOVF  ADDR,W                   ; Переносим адрес назначения

MOVWF TXBUF                   ; в буфер передачи

CALL  ТХ ,                              ; Передаем адрес назначения

MOVF   DATAO,W               ; Переносим данные

MOVWF TXBUF                   ; в буфер передачи

CALL  ТХ                       ; Передаем данные и анализируем подтверждение

CALL  BSTOP                        ; Генерируем бит STOP

RETURN

Запись команды в устройство I2C

Входные данные: ADDR = команда

SLAVE = адрес устройства в схеме (1010xxx0)

WRCOM

MOVF SLAVE.W                ; Переносим адрес устройства

MOVWF TXBUF                ; в буфер передачи

CALL BSTART                    ; Генерируем бит START

CALL TX                             ; Передаем адрес устройства

MOVF ADDR.W               ; Переносим слово команды

MOVWF TXBUF               ; в буфер

CALL TX                             ; Передаем команду

CALL BSTOP                      ; Генерируем бит STOP

RETURN

Запись ДВУХ байтов данных в устройство I2C

Входные данные: DATAO = 1-й байт данных для записи

DATAO_l = 2-й байт данных для записи

ADDR = адрес назначения (в устройстве)

SLAVE = адрес устройства в схеме (1010xxx0)

WRBYTEN

MOVF SLAVE.W                ; Переносим адрес устройства

MOVWF TXBUF                 ; в буфер передачи

CALL BSTART                      ; Генерируем бит START

CALL TX                               ; Передаем адрес устройства

MOVF ADDR,W                 ; Переносим адрес назначения

MOVWF TXBUF                 ; в буфер передачи

CALL TX                               ; Передаем адрес назначения

MOVF DATAO,W               ; Переносим первый байт данных

MOVWF TXBU                   ; в буфер передачи

CALL  ТХ                 ; Передаем данные и анализируем подтверждение

MOVF DATAO_l,W            ; Переносим второй байт данных MOVWF TXBUF                 ; в буфер передачи CALL  ТХ            ; Передаем данные и анализируем подтверждение

CALL  BSTOP                      ; Генерируем бит STOP

RETURN

Чтение байта данных из устройства I2C

Входные данные: ADDR = адрес назначения (в устройстве)

SLAVE = адрес устройства в схеме (1010xxx0)

Выходные данные: DATAI = байт данных

RDBYTE

MOVF SLAVE,W                     ; Переносим адрес устройства

MOVWF TXBUF                      ; в буфер передачи (R/W - 0)

CALL BSTART                           ; Генерируем бит START

CALL ТХ                                    ; Передаем адрес устройства

MOVF ADDR,W                       ; Переносим адрес назначения

MOVWF TXBUF                       ; в буфер передачи

CALL TX                                     ; Передаем адрес назначения

CALL BSTART                           ; Генерируем бит START

MOVF SLAVE,W                      ; Переносим адрес устройства

MOVWF TXBUF                       ; в буфер передачи

BSF TXBUF,0                            ; Устанавливаем режим READ (R/W=1)

CALL TX                                    ; Передаем адрес устройства

CALL RX                                    ; Читаем байт и подтверждение

CALL BSTOP                             ; Генерируем бит STOP

MOVF RXBUF,W                     ; Сохраняем данные

MOVWF DATAI                       ; в буфере приема DATAI

RETURN

Чтение ДВУХ байтов данных из устройства I2C

Входные данные:    ADDR = адрес назначения (в устройстве)

SLAVE = адрес устройства в схеме (1010ххх0)

Выходные данные: DATAI = 1-й байт данных

DATAI _1 = 2-й байт данных

RDBYTEN

MOVF   SLAVE,W               ; Переносим адрес устройства

MOVWF TXBUF                  ; в буфер передачи (R/W = 0)

CALL  BSTART                      ; Генерируем бит START

CALL  TX                               ; Передаем адрес устройства

MOVF  ADDR,W                 ; Переносим адрес назначения

MOVWF TXBUF                  ; в буфер передачи

CALL  TX                               ; Передаем адрес назначения

CALL  BSTART                      ; Генерируем бит START

MOVF   SLAVE,W                ; Переносим адрес устройства

MOVWF TXBUF                  ; в буфер передачи

BSF   TXBUF,0                      ; Устанавливаем режим READ (R/W = 1)

CALL  TX                               ; Передаем адрес устройства

CALL  RXO                            ; Читаем первый байт и подтверждение

MOVF  RXBUF,W                ; Сохраняем данные

MOVWF DATAI                   ; в буфере приема DATAI

CALL  RX                               ; Читаем второй байт и подтверждение

MOVF  RXBUF,W                ; Сохраняем данные

MOVWF DATAI_1               ; в буфере приема DATAI_1

CALL  BSTOP                        ; Генерируем бит STOP

RETURN

Подпрограмма генерации бита START

Генерируется бит START (SCL удерживается в состоянии 1,

 пока на SDA происходит переход от высокого уровня к низкому)

затем проверяется состояние линии SCL.

 Входных и выходных данных нет.

BSTART

MOVLW B'00000000'                ; Настраиваем SCL и SDA на вывод

MOVWF PORTA                       ; В СООТВЕТСТВИИ СО СХЕМОЙ!!! BSF PORTA,SDA                              ; надо быть уверенным, что SDA=1

BSF PORTA,SCL                       ;устанавливаем SCL=1            

MOVLW 1                                 ; предполагаемый код ошибки 1

BTFSS PORTA,SCL                  ; линия блокирована?

CALL ERR                                 ; если да, обработка кода ошибки

BCF PORTA,SDA                      ; переводим SDA в 0, пока SCL=1

NOP                                            ; защитный временной интервал

NOP

NOP

BCF PORTA,SCL                     ; сбрасываем SCL, START выполнен

RETLW 0

Генерация бита STOP

 Генерируется бит STOP (состояние SDA переходит из 0 в 1,

 пока на SCL удерживается высокий уровень)

 Входных и выходных данных нет.

BSTOP

MOVLW В’00000000’         ; Настраиваем SCL и SDA на вывод

MOVWFPORTA                   ; В СООТВЕТСТВИИ СО СХЕМОЙ!!!

BCF   PORTA,SDA                ; Устанавливаем SDA=0

BSF   PORTA,SCL                 ; Устанавливаем SCL=0

NOP                                        ; Защитный временной интервал

NOP

NOP

MOVLW 1                            ; Предполагаемый код ошибки 1

BTFSS PORTA.SCL               ;SCL=1?

CALL  ERR                            ; Нет, SCL удерживается устройством D0

BSF   PORTA.SDA                ; Переводим SDA из 0 в 1, пока SCL=0

MOVLW 4                              ; Предполагаемый код ошибки 4

BTFSS PORTA,SDA              ;SDA=1?

CALL ERR                              ; Нет, SDA не освобождается для STOP

RETLW О

Получение бита данных из устройства I2C в PIC

BITIN    MOVLW B'00001000'     ; SDA - ввод, SCL - вывод

MOVWF PORTA                ; В СООТВЕТСТВИИ CO СХЕМОЙ

BSF PORTA,SDA

BCF   I2CDEV.DI               ; DI=0

BSF   PORTA,SCL             ;SCL=1

MOVLW 1                          ; Предполагаемый код ошибки

BTFSC PORTA,SCL          ; Пропустить, если SCL=0

GOTO BIT1

BTFSS FLAG,ERR 1          ; Первая ли ошибка обнаружена?

MOVWF ERCODE             ; Сохранить код ошибки

BSF   FLAG,ERR 1             ; Установить флаг ошибки

BIT1 BTFSC PORTA,SDA                ; Читать данные с SDA

BSF   I2CDEV,DI                   ; DI=1 (если считана 1)

NOP                                      ; Защитная задержка

NOP

BCF   PORTA SCL                 ; SCL=0

RETLW 0

Передача бита данных из PIC в устройство I2C

BITOUT

MOVLW B'00000000'        ; SDA, SCL на вывод

MOVWF PORTA                  ; В СООТВЕТСТВИИ CO СХЕМОЙ

BTFSS I2CDEV,DO               ;DO=0?

GOTO   BITO                        ; если да, перейти на BITO

BSF   PORTA,SDA                ;SDA=1

MOVLW 2                            ; предполагаемый код ошибки 2

BTFSC PORTA,SDA              ; проверка на наличие ошибки 2

GOTO  CLK1                         ; если ошибки нет, уйти на CLK1

BTFSS FLAG JERRI               ; первая ли ошибка обнаружена?

MOVWF ERCODE               ; сохраняем код ошибки

BSF FLAG,ERR1                   ; устанавливаем флаг наличия ошибки

GOTO CLK1

BITO BCF   PORTA,SDA             ; SDA=0

NOP                                     ; защитная задержка

NOP

NOP

NOP

NOP

CLK1BSF   PORTA.SCL              ;SCL=1

MOVLW 1                          ; предполагаемый код ошибки 1

BTFSC PORTA,SCL          ; SCL удерживается в 0?

GOTO   ВГТ2                     ; если нет, перейти на ВIТ2

BTFSS FLAG,ERR1          ; если да,

MOVWF ERCODE            ; сохранить код ошибки

BSF   FLAGJERR1            ; установить флаг наличия ошибки

BIT2 NOP                                      ; защитная задержка

NOP

NOP

BCF   PORTA,SCL                         ; возврат SCL в 0

RETLW 0

Получение 8-битных данных из устройства I2C в PIC

Входных данных нет

Выходные данные: принятый байт в переменной RXBUF

RX   MOVLW .8                     ; количество принимаемых битов

MOVWF COUNT

CLRF   RXBUF; очистка буфера приема

RXLP RLF   RXBUF, F                  ; сдвиг данных в буфере из бита переноса

SKPC                                     ; пропустить, если CARRY=1

BCF   RXBUF,0                    ; очистка нулевого бита RXBUF

SKPNC                                  ; пропустить, если CARRY=0

BSF   RXBUF,0                    ; установить в 1 нулевой бит RXBUF

CALL  BITIN                       ; прочитать бит из устройства

BTFSC I2CDEV,DI              ; если входной бит = 1, установить

BSF RXBUF,0                          ; в 1 нулевой бит RXBUF

DECFSZ COUNT, F                ; все биты получены?

GOTO RXLP                            ; нет, продолжить

BSF I2CDEV,DO                     ; установить бит протокола ASK=1

CALL BITOUT                     ; для прекращения дальнейшего обмена данными

RETLW 0

Получение 8-битных данных, в случае, если ASK=0

Полученный байт данных помещается в переменную RXBUF

RXO MOVLW .8                              ; количество принимаемых битов

MOVWF COUNT

CLRF RXBUF                                    ; очистка буфера приема

RXLP0

RLF   RXBUF, F

SKPC

BCF RXBUF.0

SKPNC

BSF RXBUF.0

CALL BITIN

BTFSC I2CDEV.DI

BSF RXBUF,0

DECFSZ COUNT, F

GOTO RXLP0

BCF I2CDEV.DO              ; установить бит протокола ASK=0(!!!)

CALL  BITOUT          ; для прекращения дальнейшего обмена данными

RETLW 0

Побитная передача данных из PIC в устройство I2C

Входные данные: байт в переменной TXBUF

Выходные данные: нет

Данные выводятся побитно через бит переноса CARRY

ТХ    MOVLW .8                  ; количество передаваемых битов

MOVWF COUNT

TXLP BCF   I2CDEV,DO      ; фиксируем выходной бит DO=0

BTFSC TXBUF/7         ; если выводимый бит = 0, DO=0

BSF   I2CDEV,DO        ; иначе DO= 1

CALL  BITOUT            ; подпрограмма вывода бита

RLF   TXBUF, F            ; сдвиг TXBUF влево

SKPC                              ; f(6) --> f(7)

BCF   TXBUF,0             ; f(7) —> carry

SKPNC                           ; carry —> f(0)

BSF TXBUF,0

DECFSZ COUNT, F      ; все биты выведены?

GOTO  TXLP                 ; нет, продолжить

CALL  BITI                   ; читаем бит протокола ASK

MOVLW 3                     ; предполагаемый код ошибки

BTFSC I2CDEV,DI       ; проверяем бит ASK

CALL  ERR                   ; нет подтверждения от устройства

RETLW 0

Подпрограмма обработки кода ошибок шины I2C

Входные данные: регистр W - код ошибки

Выходные данные: переменная ERCODE - код ошибки

FLAG(ERR1)=1

код     причина появления ошибки

1          SCL удерживается в 0 (шина постоянно занята)

2          SDA удерживается в 0 (шина постоянно занята)

3          Нет ответа от устройства

4          SDA не освобождается для генерации бита STOP

Подпрограмма идентифицирует состояние линий SCL и SDA в соответствии

Похожие материалы

Информация о работе