Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогиття побороть ibutton plz...
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Vlad219i
Не первый день бьюсь с 1-wire. Все делаю по 126 аппноту от Далласа и даташиту на DS1990A, iButton на ресет откликается, но при попытке прочитать с него сигнатуру - упорно в ответе вылезает ff,7f,7f,7f,7f,7f,7f,7f. DS1990A - живые (пробовал разные), задержки - в норме (раздвигаю-сдвигаю время - девайс перестает откликаться), прерывания на время опроса и tx/rx - отключаю.
Возможности подключить осциллограф прямщас нет, гляньте в код plz - может проглядел что-то...
Опрос:
Код
;###### опрос 1-wire (времянка)
        cli            ;запрещаем прерывания
        rcall    owreset;ibutton обнаружен ?
        brts    ow_no;нет - обход
        rcall    ibutton;принимаем сигнатуру
        sei
        mlcdadr    $40
        ldi        tmp2, 8
        ldi        yh, high(ibuffer*2)
        ldi        yl, low(ibuffer*2)
ib000:    ld        tmp, y+
        rcall    lcdhex2
        dec        tmp2
        brne    ib000
        ldi        cntbeep, 50
        rcall    wait1s
        mprintf    $40, "                "
ow_no:    sei
ow_out:


Подпрограммки:

Код
;проверка на наличие девайса 1-wire
;выход:    T=1 - девайс не обнаружен
;        T=0 - девайс обнаружен
owreset:clt            ;изначально ставим признак "1wire девайс обнаружен"
        sbi        ddrd, owport;1wire на вывод
        cbi        portd, owport;приземляем линию
        rcall    owait_h
        sbi        portd, owport;отпускаем линию
        cbi        ddrd, owport;1wire на ввод
        rcall    owait_i    ;ждем 70 мкс
        sbic     pind, owport;девайс приземлил линию ?
        set            ;нет - девайс не обнаружен
        rcall    owait_j
        ret

;прием серийника iButton
;выход:    [ibbuffer] - 8 байт от ibutton
ibutton:ldi        yh, high(ibuffer*2)
        ldi        yl, low(ibuffer*2)
        ldi        tmpl, 8        ;принимаем 8 байт
        ldi        tmp, $33
        mov        owdata, tmp
        rcall    owtxb
ibut00:    rcall    owrxb
        st        y+, owdata
        dec        tmpl
        brne    ibut00
        ret

;передача байта по onewire
;вход:    [owdata] - байт
owtxb:
        sbi        ddrd, owport;1wire на вывод
        ldi        tmp2, 8        ;счетчик бит
owtxb0:    sbrc    owdata, 0
        rjmp    owt_1
;передаем "0"
owt_0:    cbi        portd, owport;приземляем линию
        rcall    owait_c
        sbi        portd, owport;отпускаем линию
        rcall    owait_d
        rjmp    owtnext
;передаем "1"
owt_1:    cbi        portd, owport;приземляем линию
        rcall    owait_a
        sbi        portd, owport;отпускаем линию
        rcall    owait_b
owtnext:ror        owdata
        dec        tmp2
        brne    owtxb0
        cbi        ddrd, owport;1wire на ввод
        ret

;прием байта по onewire
;выход:    [owdata] - байт
owrxb:
        clr        owdata
        ldi        tmp2, 8        ;счетчик бит
        sbi        ddrd, owport;1wire на вывод
owrxb0:    cbi        portd, owport;приземляем линию
        rcall    owait_a
        sbi        portd, owport;отпускаем линию
        cbi        ddrd, owport;1wire на ввод
        rcall    owait_e
        sec                    ;ставим C
        sbis     pind, owport;на линии 1 ?
        clc                    ;нет - сбрасываем C
        rol        owdata        ;пишем C в бит 0[owdata]
        rcall    owait_f
        dec        tmp2
        brne    owrxb0
        ret


