DowLib

Ассемблерная библиотека (AVR) для работы с однопроводным интерфейсом Dallas One Wire.
Решил собрать воедино всё, что говорил по этому поводу, чтобы не приходилось искать. Итак, вашему вниманию предлагается полуфинальный вариант библиотеки для работы с однопроводной шиной. Почему полуфинальный? Потому, что финал в подобных случаях бывает только временный, как и в футболе. В футболе будет новый сезон, с новым чемпионом и новыми голами, а у меня будет новый проект, с новым использованием библиотеки. Но костяк, основная часть библиотеки сохраняется, и переезжает из проекта в проект. То её состояние, что существует на данный момент, я сфотографирую, и выложу.

Как подключать библиотеку?
Положить файлы Dowlib.asm, DowCrc.asm и DowSearch.asm в каталог с проектом, а в основной исходник проекта добавить строку
.include "DowLib.asm". 


А почему в комплекте три файла?
DowCrc.asm выведен в отдельный исходник потому, что вычисление контрольной суммы блока данных — очень распространённая операция. Например, во всех случаях, когда настройки программы хранятся в eeprom, вместе с ними хранится и контрольная сумма. В ходе считывания становится возможным проверить, достоверны ли данные, или они повреждены. Так же обстоит дело и с пакетной передачей данных через каналы связи. А если есть уже обкатанный и привычный метод подсчёта CRC — легче взять его из репозитория, чем каждый раз изобретать новый.
DowSearch.asm — процедура поиска всех устройств на шине, штука редко используемая. Чтобы не раздувать размер кода, эта подпрограмма сделана отдельно. Сами решайте, включать её в проект или не надо.

Какие контроллеры можно использовать?
Все AVR.

Как адаптировать библиотеку к собственному проекту?
В начале файла Dowlib.asm находятся объявления назначения вывода, к которому будет подключена шина, они выглядят вот так:

.equ	owport 	= PortB
.equ	owpin	= PinB
.equ	owddr	= DdrB
.equ 	owbit	= 3

Нужно заменить имена регистров порта на тот, что используется в вашем проекте, и указать номер бита порта. После описателей бита идут константы задержки для временных интервалов шины, для частоты процессора 8 МГц, которые можно пропорционально менять в зависимости от частоты в вашем проекте. Например, для частоты 16 МГц все эти цифры надо увеличить вдвое, а для частоты 6 МГц — уменьшить на 3/4.

.equ	Dow_rstTime = 4		; Длительность импульса сброса
.equ	Dow_rstPause = 10	; интервал восстановления после сброса
.equ	Dow_Stbit = 10		; Длительность старт-импульса бита
.equ	Dow_relax = 8		; Промжуток между стартом и семплом данных бита
.equ	Dow_sample = 60		; Длительность удержания данных на шине
.equ	Dow_b_Bit = 40		; Пауза - интервал между битами на шине


Какие функции содержит библиотека?
Ex_DowRst
Ex_DowSkipRom
Ex_DowMatchZ
Ex_PollDow
Ex_DowComm
Ex_DowRead
Ex_DowReadC
Ex_DowReadArrCY
DowCRC


Ex_DowRST — состояние шины «сброс». Входных параметров нет
В флаге CY возвращает отклик подключенного к шине устройства. CY-нет оклика, NC — есть отклик. Отклик возвращается, если шина исправна, и хотя бы одно устройство подключено.
Портит r15 r16 r17

Ex_DowSkipRom — делает сброс шины, и отправляет команду «Skip Rom» (0xCC) — одно из самых часто употребимых действий с шиной, на которой всего одно устройство. Входных параметров нет
В флаге CY возвращает отклик подключенного к шине устройства. CY-нет оклика, NC — есть отклик.
Портит r15 r16 r17

Ex_DowMatchZ — выбор устройства на шине. Столь же частая операция, для шины со множеством подключенных устройств. Указатель на заводской номер выбираемого устройства (серийник) в памяти программ (8 байт) должен содержаться в регистровой паре Z. Заменой команды lpm на ld в теле подпрограммы, можно настроить её на хранение номеров в памяти данных.
В флаге CY возвращает отклик подключенного к шине устройства. CY-нет оклика, NC — есть отклик.
Портит r15 r16 r17 r18

