Еще одна реализация 1-Wire

AVR
Наконец-то и я сочинил свою программную реализацию мастера шины 1-Wire. За исходниками и комментариями добро пожаловать под кат.



Недавно случай в лице школьного учителя программирования свел меня в роли помогающего с группой людей, запускающих метеозонд. Творчество юных, и все такое. Метеозонд состоит из платки на ATmega128, радиомодуля и кучки датчиков. Собственно, поскольку департамент программирования моей бывшей школы программированием железяк не занимается, этих товарищей и отправили ко мне. Датчиком температуры в том зонде работает знаменитый DS18B20. Естесственно, первым делом я предложил им нагуглить и использовать готовую библиотеку 1-Wire, после чего они отошли к работе просветленными. Однако через некоторое время оные подвижники пришли ко мне снова со словами «не компилится». «Фигня вопрос!» — подумал я. — «Наверное, что-то не задефайнили в заголовочниках», и начал ковырять библиотеку сам. Поковырял, правда не компилится. Поковырял еще, еще… В общем, сточив напильник до основания я решил, что самый лучший велосипед — велосипед, собранный самостоятельно, и решил написать модуль 1-Wire сам. Да и мне давно хотелось просто так поковыряться с этим протоколом, чисто для души.

Итак, я написал его, модуль 1-Wire моей мечты. Он состоит из двух частей. Битовые функции (послать/прочитать бит, сгенерировать PRESENCE) реализованы на православном ассемблере (внутренняя функция задержки тоже написана самостоятельно). Вторая часть — функции приема/передачи байт, они писаны на С. Используется стандартный модуль проверки CRC из поставки WinAVR. Исходники обильно прокомментированы.

Модуль написан под AVR Studio + AVR-GCC.

owbitfunc.h содержит:


#define F_CPU_MHz	8


— частота процессора в мегагерцах. F_CPU/1000000UL не прокатит, ассемблер не понимает суффикса UL, который присутствует в макросе F_CPU.


#define OW_PORT		PORTB
#define OW_DDR		DDRB
#define OW_PIN		PINB


— на каком порту будет реализован 1-Wire


#define OW_BUSMSK	(1<<PB0)	


— битовая маска ножки, которая будет портом 1-Wire


uint8_t OW_Presence(void);


— генерирует RESET и проверяет присутствие устройства. Возвращает 0 если PRESENCE не обнаружен, 0xFF если обнаружен.


void _ow_send_1(void);
void _ow_send_0(void);
uint8_t _ow_receive_bit(void);


— собственно, сами битовые функции. Последняя возвращает 0 если принят 0, 0xFF если принята 1.

owbytefunc.h содержит:


void OW_InitBus(void);


— инициализация порта 1-Wire.


void OW_WriteByte(uint8_t byte);
uint8_t OW_ReadByte(void);


— прочитать/записать байт.


uint8_t OW_ReadRom(uint8_t rom_addr[8]);


Читает адрес устройства в массив rom_addr и заодно проверяет его CRC. Если все хорошо — возвращает 1, если не особо — 0.

Для определения PRESENCE и приема бит использован немного нестандартный подход. Чаще всего это делается так: программа выдает импульс в шину, потом ждет определенное время, потом читает значение. Я же многократно проверяю шину в границах заданного временного интервала, ожидая именно бит данных. Это повышает устойчивость программы к разбросу таймингов устройств 1-Wire. Интересующиеся могут почитать ассемблерный исходник, он обильно прокомментирован.

Отладка и тестирование производились на уже знакомой читателям макетке с ATmega48 с тестовой программой для считывания ключей iButton, поскольку это единственное 1-Wire устройство, которое у меня есть. Программа читает серийный номер, преобразует его в строку и отсылает через UART.







Тестовый проект и отдельно модуль лежат в аттаче. Файлы модуля нужно просто добавить в проект, после чего подключить owbytefunc.h.
  • +1
  • 26 января 2012, 14:41
  • _YS_
  • 2
Файлы в топике: ow_demo.zip, owlib.zip

Комментарии (20)