Что я делаю не так, а ?.. :(

PS: DS1821 ведет себя ровно так же - в ответ на $AA отдает байт $7F.
Во избежание недоразумений - порт изначально настроен на ввод, все на макетке, схемка подключения вот:
Yura_K
Вроде никакого "криминала" не видно, если только "времянка" выдержана правильно (осциллограф бы не помешал). Непонятно только зачем:
Код
ibutton:ldi        yh, high(ibuffer*2)
        ldi        yl, low(ibuffer*2)

Если работаем с ОЗУ, то надо:
Код
ibutton:ldi        yh, high(ibuffer)
        ldi        yl, low(ibuffer)

Приведенной схемы подключения не видно, попробуйте прикрепить еще раз.
При считывании бита можно попробовать защиту от дребезга.
aahardsoft
сдается мне что пишете вы ответ от ключей в озу а смотрите с flash,так что давайте макросы ваши в студию.
Vlad219i
Цитата(aahardsoft @ Dec 28 2006, 20:45) *
сдается мне что пишете вы ответ от ключей в озу а смотрите с flash,так что давайте макросы ваши в студию.


Собственно, там макросы относятся только к LCD-модулю и нареканий с моей стороны не вызывают, эта часть отработана давно и не в одном проекте. :-)
mlcdadr - установка адреса отображения, mprintf - печать строки из program memory по заданному адресу LCD. Из внешних процедур здесь мелькает только printhex2 - печать 16-ричного числа на LCD. Вообще - печать здесь только для отладки.
aahardsoft
ну а че тада вы пишете в озу а печатаете с flash чтоль?smile.gif
Vlad219i
Цитата(aahardsoft @ Dec 28 2006, 23:07) *
ну а че тада вы пишете в озу а печатаете с flash чтоль?smile.gif


Нифига не понял.
OK, давайте так.
Какое конкретно место в листинге Вас смущает ?


Цитата(Yura_K @ Dec 28 2006, 19:54) *
Если работаем с ОЗУ, то надо:
Код
ibutton:ldi        yh, high(ibuffer)
        ldi        yl, low(ibuffer)


Да, это мой глюк, спасибо за наводку. :-)
Однако - даже при этом и для записи, и для чтения использовались одни и те же адреса в sram... Вживую завтра на работе посмотрю.

Цитата(Yura_K @ Dec 28 2006, 19:54) *
Приведенной схемы подключения не видно, попробуйте прикрепить еще раз.
При считывании бита можно попробовать защиту от дребезга.


Сервак лежал, сейчас вроде видно.

Дребезг - да не похоже. 100%-повторяющийся результат...
aahardsoft
"mprintf - печать строки из program memory по заданному адресу LCD." я так понимаю что проверяете вы что с таблетки прочлось выводя на lcd .... но буффер под таблетку у вас в озу а процедура печатает с флеша,или я чтото не так понял?
Vlad219i
Цитата(aahardsoft @ Dec 29 2006, 10:57) *
"mprintf - печать строки из program memory по заданному адресу LCD." я так понимаю что проверяете вы что с таблетки прочлось выводя на lcd .... но буффер под таблетку у вас в озу а процедура печатает с флеша,или я чтото не так понял?


Угу, не так. Если посмотреть пристально на
Код
mprintf    $40, "                "

то станет очевидным, что в этом месте с адреса $40 печатается 16 пробелов, то есть это просто очистка строки #2 на LCD. :-)

Для печати данных из буфера используется "printhex2" - это печать байта из [tmp] в удобочитаемом виде на LCD с текущего знакоместа.

Адреса буфера поменял. Как и ожидалось - не помогло. Итого: осциллограф - наше все, но это уже после праздников, наверное. :-)

Всех с наступающим !
vesago
Если у вас времянки правильные и данные не криво сохраняются, не забывайте, что между битами надо небольшую паузу держать мкс так на 20.
Vlad219i
Цитата(vesago @ Dec 29 2006, 11:27) *
Если у вас времянки правильные и данные не криво сохраняются, не забывайте, что между битами надо небольшую паузу держать мкс так на 20.


Что-то в описании протокола я такого не нашел... Таймслоты (теоретически smile.gif ) отработаны правильно.
Впрочем - после введения задержек 20 мкс ниччего не изменилось... :-(
vesago
Я так делаю - просаживаю линию, на второй мкс вывожу бит на линию, на 13 мкс считываю, жду 60 мкс, подымаю линию, жду 20 мкс. После ресета передается команда 33h, потом считываются 8 байт.
add
Пока криминального ничего ненашел. Только Вы както жестковто с линиеей работаете:
Цитата
sbi portd, owport;отпускаем линию
cbi ddrd, owport;1wire на ввод

Мелочь конечно, но все же лучше наоборот:
cbi ddrd.....
sbi portd.....
И хорошо бы еще ваши delay посотреть. Сам собирал, и работал с 1wire(ibutton и термодатчики), писал на асме, таких проблем небыло.
Vlad219i
Цитата(add @ Dec 29 2006, 12:27) *
Пока криминального ничего ненашел. Только Вы както жестковто с линиеей работаете:
Цитата
sbi portd, owport;отпускаем линию
cbi ddrd, owport;1wire на ввод

Мелочь канечно, но все же лучше наоборот:
cbi ddrd.....
sbi portd.....

Тогда получится, что мы начинаем слушать порт, после чего включаем подтяжку. И при следующей перестройке порта на вывод мы сразу будем иметь на выходе "0". Нет ?
Цитата(add @ Dec 29 2006, 12:27) *
И хорошо бы еще ваши delay посотреть. Сам собирал, и работал с 1wire(ibutton и термодатчики), писал на асме, таких проблем небыло.


"На асме" - сейчас это встречается все реже, к сожалению... :-)
Задержки:

