Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Эмуляция 1-Wire устройства


Эмуляция 1-Wire устройства

Сообщений 1 страница 13 из 13

1

Завершил начатый еще до отпуска проект...

Что имеем в результате...
Эмуляция 1-Wire устройства "типа DS2408".
Эмулятор выполняет не весь набор команд DS2408, но этого вполне достаточно для обмена данными.
Почему в кавычках ? Потому, что получилась "плюшка" в виде независимых портов ввода/вывода на эмулируемом устройстве.
Это дает возможность существенно расширить схемотехнику применения.

В качестве эмулятора выбран ATMega48.

В железе не проверялось, но в течении декабря опробирование будет сделано, т.к. оригинальные DS2408 уже закончились, а новые стоят, как потасканый Боинг... ;)

Посмотреть работу в Протеусе можно, стянув архив отсюда:
https://yadi.sk/d/ktOPBG_b9jVQLA

PS  Использовались наработки как местных гуру, так и со сторонних сайтов... ;)

0

2

Тема в разделе исходников, а в архиве только прошивка.

0

3

Пётр написал(а):

Тема в разделе исходников, а в архиве только прошивка.

Биг сорри...  :blush:
Код Slave

Код:
'======================================================
' Свободно распространяемый код
' в программе использованы наработки сторонних авторов
' автор не накладывает ограничений на использование
'======================================================
' ATMega48 в качестве эмулятора
' двунаправленного двухпортового (раздельные порты ввода-вывда)
' 8 разрядного порта ввода/вывода по шине 1-Wire
' (расширенный аналог DS2408)
' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
' Реализованы следующие функциональные команды:
'
' Функциональные команды            - не проверялись в железе !
' - Search ROM &HF0
' - Skip ROM &HCC
' - Match ROM &H55
' - Read ROM &H33
'
' Контрольные функциональные команды
' - Channel Access Read &HF5
' - Channel Access Write &H5A
'======================================================
'======================================================
$Regfile="m48def.dat"
$Crystal=8000000
$hwstack=16
$swstack=16
$framesize=32

'======================================================
Const dqpin = 3                                     ' Номер бита порта шины 1-Wire эмулятора
Const Ipin = 0                                        ' значение DDRx, режим "вход"
Const Opin = 1                                      ' значение DDRx, режим "выход"
PORTC.dqpin = 0

Config PORTC.0 = Output                  'Конфигурирование вывода-эмулятора RSTZ/STRB
PORTC.0 = 1
Config PORTB = Output                     'Конфигурирование порта-эмулятора ВЫХОД
Config PORTD = Input                        'Конфигурирование порта-эмулятора ВХОД
PORTB = 255

Config Timer0 = Timer , Prescale = 64 , Compare A = Disconnect
Timer Alias TCNT0
On Timer0 Isr Nosave

'======================================================
' Временные задержки
Const Owpresent = 120                      ' 60us < OWPresent < 240us                                      150
Const Owpause = 40                          ' 15us < OWPause   < 60us
Const Owstrobe = 10                          ' read Dq value after Owstrobe, us                              15
Const Owdata = 25                             ' valid output data for Owdata, us                                 25
Const T1reset = 50                             ' T1us * 490 Min Reset width                                        60
Const Timeout = 170                          ' T1us * 970 Max Reset width                                       120

' Используемые переменные
Dim A As Byte                                     ' Служебная
Dim B As Byte                                     ' Служебная
'Dim C As Byte                                     ' Служебная
Dim Stek As Byte                                ' Указатель стека
Dim Bytedat As Byte                           ' Для передачи / приема ID
Dim Bitdat As Byte                              ' 0 - Для передачи / приема ID
                                                             ' 1 - флаг указателя сохранения стека
Dim pio As Byte                                  ' Значение PIO
Dim invpio As Byte                             ' Инвертированное значение PIO
Dim Myrom(8) As Byte                       ' ID эмулятора

'======================================================
Restore MyID                                     ' Считывание собственного ID
For B = 1 To 8
      Read Bytedat
      Myrom(B) = Bytedat
Next B

Waitms 50

Enable Interrupts
Enable Timer0
Stop Timer0
'======================================================
'                                         Главный цикл
Mainloop:
'======================================================
Waitreset:
Disable Interrupts
Timer = 0