RSS свернуть / развернуть
Что означает суффикс UL?
0
  • avatar
  • Aneg
  • 26 января 2012, 15:46
По умолчанию константы в С имеют тип int. 1000000 в int не влазит, и при обработке произойдет ошибка, если не сказать компилятору что это unsigned long. Для этого ставится суффикс UL.
0
читать букварь*!
UL == Unsigned Long

— *K&R
+1
вижу на макетке перемычки из витой пары. Ъ!
только, учитывая ее стоимость стремящуюся к нулю (в роли перемычек), можно и под размер обрезать, а не городить такие петельки… ;)
0
Та не… Петельки остались от предшествующей массовой прошивки. Надо было много раз перетыкать много МК, вот я и провел вокруг, чтобы дергать только МК, вставил/Enter/Enter/вынул->следующий.
0
да вокруг контроллера — ладно. я больше про соединяющую питания слева, и пару правее транзисторов(?), ну в смысле трех TO220 корпусов… хотя… если под рукой есть пара подходящих по длине проводков — вдруг обрезать становится таак лениивооо… ;) так что это не более чем…
0
Ну, для питания я всегда использую провода подлиннее, ибо всегда удобно ткнуть в нужное место.

То не транзисторы, то 79L05. :) Это пара. А три штуки — BC857.

соединяющую… пару правее транзисторов(?), ну в смысле трех TO220

Так та вообще не соединяет. Она хранится. :)

Большинство воткнутых деталей и перемычек бездействуют, просто они всегда воткнуты в макетку, чтобы под рукой были. Реально тут работает только МК и резистор.
0
kibermaster.net/rabota-s-shinoy-1-wire-podklyuchenie-termodatchika-ds18b20-k-avr/
вот тоже похожая библиотека, в ней есть проверка crc, возможность приема/передачи по двум пинам и эмуляция 1-wire через USART
0
Гы, как имена функций похожи. :) Чесслово, я, когда писал, никуда кроме описания 1-Wire не глядел. :)
0
c таким успехом проще заюзать внешний УАРТ-! ВАЙР интерфейс полноценный и самостоятельный — например DS2480B+

или ещё труёвее — DS2482S-800+ — восьмиканальный 1wire мастер, работает через i2c!!!

ну а если и делать передачу и приём битов с плавающей задержкой то… наверное это можно делать по прерыванию приёма/передичи UART… хотя наверное аппаратные интерфейсы таки круче будут

одного только вот не видел ни у кого!
реализацию поиска адресов… а самому раскуривать этот алгоритм… как-то убийственно чтоли?
0
Не, я так понял, тем перцам железо менять нельзя. Или не хочется.

В аппаратных конвертерах особого сысла не вижу, все прекрасно делается софтом. А если чего, можно и какую-нибудь тиньку под это отрядить.

Реализация Search ROM есть по сылке выше.

Вообще, то, что написал я — не библиотека для работы с устройствами, а именно реализация интерфейса в софте. Например, как софт-UART, если на кристалле нет. А это — софт-1Wire.
0
а самому раскуривать этот алгоритм… как-то убийственно чтоли?

Заинтриговали, почитал. :) Не такой уж он и страшный, в общем.
0
попробовал на 8 меге… чего то OW_Presence всегда возвращает окей, реально ключа нету (подставку не замутил еще).
Схема: joxi.ru/NeWXUdg5CbB7CgGBk3w
где d1/d3 — 4148, d2 — 5.1v стабилитрон. Подтяжка 4.7ком, вдоль 33ома.
0
извиняюсь, кз было)
0
ЫЫЫ :)
0
смд оно такое… диод, паста забилась под него, на землю кз было)
0
Стоит указать частоту 16МГц и не компилится s2.ipicture.ru/uploads/20130726/9tTw2ESm.jpg
0
  • avatar
  • lpa
  • 26 июля 2013, 20:17
«Это не баг, это фича.» :)

Я писал об этом.

Реализация работоспособна в интервале тактовых частот от 5 до 12МГц.
0
Я писал об этом.
Так исправь и здесь, в чем дело?
0
Дело в моей вселенской лени. :)
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.