Ex_DowComm — обмен данными по шине. Одновременно и чтение и запись, так устроена шина, цикл чтения ничем не отличается от записи числа 0xFF
Входной параметр — r16, и он же результат. При записи несоответствие записанного и принятого байтов обычно означает конфликт на шине.
Портит r16 r17

Ex_DowRead — чтение шины, один байт.
результат чтения — r16
Портит r16 r17
Ex_DowReadС — чтение одного байта с шины и обновление CRC.
результат чтения — r16, CRC — r18
Портит r7 r8 r16 r17 r18

Ex_DowReadArrCY — чтение массива и подсчёт CRC. Обычно применяется при чтении скратчпада или серийника устройства. Считывает в память массив, и проверяет CRC. Размер считываемых данных указывается без учёта контрольки. Таким образом, для серийного номера он равен 7, для скратчпада-8. В память данные укладываются вместе с принятой контролькой, то есть при чтении серийного номера — 8 байт, при чтении скратчпада — 9. В флаге Z возвращается результат сравнения принятой и посчитанной контрольных сумм.
На входе: r17 — размер массива, yh:yl — указатель, куда положить в память.
На выходе: заполненный массив, Z=контрольки совпали, r16 — считанная контролька, r18-ожидаемая (подсчитанная) контролька.
Портит регистры r7 r8 r15 r16 r17 r18

DowCrc — процедура обновления контрольной суммы. В качестве посчитанного значения CRC используется регистр r18, как глобальная переменная. Если нам нужно, скажем, посчитать контрольку блока — то что мы делаем?
Для начала очищаем r18, таким образом инициализируем CRC.
Вызываем процедуру, такое количество раз, сколько байт в нашем блоке данных, передавая каждый байт в r16. (при этом значения регистров r7 r8 r17 становятся произвольными, а r18 приобретает значение посчитанной CRC. Его не трогаем, оно будет использоваться для расчёта следующего элемента)
После достижения конца блока, r18 содержит нужную нам контрольку. сравниваем её с ожидаемым значением.
Портит r7 r8 r17

Ex_PollDow — опрос шины, на предмет завершения устройством операции преобразования. Вызывается обычно после команд измерения температуры, напряжения, после команд записи в независимую память. Подробнее, о необходимости опроса шины, написано в даташитах конкретных 1-wire микросхем.
Портит r16 r17

SearchDow — поиск устройств на шине DOW. Список найденных серийников складируется в память, по восемь байт на каждую запись. На входе в функцию требуется указатель на массив в памяти в паре XH:XL.
На выходе отдаёт заполненный массив в памяти, и в r21 — количество обнаруженных устройств.
Портит r0,r18,r19,r20,r21 (можно переназначить)
Комментарии к алгоритму есть здесь
Недостаток: Отсутствует ограничитель, при большом количестве устройств на шине, и малым объёмом памяти в контроллере — может разрушить стек. Легко фиксится, но пока в этом не было необходимости.

А размер?
Размер, безусловно, имеет значение! 318 байт без процедуры поиска, 410 байт — с поиском, 36 байт — отдельно процедура подсчёта CRC.

Можно пример посмотреть?
Без проблем! Например, вот так читают серийный номер:

		rcall	Ex_DowRST	; сброс шины
		ldi	r16,0x33	; Команда "чтение серийника"
		rcall	Ex_DowComm
		ldi	yh,high(Buf)	;указатель на буфер для номера
		ldi	yl,low(Buf)
		ldi	r17,7	 ; без учёта контрольки!
		rcall	Ex_DowReadArrCY	; читаем...

А вот так — измеряют температуру

		rcall	Ex_DowSkipRom	; сброс шины
		ldi	r16,0x44	; ConvertT cmd
		rcall	Ex_DowComm		; send it
		rcall	Ex_Polldow	; Polling
		rcall	Ex_DowSkipRom	; сброс шины
		ldi	r16,0xBE	; ReadScratchPad cmd
		rcall	Ex_DowComm		; send it
		ldi	r17,8		; 8 байт
		ldi	yh,high(Buf)	; В буфер...
		ldi	yl,low(Buf)
		rcall	Ex_DowReadArrCY	; ...Читаем скратчпад