Код
;микросекундные задержки для 1wire - изменять код при изменении Tclk !!!
;//Tclk 7.3728MHz, 1такт - ~135нс
owait_a:ldi    tmp, 6        ;6 мкс
        rjmp    ow0
owait_b:ldi    tmp, 64        ;64 мкс
        rjmp    ow0
owait_c:ldi    tmp, 60        ;60 мкс
        rjmp    ow0
owait_d:ldi    tmp, 10        ;10 мкс
        rjmp    ow0
owait_e:ldi    tmp, 9        ;9 мкс
        rjmp    ow0
owait_f:ldi    tmp, 55        ;55 мкс
        rjmp    ow0
owait_h:ldi        tmp, 240;480 мкс
        rcall    ow0
        ldi        tmp, 240
        rjmp    ow0
owait_i:ldi        tmp, 70    ;70 мкс
        rjmp    ow0
owait_j:ldi        tmp, 200;410 мкс
        rcall    ow0
        ldi        tmp, 210
ow0:    rjmp    pc+1    ;2 такта    \~1мкс
        rjmp    pc+1    ;2 такта
        dec        tmp        ;1 такт
        brne    ow0        ;2 такта    /
        ret
add
Нашел помойму ошибку..:
Цитата
sbi ddrd, owport;1wire на вывод
owrxb0: cbi portd, owport;приземляем линию
rcall owait_a
sbi portd, owport;отпускаем линию
cbi ddrd, owport;1wire на ввод

Порт ddrb обнуляете но потом неустанавливаете перед синхро уровнем :-) так нет? (отсюда 7f)
зы: всеж таки обмен стоит делать пасивным.
1 = portd в 1, ddrd в 0
0 = portd в 0, ddrd в 1
Цитата
Тогда получится, что мы начинаем слушать порт, после чего включаем подтяжку. И при следующей перестройке порта на вывод мы сразу будем иметь на выходе "0". Нет ?

"Слушать" порт начинаем здесь:
Цитата
sbis pind, owport;на линии 1 ?

Удачи! :-)
Vlad219i
Цитата(add @ Dec 29 2006, 13:59) *
Нашел помойму ошибку..:
Цитата
sbi ddrd, owport;1wire на вывод
owrxb0: cbi portd, owport;приземляем линию
rcall owait_a
sbi portd, owport;отпускаем линию
cbi ddrd, owport;1wire на ввод

Порт ddrb обнуляете но потом неустанавливаете перед синхро уровнем :-) так нет? (отсюда 7f)

Как не устанавливаю, вот же:
sbi portd, owport;отпускаем линию
Цитата(add @ Dec 29 2006, 13:59) *
зы: всеж таки обмен стоит делать пасивным.
1 = portd в 1, ddrd в 0
0 = portd в 0, ddrd в 1

А вот это (а именно пассивный обмен) помогло.
Первым делом в ресете 1-wire настраиваю порт на вывод, обнуляю и оставляю в таком виде навсегда.
Дальше достаточно играть только направлением, ибо при настройке порта на ввод он отпускает линию.
Спасибо, заработало ! :-)

Попутно выяснилось, что девайс отдает байты от старшего бита к младшему (а вроде должен наоборот).
Шаманство какое-то...
Цитата(add @ Dec 29 2006, 13:59) *
"Слушать" порт начинаем здесь:
Цитата
sbis pind, owport;на линии 1 ?

Удачи! :-)

Не, я не об этом. Неточно выразился. "Слушать"=имелось в виду "настраивать на ввод".
Если настроить пин с помощью ddrd на ввод, а потом в portd на этот пин выдать 1 - включится подтяжка для этого пина, состояние же регистра порта не изменится.

PS: если интересно, могу выложить уже рабочий исходник.
add
Цитата
Как не устанавливаю, вот же:
sbi portd, owport;отпускаем линию

Я говорю про ddrd!!! сначало на вывод, а в цикле устанавливаешь на вход и он в третьем состоянии.

Цитата
sbi ddrd, owport;1wire на вывод.;<<<<<<<<<<ВОТ ЗДЕСЬ

owrxb0: cbi portd, owport;приземляем линию
...
cbi ddrd, owport;1wire на ввод.;<<<<<<<<<< и ВОТ ЗДЕСЬ (и так 8 раз!)
...
brne owrxb0


И как вы тогда "приземляете линию"? :-)
зы:
Цитата
Попутно выяснилось, что девайс отдает байты от старшего бита к младшему (а вроде должен наоборот).
Шаманство какое-то...

У вас вроде все правильно... я делал так же!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.