Waitfall:
L1:
    sbis pinC, dqpin
    rjmp L1
L2:
    sbic pinC, dqpin
    rjmp L2

Start Timer0

Rwaitrise:
L01:
    sbic pinC, dqpin
    rjmp L01
L02:
    sbis pinC, dqpin
    rjmp L02

Stop Timer0

If Timer < T1reset Then Goto Waitreset
If Timer > Timeout Then Goto Waitreset

Sendpresense:
Waitus Owpause

DDRC.dqpin = Opin

Waitus Owpresent
DDRC.dqpin = Ipin

Start Timer0
Timer = 0
Enable Interrupts

Readb:
Gosub Readbyte

Readb1:
If Bytedat = &H33 Then Goto Readrom      ' работает
If Bytedat = &HF0 Then Goto Sendrom      ' работает
If Bytedat = &HCC Then Goto Funct          '
If Bytedat = &H55 Then Goto Matchrom     '

Goto Readb

End

'======================================================
Isr:

If PINC.dqpin = 0 Then
Timer = T1reset
      LDI ZL , low(Rwaitrise)                   ' Забираем адрес метки
      LDI ZH , high(Rwaitrise)                ' Забираем адрес метки
      SEI                                                 ' Так как мы в прерывании и не выходим по RETI (Return),
''                                                               разрешаем прерывания
      IJMP                                                ' Переход на метку без последствий для стека
Else
      LDI ZL , low(Waitreset)
      LDI ZH , high(Waitreset)
'      SEI
IJMP
End If

Return
'======================================================
Readrom:
For B = 1 To 8
      Bytedat = Myrom(B)
      Gosub Sendbyte
Next B
Goto Readb

'======================================================
Matchrom:
For B = 1 To 8
      Gosub Readbyte
      If Bytedat <> Myrom(B) Then Goto Mainloop
Next B
'----------------------------------
Funct:
Gosub Readbyte

If Bytedat = &HF5 Then Gosub Read_PIO
If Bytedat = &H5A Then Gosub Write_PIO

Goto Readb1

'======================================================
' Передача состояния PIO мастеру (команда Channel Access Read)
Read_PIO:

Waitus 3
Bytedat = PIND                                      ' Чтение состояния порта-эмулятора PIO
Gosub Sendbyte                                   ' Отправка считанного состояния PIO мастеру

Return

'======================================================
' Прием состояния PIO от мастера (команда Channel Access Write)
Write_PIO:

Gosub Readbyte                                   ' Принимаем байт нового состояния
pio = Bytedat
Gosub Readbyte                                   ' Принимаем инвертированный байт состояния
invpio = Bytedat

invpio = Not invpio

Bytedat = &HAA                                     ' Отправляем мастеру
Gosub Sendbyte                                   ' подтверждение приема

If pio = invpio Then                               ' Если прием правильный, то:
      PORTB = pio                                   ' - передаем в порт новое значение PIO
      PORTC.0 = 0                                  ' - выставляем сигнал STRB
End If

Bytedat = pio                                         ' Отправляем мастеру
Gosub Sendbyte                                  ' значение принятого состояния PIO

Waitus Owstrobe
PORTC.0 = 1                                        ' Убираем сигнал STRB

Return

'======================================================
' Прием байта от мастера
Readbyte:
For A = 0 To 7

L11:
    sbis pinC, dqpin
    rjmp L11
L12:
    sbic pinC, dqpin
    rjmp L12
         Timer = 256 - T1reset
         Start Timer0

         Rotate Bytedat , Right
         Waitus Owstrobe

         Bytedat.7 = PINC.dqpin

Next A
Stop Timer0
Return

'======================================================
' Передача байта мастеру
Sendbyte:
For A = 0 To 7

L21:
    sbis pinC, dqpin
    rjmp L21
L22:
    sbic pinC, dqpin
    rjmp L22
Timer = 256 - T1reset
Start Timer0

If Bytedat.0 = 0 Then DDRC.dqpin = Opin
Waitus Owdata
DDRC.dqpin = Ipin

Rotate Bytedat , Right

Next A
Stop Timer0
Return

'======================================================
Sendrom:
For A = 1 To 8
      Bytedat = Myrom(A)