Где взять эту нужную, полезную радость?
Вот здесь

Обновление от 23.04.14 Скачать
  • +6
  • 11 апреля 2011, 13:49
  • Gornist

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

RSS свернуть / развернуть
Функцию поиска осветить забыл.
0
  • avatar
  • Vga
  • 11 апреля 2011, 15:10
Спасибо, добавил описание.
0
То, что надо… хотел сам писать такое, а уже все сделано :)
0
Горнист, а почему-бы не сделать константы задержек в микросекундах, а не в попугаях?

Пусть, к примеру, Dow_rstTime_us указывает пользователь, а Dow_rstTime будет расчитываться автоматически при компиляции. Правда, придется еще указывать частоту МК, но все-равно это проще, чем считать вручную.


А чаще всего нет необходимости в изменении таймингов — тогда можно просто изменить F_MCU на свой вкус и получить нужные задержки…
Удобно же :)

А вообще, библиотека хорошая. Главное — компактная. И описано хорошо. Особенно радует, что указаны регистры, которые портятся той или иной функцией.

Вот только непонятно (лень глядеть в код) — на сколько уровней опускается стек при использовании тех или иных функций… Скорее всего будет не больше 2х — сама функция + вызываемая из неё задержка. Но все-же…
+1
Исторически так сложилось. Этому коду много лет, и начинался он с двух палочек и какашки. Нет ничего удивительного, что рудименты дожили до наших дней. Микросекунды — это будет, конечно… Даже слова подобрать не могу. Красиво? Нихрена не красиво. Правильно? Тоже не то.
Да, с микросекундами — это будет ПРИВЫЧНО. Типа привычно. Но лучше работать от этого не станет, я думаю. Зато добавит овермайнда, и возможно, раздует код. Не, не хочу. Попугаи проще. Если нет разницы — зачем платить больше?
Со стеком не считал. Максимум, по моим представлениям, 2-3 уровня в глубину.
0
Категорически не согласен.
Красиво? Быть может не очень. Лишние константы, расчёты. Правильно? Да! Всё-таки настоящее время приоритетнее, а не попугаи. Устройству, с которым разговариваешь, до них дела нет. Такой код будет работать при разной частоте, при этом нужно будет заменить одну константу, а не несколько. Да и ошибиться не получится, ведь указываешь частоту, а не какие-то цифры, для которых можно забыть, для какой они предназначались частоты.
возможно, раздует код
Не раздует. Если задать время препроцессорными директивами, используя частоту для расчёта (как коэффициент), то кода не прибавится ни на байт. Попугаи проще для написания, а для использования проще то, что проще пользователю.
0
Однако же это мелочи, и их несложно допилить уже по ходу использования, если приходится пользоваться библиотекой часто.
+2
(воздев руки горе:) Боженька! Только не говори мне, будто ты помешаешь всем этим людям поступить так, как они хотят!
:)
-1
Отличная библиотека для 1-Wire на Си: DS18X20 with AVR
0
Спасибо, пригодится.
Есть у меня еще желание в таком же стиле сделать IIC-библиотеку (именно программую, TWI не везде есть). По прикидкам — примерно такая, может чуть больше выйдет.
0
Такую? Даже чуть меньше получается.
0
Огромный плюс твоей библиотеки — не используется стек. Я когда писал — вовсю использовал подпрограммы, и уже когда доходило до самих функций приёма/передачи относительно основного цикла мог быт 5-6 уровень вложенности, что не есть хорошо.
0
Минимальная тактовая частота получается 2 МГц?
0
  • avatar
  • ACE
  • 15 апреля 2011, 13:45
Если пересчитать задержки ручками, и повставлять константы в нужные места программы, то можно и меньше.
0
Кто нибудь в Протиусе пробовал играться с этой библиотекой? У меня что-то не получилось…
0
  • avatar
  • Volk
  • 11 марта 2012, 13:22
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.