Си библиотека для работы с 1-Wire устройствами

31/12/2010 - 16:03
   Для работы с устройствами, поддерживающими 1-Wire протокол уже давным-давно написаны библиотеки. Поэтому нет смысла изобретать велосипед (лично я это уже делал, когда программировал  на ассемблере) и писать что-то свое. На сайте фирмы ATMEL есть замечательный application note AVR318: Dallas 1-Wire, в котором рассмотрены два варианта реализации 1-Wire протокола на микроконтроллерах AVR – программная и аппаратная. Программная реализация позволяет использовать однопроводный протокол на любых микроконтроллерах. Аппаратная – только на тех, на которых есть модуль UART. Аппаратной поддержки 1-Wire протокола «в чистом виде» микроконтроллеры AVR не имеют, однако, используя модуль UART неким хитрым образом, эту поддержку можно организовать. К application note идет проект. Я взял из этого проекта исходные файлы библиотеки, добавил, изменил несколько функций и написал файл compilers.h, чтобы можно было использовать эту либу с любым из трех компиляторов – IAR AVR, GNU GCC (WINAVR), CodeVision.

   Библиотека состоит из следующих файлов
 
OWISWBitFunction.h
OWISWBitFunction.c
OWIUARTBitFunction.c
 
OWIHighLevelFunction.h
OWIHighLevelFunction.c
 
OWIPolled.h
compilers.h
 
OWIdefs.h
OWIdevicespecific.h
OWIcrc.h
OWIcrc.c

Как подключить библиотеку к проекту

Процесс интеграции 1-Wire библиотеки с проектом заключается в следующем:

- переписываем файлы библиотеки в папку проекта

- подключаем сишные файлы к проекту
OWIHighFunction.c
OWISWBitFunction.c
OWIUARTBitFunction.c
OWIcrc.c

- добавляем заголовочные файлы в main.c
#include "OWIPolled.h"
#include "OWIHighLevelFunctions.h"
#include "OWIBitFunctions.h"
#include "common_files\OWIcrc.h"

- настраиваем файл OWIPolled.h

- выбираем реализацию OneWire интерфейса – программную 
       #define     OWI_SOFTWARE_DRIVER    
       //#define     OWI_UART_DRIVER

- задаем тактовую частоту микроконтроллера
       #define     CPU_FREQUENCY   16.000

- задаем порт, к которому подключена OneWire шина
       #define     OWI_PORT      PORTD   //!< 1-Wire PORT Data register.
       #define     OWI_PIN         PIND    //!< 1-Wire Input pin register.
       #define     OWI_DDR        DDRD    //!< 1-Wire Data direction register.

- в main.c задаем вывод, к которому подключена OneWire шина
      #define BUS   OWI_PIN_7
 
Для GCC проектов в makefile нужно будет добавить все сишные файлы. 
Например, так:
 
SRC = $(TARGET).c bcd.c lcd_lib.c OWISWBitFunctions.c OWIHighLevelFunctions.c OWIUARTBitFunctions.c  common_files/OWIcrc.c

Файлы

Application note AVR318: Dallas 1-Wire