For B = 0 To 7
'----------------------------
Sendcbit1:

L31:
    sbis pinC, dqpin
    rjmp L31
L32:
    sbic pinC, dqpin
    rjmp L32

           If Bytedat.0 = 0 Then DDRC.dqpin = Opin
           Waitus Owdata
           DDRC.dqpin = Ipin
'----------------------------
Sendcbit2:

L41:
    sbis pinC, dqpin
    rjmp L41
L42:
    sbic pinC, dqpin
    rjmp L42

           If Bytedat.0 = 1 Then DDRC.dqpin = Opin
           Waitus Owdata
           DDRC.dqpin = Ipin
'--------------------------
Readcbit:

L51:
    sbis pinC, dqpin
    rjmp L51
L52:
    sbic pinC, dqpin
    rjmp L52

Waitus Owstrobe

Bitdat.0 = PINC.dqpin
If Bitdat.0 <> Bytedat.0 Then Goto Mainloop
Rotate Bytedat , Right
Next B
Next A

Goto Readb

'======================================================

MyID:
Data &HF0 , &H24 , &H08 , &H01 , &H00 , &H00 , &H00 , &H9F

Отредактировано Nord (2018-12-04 19:48:28)

0

4

Апну тему...

Где-то с 20 декабря начал проверку прошивки эмулятора в железе на макетке.
В том виде, как она живет в Протеусе - не пошла от слова никак... ;)
Лишнее доказательство, что нельзя полностью доверять Протеусу... ;)

Потом были другие срочные дела и НГ... ;)

5-го января занялся (по мере возможности) снова.
Кастрировал прошивку и, постепенно добавляя и исправляя, пока что добился 100% устойчивого отклика на Reset мастера.

В качестве мастера используется Mega16 с дисплеем 2004 для визуализации результатов.
Для наглядности процесса на этой же шине 1-Wire подключен DS18B20.

0

5

Nord написал(а):

On Timer0 Isr Nosave

В обработчике прерывания регистры не сохраняются. Работает без ошибок?
Может лучше принимать данные по захвату таймера? Или попробовать настроить USART и его использовать для приема и передачи 1-Wire.

0

6

Пётр написал(а):

On Timer0 Isr Nosave
В обработчике прерывания регистры не сохраняются.
Работает без ошибок?

В Протеусе работало... ;)
От Nosave уже ушел.
Прерывание тоже обрабатывается по-другому.

Пётр написал(а):

Может лучше принимать данные по захвату таймера?

Пока таймер задействуется только для подсчета временных интервалов.

Пётр написал(а):

Или попробовать настроить USART и его использовать для приема и передачи 1-Wire.

Видел такие способы реализации.
Пока не пробовал, хочется в этом варианте чего-то большего добиться... ;)

0

7

Отпишусь про достигнутое... ;)

Пока удалось добиться устойчивой работы эмулятора "в железе" только с несколькими операциями.
От использования таймеров отказался, сподвигло к этому решению вычитанное на сайте (перевод Гугла):
https://www.mcselec.com/index2.php?opti … wire+slave
"Да, поскольку 1wire не использует системные ресурсы, такие как таймер, это означает, что синхронизация создается программным циклом."
https://www.mcselec.com/index2.php?opti … wire+slave
"Чтобы ответить на вопрос: 1wire не использует таймер."

Вся работа строится на проверках уровня ("0" или "1") и задержках.
Ряд операций (более половины) выполнены на ассемблерных вставках, т.к. скорости Bascom не хватает...
По этой же причине пришлось отказаться от циклов For...Next, особенно вложенных - тормоза неимоверные... ;)
В двух местах пришлось даже отказаться от Gosub...Return...

Связь между мастером и эмулятором - по неэкранированному кабелю UTP около 20м, проложенному кольцом по периметру комнаты. Подтяжка - 4,7кОм.
Используемые команды взяты из протокола DS2408, впоследствии заменю на уникальные, не используемые имеющимися м/с DS.
Работают:
1 - импульс присутствия (самое простое ;) )
2 - &H33 - считывание ID эмулятора
3 - &HF5 - чтение состояния порта ввода эмулятора
4 - &H5A - запись данных в порт выхода эмулятора

При наличии на шине других м/с 1-Wire эмулятор однозначно откликается на команды "3" и "4", а вот на "2" отвечают только "заводские" экземпляры... ;)

Собственно, в имеющемся виде эмулятор вполне работоспособен, но при условии, что на шине не будет устройств, реагирующих на команды "3" и "4".
Могут "запутаться", проверялось с DS2413... ;)

0

8

Готовый вариант эмулятора 1-Wire Slave устройства на базе ATMega48P (DIP-28).
Работает как в "железе" (описано выше), так и в Протеусе.
Расход памяти - 23%...

Некий "аналог" DS2408... ;)
В качестве бонуса - раздельные порты ввода-вывода.
В случае отсутствия необходимости двунаправленного обмена легко портируется на ATTiny2313 с Int.RC 8МГц без значительных изменений в программе (только переназначение портов).

Задействованые команды:
1 - Read ROM &H33
2 - Channel Access Read &HF5
3 - Channel Access Write &H5A

Как и было упомянуто ранее, при наличии на шине "заводских" устройств 1-Wire, будет выполнять только команды "2" и "3"... ;)
По этой причине обработка команды "1" выглядит неким излишеством... ;)
В моем случае ;) этого более чем достаточно, т.к. создавалось и будет работать в описанном здесь  Часовой интерфейс проекте на отдельной шине 1-Wire.

Код эмулятора (Slave):

Код:
$Regfile="m48pdef.dat"
$Crystal=8000000
$hwstack=16
$swstack=16
$framesize=16

'==========================================
' Формируем шину 1-Wire
Const dqpin = 3                      ' Номер бита порта шины 1-Wire эмулятора
DDR1W Alias DDRC.dqpin        ' Переключатель вход (0) - выход (1)
PIN1W Alias PINC.dqpin
DDR1W = 0
PORTC.dqpin = 0

'==========================================
' Конфигурирование портов ввода-вывода
Config PORTC.4 = Output       'Конфигурирование вывода RSTZ/STRB эмулятора
PORTC.4 = 1
Config PORTB = Output           'Конфигурирование порта-выхода эмулятора PIO
PORTB = 255
Config PORTD = Input              'Конфигурирование порта-входа эмулятора PIO

'==========================================
' Константы для отсчета длительностей ( us )
Const nochip = 320            ' Сбой на шине
Const tres = 170                ' Длительность tRSTL
Const presence = 130       ' Длительность импульса присутствия

Dim cnt0 As Word : cnt0 = 0          ' Счетчик циклов "0"
Dim priem As Byte : priem = 0
Dim a As Byte
Dim b As Byte
Dim Myrom(8) As Byte                  ' ID эмулятора

'==========================================
' Считывание собственного ID
Restore MyID
For a = 1 To 8
      Read b
      Myrom(a) = b
Next a

'==========================================
'******************************************************
Do
main:

' Ожидание "0" на шине
m20:
!SBIC PINC, dqpin
!RJMP m20

' Ожидание "1" на шине
cnt0 = 0
m21:
Incr cnt0
!SBIS PINC, dqpin
!RJMP m21

' Определяем принятый сигнал
If cnt0 > nochip Then Goto main                          ' Превышение длительности "0" на линии
If cnt0 > tres Then Gosub привет                        ' Есть Reset от мастера

If priem = &H33 Then Gosub send_ID                 ' Обработка Read ROM &H33
If priem = &HF5 Then Gosub send_PIO              ' Обработка Channel Access Read &HF5
If priem = &H5A Then Gosub rec_PIO                 ' Обработка Channel Access Write &H5A

Loop
End

'******************************************************
'==========================================
' Формирование импульса присутствия
привет:

Waitus trec
DDR1W = 1                        ' Выставляем уровень "0" сигнала присутствия (пин "на выход")
Waitus presence
DDR1W = 0                        ' Убираем сигнал присутствия (пин "на вход")

' Принимаем байт команды
a = 0
priv20:
!SBIS PINC, dqpin
!RJMP priv20
priv21:
!SBIC PINC, dqpin
!RJMP priv21
cnt0 = 0
priv22:
Incr cnt0
!SBIS PINC, dqpin
!RJMP priv22
If cnt0 < 20 Then
      priem.a = 1
   Else
      priem.a = 0