Проекты проверялись в железе и никаких нареканий не вызывали. В Proteus`е я их тоже запустил, но не сразу. Оказывается по умолчанию датчикам DS18B20 присваиваются одинаковые адреса. При использовании нескольких датчиков адреса нужно подправить ручками.

Подробное описание проектов будет уже в новом году...

Комментарии   

# foxit 31.12.2010 20:16
на сайте gaw.ru есть апноут AVR318 на русском.
Ответить | Ответить с цитатой | Цитировать
# foxit 03.01.2011 09:23
Жду с нетерпением проектов!
Ответить | Ответить с цитатой | Цитировать
# Petrov 06.01.2011 10:39
Спасибо! ;-)
Ответить | Ответить с цитатой | Цитировать
# Vector 07.01.2011 11:01
И в Proteus - все работает!
Тактовая процессора 8MHZ ,и адрес одного датчика поменять. (Proeus по умолчанию лепит одинаковые для всех)
Спасибо!
Ответить | Ответить с цитатой | Цитировать
# Pashgan 08.01.2011 09:14
Отлично. А я не знал, что адреса датчиков менять нужно.
Ответить | Ответить с цитатой | Цитировать
# Vector 10.01.2011 18:37
Ну я свои "грабли" описал, не ожидал, что такую фигню Proteus делает.
Ответить | Ответить с цитатой | Цитировать
# foxit 07.01.2011 11:34
А под winavr будут проекты?
Ответить | Ответить с цитатой | Цитировать
# Pashgan 07.01.2011 13:14
Уже есть. Скоро выложу. Материала пока нет. Праздники - отдыхаю, ленюсь.
Ответить | Ответить с цитатой | Цитировать
# Pashgan 10.01.2011 20:50
Выложил проекты для WINAVR, CodeVision и Proteus`a.
Ответить | Ответить с цитатой | Цитировать
# Ky 03.09.2014 19:49
А можете носом ткнуть в проект для протеуса? Жажду взглянуть на него, ибо у самого в проте далласовский датчик работает крайне нестабильно.
Ответить | Ответить с цитатой | Цитировать
# Vector 08.01.2011 16:27
С частотой в Proteus действительно - лажа. Работает, только если в OWIPolled.h завысить на 50% CPU_FREQUENCY (в Protrus 4MHz ,OWIPolled.h 6MHz)
Предпочтительней уменьшить время в настройках модели датчика процентов на 30. (проверял - помогает с IAR 5.3 и Proteus 7.7 Sp2; макет на ATMEGA8515 4MHz)
Ответить | Ответить с цитатой | Цитировать
# Pashgan 10.01.2011 14:48
А я проверил второй проект в Proteus`e и все работает как часы!!!
Ответить | Ответить с цитатой | Цитировать
# andrdoy 10.01.2011 07:12
а что делать если датчик не 18B20
а 18S20 или 1820 (без буквы)
Ответить | Ответить с цитатой | Цитировать
# Pashgan 10.01.2011 14:46
DS18S20 и DS1820 отличается от DS18B20 температурным разрешением. У первых разрешение 9 бит, у последнего 9-12.
Чтобы использовать проект "работа с одним датчиком DS18B20" для датчика DS18S20, нужно изменить кусок вывода значения температуры на дисплей
Код:
/*выводим знак*/
LCD_Goto(5,0);
if ((scratchpad[1]&128) == 0){
LCD_WriteData('+');
}
else{
LCD_WriteData('-');
tmp = ((unsigned int)scratchpad[1]<<8)|scratchpad[0];
tmp = ~tmp + 1;
scratchpad[0] = tmp;
scratchpad[1] = tmp>>8;
}

/*выводим целую часть*/
temperature = (scratchpad[0]>>4)|((scratchpad[1]&7)<<4);
BCD_3Lcd(temperature);

/*выводим дробную часть*/
temperature = (scratchpad[0]&15);
temperature = (temperature>>1) + (temperature>>3);
LCD_WriteData('.');
BCD_1Lcd(temperature);


на

Код:
LCD_Goto(5,0);
if ((scratchpad[1]&128) == 0){
LCD_WriteData('+');
}
else{
LCD_WriteData('-');
}
temperature = (scratchpad[0]>>1);
BCD_3Lcd(temperature);
Ответить | Ответить с цитатой | Цитировать
# CHERTS74 17.02.2011 06:22
Для DS18B20 вообще можно заменить кусок:
Код:
/*выводим знак*/
LCD_Goto(5,0);
if ((scratchpad[1]&128) == 0){
LCD_WriteData('+');
}
else{
LCD_WriteData('-');
tmp = ((unsigned int)scratchpad[1]<<8)|scratchpad[0];
tmp = ~tmp + 1;
scratchpad[0] = tmp;
scratchpad[1] = tmp>>8;
}

/*выводим целую часть*/
temperature = (scratchpad[0]>>4)|((scratchpad[1]&7)<<4);
BCD_3Lcd(temperature);

/*выводим дробную часть*/
temperature = (scratchpad[0]&15);
temperature = (temperature>>1) + (temperature>>3);
LCD_WriteData('.');
BCD_1Lcd(temperature);


на более короткий и лаконичный:

Код:
LCD_Goto(5,0);
if ((scratchpad[1]&128) == 0){
LCD_WriteData('+');
}else{
LCD_WriteData('-');
}
int reading = (scratchpad[1]<<8) + scratchpad[0];
if (reading & 0x8000) {
reading = (reading ^ 0xffff) + 1;
}
float temp = (6 * reading) + reading / 4;
dtostrf((temp/100),2,2,temperature);
LCD_SendString(temperature);
LCD_WriteData('C');


После этого можно избавиться от файла bcd.c в Makefile
Не забыть добавить вначале main.c
#include и убрать #include "bcd.h"

После
int main( void )
{
удалить
unsigned int tmp = 0;
unsigned char temperature;
добавить
Код:#include<stdlib.h>
int main(void)
{
unsigned char temperature[20];
Ответить | Ответить с цитатой | Цитировать
# Pashgan 17.02.2011 07:44
Код выглядит компактно только на Си. На Асме код будет тяжелый и медленный.
Ответить | Ответить с цитатой | Цитировать
# CHERTS74 17.02.2011 09:50
Не думаю что если я выкину файл bcd.c с кучей ненужных функций и заменю его на более простые, код от этого усложнится. Думаю наоборот полегче станет. Да и стак как бы полегче. Проверено ;)
А так, огромное спасибо за такие полезные статьи!

P.S. Кстате, почему то не приходит письмо с активацией моего акаунта CHERTS :(
Ответить | Ответить с цитатой | Цитировать
# Pashgan 19.02.2011 23:47
Неиспользуемые функции не добавляют лишних байт к прошивке. Чего нельзя сказать о стандартных сишных функциях. Они как правило тяжеловесны, почему я их и недолюбливаю. Сравните два варианта кода и увидите разницу. Размер hex файла во втором случае будет больше.

Кстати, с чего вы решили, что dtostrf более простая? Видели исходники этой функции. Посмотрите.
www.koders.com/c/fid59843B28432C0FF3F7D5DA5BE2A2F4051E5E095E.aspx?s=dtoa_prf#L54
www.koders.com/c/fidDB4D83581A0529937AFB0C8F77401277E6F372AA.aspx?s=dtoa_prf#L29

Цитата:
Кстате, почему то не приходит письмо с активацией моего акаунта CHERTS
Может быть не правильно указали е-mail, может быть движок глючит.Я активировал ваш аккаунт вручную.
Ответить | Ответить с цитатой | Цитировать
# Вадим 24.01.2011 19:51
Заметил одну неточность в проекте для IAR AVR — работа с одним датчиком DS18B20. В файле main.c дробная часть обрабатывается так:
Код:
temperature = (scratchpad[0]&15);
temperature = (temperature>>1) + (temperature>>3);
LCD_WriteData('.');
BCD_1Lcd(temperature);

При обработке возникает погрешность (это можно легко проверить: пусть датчик померил 0,9375 гр. или 0x0F, на LCD выведет - 0,8гр. цельсия)
Правильнее написать так:
Код:
temperature = (scratchpad[0]&15);
temperature = (temperature<<1) + (temperature<<3);// Умножаем на 10
temperature = (temperature>>4);//делим на 16 или умножаем на 0,0625
LCD_WriteData('.');
BCD_1Lcd(temperature);
Ответить | Ответить с цитатой | Цитировать
# Pashgan 29.01.2011 21:27
Да, есть некоторые недостатки
Ответить | Ответить с цитатой | Цитировать
# Богдан 29.04.2011 09:39
Дякую авторам!
Ответить | Ответить с цитатой | Цитировать
# Den1s 11.08.2011 13:13
подскажите, а почему ни с одной тини не компилится в ИАРе проект с этой библиотекой. Пробовал 10, 13, 13А, 2313. Ругается на стек.
Ответить | Ответить с цитатой | Цитировать
# Blambik 07.09.2011 13:13
Автор! Респект! Наконец то увидел реализацию функции SearchROM! А то никак не мог ее реализовать :(
Ответить | Ответить с цитатой | Цитировать
# Max 05.11.2011 20:45
Нужен код для конфигурации датчика (изменить его разрешающую способность),
как запрограммирова ть R0=0, R1=0
Заранее спасибо
Ответить | Ответить с цитатой | Цитировать
# Финский 19.10.2013 11:34
Спасибо за библиотеку, разбираюсь потихоньку. Столкнулся с некоторыми затыками, которые решил и делюсь решениями:
1. В Atmel Studio в упор не компилился проект, с ошибкой No such file or directory, на файл compilers.h, пока в свойствах проекта не указал include folders, добавил корневой каталог проекта, и папку common_files.
2. В протеусе в упор не виделись датчики, ни один, ни несколько сразу. Даже на Presence не отвечали. Проблема решилась заменой Код:#define OWI_DELAY_OFFSET_CYCLES 13 //!< Timing delay when pulling bus low and releasing bus. на значение 7 или ниже. При значении 8 - уже не работает. В железе пока не проверялось.
Ответить | Ответить с цитатой | Цитировать
# ДмитрийМ 24.10.2013 13:28
попробовал этот проект на attiny2313 на частоте 8 мгц, в протеусе работает, в железе не идёт дальше вот этой строчки
Код:
/*ждем, когда датчик завершит преобразование*/
while (!OWI_ReadBit(BUS));

наличие датчика проверял функцией OWIsearchRom, датчик находится, если он подключен, не находится, если отключен.
Ответить | Ответить с цитатой | Цитировать
# Pashgan 24.10.2013 13:51
Попробуй заменить программной задержкой и посмотреть результат.
Ответить | Ответить с цитатой | Цитировать
# ДмитрийМ 24.10.2013 16:18
сам только что об этом подумал, поставил вместо этого Код:delay_ms(800);
всё так же, протеус - работает, железо - нет
Ответить | Ответить с цитатой | Цитировать
# ДмитрийМ 24.10.2013 18:47
Работаю, кстати, в codevision, попробую проект для авр студии.
Ответить | Ответить с цитатой | Цитировать
# vitaliy 15.01.2014 14:23
Цитата:
1. В Atmel Studio в упор не компилился проект, с ошибкой No such file or directory, на файл compilers.h, пока в свойствах проекта не указал include folders, добавил корневой каталог проекта, и папку common_files.
Такие же грабли в AVR Studio 4.19,пока не прописал в include directories корневой каталог и папку common_files,вы брасывало ту же ошибку.
Контролер Atmega8,кварц 16 МГц.Фокус с proteus в плане понижения в два раза частоты в свойствах Atmega8 - работает.Иначе температура на LCD +0,00.
Еще раз спасибо за библиотеку.
Ответить | Ответить с цитатой | Цитировать
# Володя 26.01.2014 16:33
Скажите пожалуйста где прописывается include directories? Папку common_files добавил, все равно ошибка No such file or directory
Ответить | Ответить с цитатой | Цитировать
# Pashgan 28.01.2014 11:47
Для какого компилятора проект?
Ответить | Ответить с цитатой | Цитировать
# Володя 28.01.2014 12:40
5я студия
AVR GNU C Compiler
Ответить | Ответить с цитатой | Цитировать
# _Артём_ 28.01.2014 13:53
Возможны варианты:
1) Если у вас makefile project - прописываеие пути в makefile :)
2) Проект с визуальными настройками - открываете свойства проекта - вкладка Toolchain - AVR GNU C Compiler -Directories. Там вписываете нужные пути.
Ответить | Ответить с цитатой | Цитировать
# Pashgan 29.01.2014 09:11
Свойства проекта > вкладка Toolchain > AVR GNU C Compiler > Directories
Там нужно прописать пути:
../common_files
../
Ответить | Ответить с цитатой | Цитировать
# Володя 29.01.2014 15:46
Большое спасибо!!!! Заработало ;-)
Ответить | Ответить с цитатой | Цитировать
# Berg 13.03.2015 20:28
Спасибо Всем. Наконец-то заставил работать сей датчик и вывести данные на дисплей nokia5110(3310) в AVR Studio. Теперь мечтаю получить данные с 2-х датчиков.
Ответить | Ответить с цитатой | Цитировать
# Vol-Y.I.P 20.04.2015 14:04
Привет Всем!!!
Такая ошибка:"undefin ed reference to `OWI_Init'"
Atmel Studio 6.2
В чем может быть проблема?
Ответить | Ответить с цитатой | Цитировать
# Sanek0 19.06.2016 08:50
Такая же проблема, похоже как то связано с тем, что исходный проект в C++. Если получится решить как то напишу.
Ответить | Ответить с цитатой | Цитировать
# Sanek0 19.06.2016 10:10
У кого возникает ошибка "undefin ed reference to `OWI_Init'" и проект на C++ необходимо хедлеры указать как внешние "С".
Код:
extern "C"
{
#include "OWIHighLevelFunctions.h"
#include "OWIBitFunctions.h"
#include "common_files/OWIcrc.h"
}
Ответить | Ответить с цитатой | Цитировать

Добавить комментарий

Защитный код
Обновить