End If
Incr a
If a < 8 Then Goto priv21

Return

'==========================================
' Отправка ID номера команда &H33
send_ID:

a = 1
передача_байта:
priem = Myrom(a)

b = 0
передача_бита:

id21:
!SBIS PINC, dqpin
!RJMP id21
id22:
!SBIC PINC, dqpin
!RJMP id22
If priem.b = 0 Then
      DDR1W = 1
      Waitus 30
End If
DDR1W = 0

Incr b
If b < 8 Then Goto передача_бита

Incr a
If a < 9 Then Goto передача_байта

Waitus 2
Return

'==========================================
' Отправка состояния порта ввода команда &HF5
send_PIO:

a = 0
priem = PIND

rp21:
!SBIS PINC, dqpin
!RJMP rp21
rp22:
!SBIC PINC, dqpin
!RJMP rp22
If priem.a = 0 Then
      DDR1W = 1
      Waitus 30
End If
DDR1W = 0

Incr a
If a < 8 Then Goto rp21

Return

'==========================================
' Прием байта состояния PIO команда &H5A
rec_PIO:

a = 0

pr21:
!SBIC PINC, dqpin
!RJMP pr21
cnt0 = 0
pr22:
Incr cnt0
!SBIS PINC, dqpin
!RJMP pr22
If cnt0 < 20 Then
      priem.a = 1
   Else
      priem.a = 0
End If

Incr a
If a < 8 Then Goto pr21

PORTB = priem
PORTC.4 = 0
Waitus 2
PORTC.4 = 1

Return

'==========================================
MyID:
Data &H3F , &H24 , &H08 , &H01 , &H00 , &H00 , &H00 , &H85
'Data &H3F , &H24 , &H08 , &H02 , &H00 , &H00 , &H00 , &HC2
'Data &H3F , &H24 , &H08 , &H03 , &H00 , &H00 , &H00 , &HFF
'Data &H3F , &H24 , &H08 , &H04 , &H00 , &H00 , &H00 , &H4C
'Data &H3F , &H24 , &H08 , &H05 , &H00 , &H00 , &H00 , &H71
'Data &H3F , &H24 , &H08 , &H06 , &H00 , &H00 , &H00 , &H36
'Data &H3F , &H24 , &H08 , &H07 , &H00 , &H00 , &H00 , &H0B
'Data &H3F , &H24 , &H08 , &H08 , &H00 , &H00 , &H00 , &H49
'Data &H3F , &H24 , &H08 , &H09 , &H00 , &H00 , &H00 , &H74
'Data &H3F , &H24 , &H08 , &H10 , &H00 , &H00 , &H00 , &HFB

Код Master, используемый при проверке:

Код:
Do

1wreset PINC, 0
1wwrite &H33, 1, PINC, 0
id(1) = 1wread(8, PINC, 0)
For a = 1 To 8
      Print Hex(id(a));
Next a
Print
Wait 1

1wreset PINC, 0
1wwrite &HF5, 1, PINC, 0
a = 1wread(1, PINC, 0)
Print a
Wait 1

1wreset PINC, 0
1wwrite &H5A, 1, PINC, 0
1wwrite 170, 1, PINC, 0
Print "170"
Wait 1

1wreset PINC, 0
1wwrite &H5A, 1, PINC, 0
1wwrite 85, 1, PINC, 0
Print " 85"
Wait 1

Loop

Отредактировано Nord (2019-01-24 21:16:16)

+2

9

Маленький видеоотчет о результатах...

На одном из модулей вторичных часов DS2408 была заменена на эмулятор на базе ATTiny2313.
Использована только одна команда - &H5A.
На фото этот МК слева сверху.
http://sd.uploads.ru/t/tbcC9.jpg

Мастером выступает ATMega32 на макетке, сигнал гоняет по кабелю, как было описано ранее.
С промежутком в несколько секунд отсылает "что-то типа времени"... ;)
Питание данного модуля самостоятельное (видны "крокодилы"), сигнальная связь только по двум линиям - DO и GND.
https://yadi.sk/i/YuoW5DHjgS4qNg

0

10

Апну немного... ;)

На работу с эмулятором переведены модули, показаные тут Часовой интерфейс

Вразрез с топологией 1-Wire имеющиеся (собраные) 4 модуля вторичных часов прекрасно работают на одной линии 1-Wire, проложенной по схеме "звезда".
В центре - Мастер, 4 луча - кабель UTP разной длины, от 4 до 20 метров.
Подтяжка только на Мастере.

В 15:00 "тикнет" уже сутки, как идет передача.
Сбоев не замечено.

Отредактировано Nord (2019-02-07 14:22:15)

+1

11

Продолжение испытаний... ;)

К упомянутой ранее "звезде" добавлен пятый луч около 6 метров UTP, на котором "трудится" ATTiny2313, играющий роль считывателя "сухих контактов".
Фактически он циклически отдает по команде Мастера &HF5 (Channel Access Read) несколько фиксированных значений.

Заканчиваются вторые сутки... ;)
Ошибок нет (Мастер проверяет правильность последовательности).

Обработки команд, связанных с ID номером исключил полностью, оставлены только Channel Access Read &HF5 и Channel Access Write &H5A.
Каких-либо "накладок" и "ругани" между эмуляторами не замечено... ;)

Отредактировано Nord (2019-02-15 06:42:05)

0

12

КрасаУчег!!!     :flag:

+1

13

Немного доработал функциональность эмулятора адресуемого параллельного расширителя шины 1-Wire.

Забил на оригинальный протокол работы с ID-номером устройства по причине непреодолённого конфликта с заводскими устройствами 1-Wire, если они присутствуют на шине совместно с эмулятором.
Считаю это несущественным, т.к. выделить одну ножку МК не проблема... ;)

Проверка в железе проводилась в условиях, описанных ранее (линии, топология).

Симуляция в Протеус - https://yadi.sk/d/FO9bXYV3SAVH1w
http://sg.uploads.ru/t/BHg70.png

Выполняемые команды:
&HC5 - команда-аналог Skip ROM &HCC
&HCA - команда-аналог Match ROM &H55
&HF5 - команда Channel Access Read &HF5
&H5A - команда Channel Access Write &H5A

Особенности:
- однобайтовый ID-номер, задается при прошивке
- раздельные порты ввода/вывода
- возможность работать на шине с топологией «звезда» с лучами до 20м (проверялось в «железе»), причем расположение «мастера» на шине не регламентируется
- желательно не использовать на одной шине с эмулятором заводские устройства 1-Wire
- ID эмулятора не должен быть &HF5 или &H5A

Код слейва:
В этой строке указывается ID конкретного слейва-эмулятора.

Const myrom = &HDA                    ' ID эмулятора (вписывается вручную)

Код:
$Regfile="m48pdef.dat"
$Crystal=8000000
$hwstack=16
$swstack=16
$framesize=16

'==========================================
' Формируем шину 1-Wire
Const dqpin = 3               ' Номер бита порта шины 1-Wire эмулятора
DDR1W Alias DDRC.dqpin        ' Переключатель вход (0) - выход (1)
PIN1W Alias PINC.dqpin
DDR1W = 0
PORTC.dqpin = 0

'==========================================
' Конфигурирование портов ввода-вывода
Config PORTC.4 = Output        'Конфигурирование вывода STRB эмулятора
PORTC.4 = 1
Config PORTB = Output          'Конфигурирование порта-выхода эмулятора
PORTB = 255
Config PORTD = Input           'Конфигурирование порта-входа эмулятора

'==========================================
' Константы для отсчета длительностей
Const nochip = 320                        ' Сбой на шине
Const tres = 170                            ' Длительность tRSTL
Const presence = 130                    ' Длительность импульса присутствия

‘ Используемые константы и переменные
Const myrom = &HDA                    ' ID эмулятора (вписывается вручную)
‘                                             DA, DB, DC, DD, DE, DF
Dim cnt0 As Word : cnt0 = 0          ' Счетчик циклов "0"
Dim priem As Byte : priem = 0
Dim flag As Byte : flag = 0             ‘ 0 – общее/адресное обращение к данному чипу
Dim a As Byte
Dim b As Byte

'==========================================
'******************************************************
Do
main:

' Ожидание "0" на шине
m20:
!SBIC PINC, dqpin
!RJMP m20

' Ожидание "1" на шине
cnt0 = 0
m21:
Incr cnt0
!SBIS PINC, dqpin
!RJMP m21

' Определяем принятый сигнал
If cnt0 > nochip Then Goto main                          ' Превышение длительности "0" на линии
If cnt0 > tres Then Gosub привет                        ' Есть Reset от мастера

If priem = &HC5 Then flag.0 = 1                          ' Команда-аналог Skip ROM &HCC
If priem = &HCA Then Gosub read_ID                ' Команда-аналог Match ROM &H55
If flag.0 = 0 Then Goto m22
If priem = &HF5 Then Gosub send_PIO              ' Обработка Channel Access Read &HF5
If priem = &H5A Then Gosub rec_PIO                 ' Обработка Channel Access Write &H5A

m22:
Loop
End

'******************************************************
'==========================================
' Формирование импульса присутствия
привет:

Waitus trec
DDR1W = 1                        ' Выставляем уровень "0" сигнала присутствия (пин "на выход")
Waitus presence
DDR1W = 0                        ' Убираем сигнал присутствия (пин "на вход")

' Принимаем байт команды
a = 0
priv20:
!SBIS PINC, dqpin
!RJMP priv20
priv21:
!SBIC PINC, dqpin
!RJMP priv21
cnt0 = 0
priv22:
Incr cnt0
!SBIS PINC, dqpin
!RJMP priv22
If cnt0 < 20 Then
      priem.a = 1
   Else
      priem.a = 0
End If
Incr a
If a < 8 Then Goto priv21

Return

'==========================================
' Прием байта для проверки ID (команда &HCA)
read_ID:

a = 0

pi21:
!SBIC PINC, dqpin
!RJMP pi21
cnt0 = 0
pi22:
Incr cnt0
!SBIS PINC, dqpin
!RJMP pi22
If cnt0 < 20 Then
      priem.a = 1
   Else
      priem.a = 0
End If

Incr a
If a < 8 Then Goto pi21

If priem = myrom Then flag.0 = 1

Return

'==========================================
' Отправка байта состояния порта ввода (команда &HF5)
send_PIO:

a = 0
priem = PIND

rp21:
!SBIS PINC, dqpin
!RJMP rp21
rp22:
!SBIC PINC, dqpin
!RJMP rp22
If priem.a = 0 Then
      DDR1W = 1
      Waitus 30
End If
DDR1W = 0

Incr a
If a < 8 Then Goto rp21

flag.0 = 0
Return

'==========================================
' Прием байта состояния порта вывода (команда &H5A)
rec_PIO:

a = 0

pr21:
!SBIC PINC, dqpin
!RJMP pr21
cnt0 = 0
pr22:
Incr cnt0
!SBIS PINC, dqpin
!RJMP pr22
If cnt0 < 20 Then
      priem.a = 1
   Else
      priem.a = 0
End If

Incr a
If a < 8 Then Goto pr21

PORTB = priem
PORTC.4 = 0
Waitus 2
PORTC.4 = 1

flag.0 = 0
Return

'==========================================


Код Мастера:

Код:
Do

1wreset PINC, 3
1wwrite &HC5, 1, PINC, 3
1wreset PINC, 3
1wwrite &H5A, 1, PINC, 3
1wwrite 170, 1, PINC, 3
Wait 1

1wreset PINC, 3
1wwrite &HCA, 1, PINC, 3
1wwrite &HDA, 1, PINC, 3
1wreset PINC, 3
1wwrite &H5A, 1, PINC, 3
1wwrite 85, 1, PINC, 3
Wait 1

1wreset PINC, 3
1wwrite &HCA, 1, PINC, 3
1wwrite &HDC, 1, PINC, 3
1wreset PINC, 3
1wwrite &H5A, 1, PINC, 3
1wwrite 85, 1, PINC, 3
Wait 1

1wreset PINC, 3
1wwrite &HCA, 1, PINC, 3
1wwrite &HDE, 1, PINC, 3
1wreset PINC, 3
1wwrite &HF5, 1, PINC, 3
a = 1wread(1, PINC, 3)
PORTB = a
Wait 1

Loop

Отредактировано Nord (2019-03-10 22:36:23)

+1


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Эмуляция 1-Wire устройства