Работа с шиной 1-wire. Подключение термодатчика DS18B20 к AVR

Обновлено 21.01.14. Исходники переписаны под AVR Studio 6 (с тулчейном)

Сразу хочу сообщить, что в этой статье я не буду описывать принцип работы шины (описание временных слотов и т.д.). Статья будет типа "Быстрый старт". Конкретно: я выложу свою библиотеку для работы с 1-wire, опишу как ею пользоваться, как подключить устройства к шине, как производить поиск устройств, передавать данные и т.д. А так, как (вероятно) 70% радиолюбителей в первую очередь решит подключить к шине термодатчик DS18B20, я выложу библиотеку для работы с DS18B20, где надо тупо запустить преобразование, подождать пока идет преобразование и записать температуру в массив.

Теория


Итак, 1-wire(еще называют MicroLAN, dallas-wire) так назвали потому что для передачи данных в обе стороны используется только 1 провод. Среди самых популярных устройств, работающих на этой шине можно выделить термодатчик DS18B20 и электронный ключ DS1990 (которым вы в подъезде двери открываете). У сети 1-wire есть одно ведущее устройство(Master) и несколько (или 1) подчиненных (Slave). Бывают сети с несколькими ведущими, по это нам сейчас не нужно. Передачу данных начинает ведущий, только он может посылать сигнал сброса (Reset), остальные устройства могут только отвечать на его запросы. Все устройства подключаются к шине параллельно, то есть, линию данных с каждого устройства (она обозначается DATA, DQ или OW_DQ), включая линию ведущего, подключают к одному проводу, типа вот так: 


Еще линия должна быть подтянута к питанию через резистор 2,2-4,7 кОм. Каждое устройство имеет свой индивидуальный 64-битный адрес, который устанавливается при изготовлении устройства (прямо на заводе).

Практика


Работать с 1-wire мне приходится очень часто, поэтому, я написал безглючную библиотеку, которая имеет кучу функций, включая возможность эмуляции 1-wire с помощью USART. К тому же, библиотека стабильно работает даже в протеусе. Многие говорят, что 1-wire слишком медленный, а из-за того, что он требует очень точных временных задержек (в несколько микросекунд), с ним практически не возможно работать, если в микроконтроллере часто вызываются прерывания. Действительно, если одновременно использовать софтовый USB (V-USB) и 1-wire, то что то одно с них не будет стабильно работать. Я решил эту проблему эмуляцией 1-wire через USART микроконтроллера. Поэтому, если у вас будет свободный USART, то 1-wire обязательно вешайте на него. Как же будем подключать устройства? Я использую три (уже 4) способа. Первый. Эмуляция USARTом. Если вы используете длинную линию (более 20 метров) и более 4 устройств на шине, то подключать нужно вот так: Здесь сигнал усиливается с помощью двух транзисторов. На шине стоит метка OW_DQ, вот к ней и подключаем подчиненные устройства. Если длина не более 20 метров, то можно подключить вот так:Здесь резистор может быть номиналом 2,2 - 4,7 кОм. Если вы не используете USART для эмуляции 1-wire, то подключать нужно так:Здесь одна ножка МК работает в качестве и входа, и выхода. Есть еще и четвертый способ, подключение как на первом, только для эмуляции не используется USART, но мне этот способ ни разу не понадобился. Давайте теперь соберем схему в протеусе (можете скачать в прикрепленных файлах). USART будет занят терминалом, поэтому шина будет подключена по третьем способу. В качестве ведущего - ATMega8, подчиненные - термодатчики DS18B20 и DS18S20, память EEPROM на 256 Кбит, таблетка, DS18B20 и двухканальный ключ DS2413. Так же, на схеме есть терминал, в котором будут отображаться данные.

Код


Скачайте прикрепленные файлы и откройте onewire.h. В нем есть строка
#define MAXDEVICES 10

Здесь указывается максимальное количество подчиненных устройств, которые будет искать подчиненный, если выберите меньше, чем подключено, то просто не будут обнаружены все устройства, если больше - то увеличиться время процедуры поиска. Но лучше ставьте с запасом, при 32 поиск занимает не более двух секунд (а может и меньше секунды).
#define UART_AS_OneWire

Если вы не используете эмуляцию 1-wire через USART, то закомментируйте эту строку.
#define OW_DDR DDRB
#define OW_PORT PORTB
#define OW_PIN PINB
#define OW_BIT 0

Если не используется эмуляция, укажите здесь куда подключен 1-wire. В том же файле есть несколько функций:
unsigned char OW_Reset(void);
void OW_WriteBit(unsigned char bit);
unsigned char OW_ReadBit(void);
unsigned char OW_ReadByte(void);
void OW_WriteByte(unsigned char byte);
unsigned char OW_SearchROM( unsigned char diff, unsigned char *id );
void OW_FindROM(unsigned char *diff, unsigned char id[]);
unsigned char OW_ReadROM(unsigned char *buffer);
unsigned char OW_MatchROM(unsigned char *rom);

По названию функции можно определить их предназначение, поэтому не стоит их описывать. В исходниках откройте главный файл (main.c). Здесь есть функция search_ow_devices(), она производит поиск устройств на шине и записывает их адреса в многомерный массив owDevicesIDs[MAXDEVICES][8], возвращает количество найденных устройств. Вот главная функция:
int main(void)
{
stdout = &usart_str; // указываем, куда будет выводить printf

DDRB = 0b00000000; PORTB = 0b00000000;
DDRC = 0b00000000; PORTC = 0b00000000;
DDRD = 0b00000010; PORTD = 0b00000000;

USART_init(); // включаем uart

timerDelayInit();

nDevices = search_ow_devices(); // ищем все устройства

printf("---------- Found %d devices ----------", nDevices);

for (unsigned char i=0; i<nDevices; i++) // теперь сортируем устройства и запрашиваем данные
{
// узнать устройство можно по его груповому коду, который расположен в первом байте адресса
switch (owDevicesIDs[i][0])
{
case OW_DS18B20_FAMILY_CODE: { // если найден термодатчик DS18B20
printf("\r"); print_address(owDevicesIDs[i]); // печатаем знак переноса строки, затем - адрес
printf(" - Thermometer DS18B20"); // печатаем тип устройства
DS18x20_StartMeasureAddressed(owDevicesIDs[i]); // запускаем измерение
timerDelayMs(800); // ждем минимум 750 мс, пока конвентируется температура
unsigned char data[2]; // переменная для хранения старшего и младшего байта данных
DS18x20_ReadData(owDevicesIDs[i], data); // считываем данные
unsigned char themperature[3]; // в этот массив будет записана температура
DS18x20_ConvertToThemperature(data, themperature); // преобразовываем температуру в человекопонятный вид
printf(": %d.%d C", themperature[1],themperature[2]);
} break;
case OW_DS18S20_FAMILY_CODE: { // если найден термодатчик DS18B20
printf("\r"); print_address(owDevicesIDs[i]); // печатаем знак переноса строки, затем - адрес
printf(" - Thermometer DS18S20"); // печатаем тип устройства
} break;

case OW_DS1990_FAMILY_CODE: { // если найден электронный ключ DS1990
printf("\r"); print_address(owDevicesIDs[i]); // печатаем знак переноса строки, затем - адрес
printf(" - Serial button DS1990"); // печатаем тип устройства
} break;
case OW_DS2430_FAMILY_CODE: { // если найдена EEPROM
printf("\r"); print_address(owDevicesIDs[i]); // печатаем знак переноса строки, затем - адрес
printf(" - EEPROM DS2430"); // печатаем тип устройства
} break;
case OW_DS2413_FAMILY_CODE: { // если найден ключ
printf("\r"); print_address(owDevicesIDs[i]); // печатаем знак переноса строки, затем - адрес
printf(" - Switch 2413"); // печатаем тип устройства
} break;
}
}
while(1){}
}

В начале у нас идет инициализация периферии, затем, производится поиск устройств на шине и найденное количество записывается в переменную nDevices. Далее, в цикле for определяется тип устройства (его можно определить по первом байту адреса). В терминале протеуса печатается адрес каждого устройства и его тип: Как видите, напротив DS18B20 написана еще и его температура, глянем в код:
printf("\r"); print_address(owDevicesIDs[i]); // печатаем знак переноса строки, затем - адрес
printf(" - Thermometer DS18B20"); // печатаем тип устройства
DS18x20_StartMeasureAddressed(owDevicesIDs[i]); // запускаем измерение
timerDelayMs(800); // ждем минимум 750 мс, пока конвентируется температура
unsigned char data[2]; // переменная для хранения старшего и младшего байта данных
DS18x20_ReadData(owDevicesIDs[i], data); // считываем данные
unsigned char themperature[3]; // в этот массив будет записана температура
DS18x20_ConvertToThemperature(data, themperature); // преобразовываем температуру в человекопонятный вид
printf(": %d.%d C", themperature[1],themperature[2]);

В первых двух строчках просто печатается адрес устройства и его тип. Затем, запускается измерение с помощью функции DS18x20_StartMeasureAddressed(owDevicesIDs[i]);. В эту функцию передается массив с адресом устройства. Далее, нужно подождать 750 мс, пока конвертируется температура, после чего, считываем данные с устройства DS18x20_ReadData(owDevicesIDs[i], data);. В функцию передается указатель на массив с адресом и указатель на массив, в который надо записать результат (2 байта). Теперь надо перевести эти 2 байта в человекопонятный вид, то есть, "знак, целая часть, запятая, десятая часть", это делает функция DS18x20_ConvertToThemperature(data, themperature);. Кстати, совсем не обязательно для запуска измерения температуры передавать адрес устройства, можно просто написать DS18x20_StartMeasure(). Тогда преобразование запустится на всех DS18B20, которые подключены к шине, спустя 750мс можно считать данные по очереди со всех DS18B20 без задержки. Так же, если используете эмуляцию 1-wire через USART, то обязательно устанавливайте не только DDR пина TX, а и PORT, иначе обмен на шине будет запускаться максимум в 30% случаев.
Обновление №1 (5.12.2011):

Добавил возможность подключения четвертым способом. Подключение такое же как в первых двух, но для эмуляции не используется USART. Этот способ стоит использовать если у Вас занят USART и линия длинней 15-20 метров. В файле onewire.h появились новая опция:
// Если для эмуляции 1-wire не спольльзуется USART, но используется 2 пина (вход и выход)
#define OW_TWO_PINS

Также Вам стоит немного взглянуть сюда:
	#ifndef OW_TWO_PINS //если используется один пин, укажите его номер
#define OW_BIT 0
#else // если используются 2 пина, укажите их номера
#define OW_BIT_OUT 1
#define OW_BIT_IN 0
#endif

При настройке портов нужно установить DDR и PORT входа в 0, а выхода в 1.
Обновление №2 (3.1.2012):

Добавил возможность проверки CRC. Теперь функция DS18x20_ReadData() возвращает 0, если crc ошибочная. Зачем это нужно? Делал один проект, где на шине висит много датчиков и есть вероятность, что после прочтения адреса один из датчиков может быть отключен и система должна знать, что его нет, но функция DS18x20_ReadData() возвращает 1, если на шине есть любое устройство 1-wire, так как наличие устройства функция определяет с помощью функции OW_Reset(). Теперь с датчика считываются не только первые 2 байта, в которых температура, а все 9, вместе с контрольной суммой (CRC), контрольная сумма проверяется, и если она не совпала, то возвращается 0. Вопросы в комментариях.

Скачать исходники и проект в Proteus (84 Kb)

Комментарии

  1. Статья понравилась
    единсвенное не нашел в ней упоминания про среду прогаммирования вот и гадаю... вроде WinAvr?

    ОтветитьУдалить
  2. угадали:). Точней в связки AVR Studio 4 + AVR Toolchain

    ОтветитьУдалить
  3. Доброго времени суток)Очень понравилась мне ваша статья)но...есть но..не как у меня датчики не ищутся...ну вообщем не чего не происходит))ткините мея носом есле не сложно что я нетак делаю))юарты все заняты так что эмуляция их отпадает))тоесть закоментил как указано выше) пин изменил на 7 ...и тишина

    ОтветитьУдалить
  4. может это звучит нагло)) но всётаки попрошу используется ATMEGA 128 порт В7 тоесть один пин и именно этот если не трудно подскажите дефайны

    ОтветитьУдалить
  5. а про порт не забыли? что именно вы закомментировали в исходнике?

    ОтветитьУдалить
  6. // Если для эмуляции шины используется USART
    //#define UART_AS_OneWire

    // Если для эмуляции 1-wire не спольльзуется USART, но используется 2 пина (вход и выход)
    //#define OW_TWO_PINS

    #ifdef UART_AS_OneWire
    #define USART_BAUDRATE_57600 (((F_CPU / (57600 * 16UL))) - 1)
    #define USART_BAUDRATE_115200 (((F_CPU / (115200 * 16UL))) - 1)
    #define USART_BAUDRATE_9600 (((F_CPU / (9600 * 16UL))) - 1)
    #else
    #include
    #define OW_DDR DDRB
    #define OW_PORT PORTB
    #define OW_PIN PINB
    #ifndef OW_TWO_PINS //если используется один пин, укажите его номер
    #define OW_BIT 7
    #else // если используются 2 пина, укажите их номера
    #define OW_BIT_OUT 1
    #define OW_BIT_IN 0
    #endif
    #endif
    я сделал так..... подскажите плиз..,с уважением)

    ОтветитьУдалить
  7. все правильно.
    А как вы проверяете?

    ОтветитьУдалить
  8. в main.c покачто добавил

    timerDelayInit();
    nDevices = search_ow_devices(); // ищем все устройства
    и в протеусе смотрю ммм..ну вообщем буферы в которых должны быть ром коды,а так же попробовал посмотреть активность ослогрофом на pin 7 port B и в общем не чего не там не там,таймер 0 более не где не использован avr studio 4.18

    ОтветитьУдалить
  9. здесь таймер 0 не нужен вообще.
    Если вы правильно задали частоту, то это глюки протекса

    ОтветитьУдалить
  10. тоесть строку timerDelayInit(); закоментить или удалить а частота задана в свойсвах проекта 8 мгц я правильно вас понял?

    ОтветитьУдалить
  11. мне очень не удобно вас отвлекать но может комуто еще пригодится,а может гдето как то еще инициализировать порт к которому подключены датчики

    ОтветитьУдалить
  12. скиньте полностью ваш проект

    ОтветитьУдалить
  13. ммм а каким образом это сделать я может плохо искал но не нашёл ваших координатов

    ОтветитьУдалить
  14. тоесть вот на эту почту?admin@kibermaster.net

    ОтветитьУдалить
  15. Большое спасибо всё работает! проблема была в оптимизации

    ОтветитьУдалить
  16. Доброго дня, можно вопрос - как в протеусе Вы проверяете
    работу по двум пинам?

    ОтветитьУдалить
  17. отбой вопроса сори посмотрел вложенный архив, недавно обновили! "Доброго дня, можно вопрос — как в протеусе Вы проверяете
    работу по двум пинам?"

    ОтветитьУдалить
  18. в шпротеусе вообще есть замчательная вещь!! и2с дебуггер))

    ОтветитьУдалить
  19. Что-то как-то не то... Прикладываю ключ от домофона Метаком универсальный, читает и показывает нормально (01 FF FF FF FF FF FF 2F). А вот если я прикладываю другие ключики от домофона, то показывает множество устройств и код из семи FF и CRC, то же самое будет, если закоротить на землю вход. В чем может быть причина?

    ОтветитьУдалить
  20. Наверно, им нужно паразитное питание, а эта прошивка его не обеспечивает.

    ОтветитьУдалить
  21. Пробовал подключать и 3 и 4 способами, один и несколько датчиков ds18b20, всегда находит 0 устройств (((.
    Питание не паразитное.
    Код пишу и компилирую в Atmel Studio 6.
    Подскажите пожалуйста где может быть ошибка.

    ОтветитьУдалить
  22. а прошивку настраивали для конкретного способа?

    ОтветитьУдалить
  23. Да, настраивал. Может из-за того что меня ATMega16A и библиотека просто не знает этого микроконтроллера?

    ОтветитьУдалить
  24. это обычная атмега16

    ОтветитьУдалить
  25. Огромнейшее спасибо автору за чудо-библиотеку.
    Применил к своему устройству - работает на ура, но все-таки нашел глюк в конвертировании температуры. В файле ds18x20.c написал так:
    themp[2] = data[0]&0xf;
    themp[2] *= 0.625;//дробная часть будет от 0 до 9
    if (data[1]>0xFB){
    themp[2] = 10-themp[2];//при минусовой тоже глюк
    themp[1] = 127-themp[1];
    themp[0] = '-';

    ОтветитьУдалить
  26. Алексей Новак17 ноября 2012 г. в 11:07

    Проблема так же как и у zoomerland
    Настроил под Atmel Studio 6, себе вставил только поиск устройств. При компиляции в протеусе пин даже не дёргается. Всегда найдено 0 устройств. Железо будет готов через неделю-полторы, поэтому пока проверяю только в протеусе.
    Может есть какой-то нюанс совместимости кода.

    ОтветитьУдалить
  27. если скомпилировалось без ошибок, то вообще то, должно работать. Возможно, вы схему в протеусе не правильно собрали? Попробуйте с одним устройством на шине

    ОтветитьУдалить
  28. Не работало сначало в Avre 5. долго мучался пока не разобрался с delay.h . очень чувствительна к задержкам.

    ОтветитьУдалить
  29. Алексей Новак19 ноября 2012 г. в 02:08

    Компилируется без ошибок и предупреждений.
    Есть только лог.0 длительностью 60мкс. и всё. Он при каждой попытке найти устройства.
    Как delay.h завязан на формировании задержек? У меня подключён стандартный delay.h и указана частота 8МГц. Ну в протеусе соответственно указано что контроллер тактируется от 8МГц.

    ОтветитьУдалить
  30. получается, что ведущий формирует ресет (устанавливает 0 на 60 мкс), но термодатчик не отвечает, значит проблемы в нем

    ОтветитьУдалить
  31. Скачал архив, сразу же запустил в Proteus'е. РАБОТАЕТ!!!
    Открыл проект в AVR Studio 4 и, не меняя код, скомпилировал. Возвращаюсь в Proteus -- "Найдено 0 устройств". Что я сделал не так?)

    ОтветитьУдалить
  32. а что используется в качестве компилятора? Winavr или тулчейн?

    ОтветитьУдалить
  33. ЗАРАБОТАЛО!!! :)

    Решение:
    - снёс Toolchain
    - скачал свежую версию с офф.сайта
    - установил

    ОтветитьУдалить
  34. Я попытался перенести ваш код на at90usb162, однако как я понял там нет U2X. Возможно ли переделать Ваш код чтобы он заработал на этом камне?

    ОтветитьУдалить
  35. по-мойму, у этого МК нужно указывать U2X0.
    PS: несколько лет назад работал и ним, проблем там было много, советую применить другой МК

    ОтветитьУдалить
  36. К сожалению такого регистра там нет.

    ОтветитьУдалить
  37. лучше возьмите другой мк)) Кстати, at90usb162 не поддерживался WinAVR и хз, поддерживается ли сейчас тулчейном

    ОтветитьУдалить
  38. да оно и у меня компилилось, только не работало, даже мигание светодиодом

    ОтветитьУдалить
  39. Здравствуйте. Скажите пожалуйста, "Так же, если используете эмуляцию 1-wire через USART, то обязательно устанавливайте не только DDR пина TX, а и PORT, иначе обмен на шине будет запускаться максимум в 30% случаев." - в каком месте это делается?
    Если здесь:
    #ifdef UART_AS_OneWire
    #define USART_BAUDRATE_57600 (((F_CPU / (57600 * 16UL))) - 1)
    #define USART_BAUDRATE_115200 (((F_CPU / (115200 * 16UL))) - 1)
    #define USART_BAUDRATE_9600 (((F_CPU / (9600 * 16UL))) - 1)
    #else
    #include
    #define OW_DDR DDRD
    #define OW_PORT PORTD
    #define OW_PIN PIND
    #ifndef OW_TWO_PINS
    #define OW_BIT 1
    #else
    #define OW_BIT_OUT 1
    #define OW_BIT_IN 0
    #endif
    #endif
    то то, что касается пинов в случае использования USART не используется же...
    Ни как не удается запустить (

    ОтветитьУдалить
  40. Здесь: DDRD = 0b00000010; PORTD = 0b00000000;

    ОтветитьУдалить
  41. Увы, не помогло =( Здесь
    char DS18x20_StartMeasure(void)
    {
    //Reset, skip ROM and start temperature conversion
    if (!OW_Reset()) return 0;
    функция сброса возвращает ноль, хотя и сам датчик и усилятор на мосфетах работают - проверено на USB-UART адаптере. Да и на анализаторе видно, что МК формирует сброс, датчик присутствие обозначает.

    ОтветитьУдалить
  42. Покажите код инициализации и укажите МК и частоту

    ОтветитьУдалить
  43. В main`е так:
    #define XTAL 8000000L
    #define baudrate 9600L
    #define bauddivider (XTAL/(16*baudrate)-1)
    #define HI(x) ((x)>>8)
    #define LO(x) ((x)& 0xFF)

    UBRRL = LO(bauddivider);
    UBRRH = HI(bauddivider);

    UCSRA = 0;
    UCSRB = 1<<TXEN;
    UCSRC = 1<<URSEL|1<<UCSZ0|1<<UCSZ1;
    Частота, соответственно 8 МГц, atmega16.

    ОтветитьУдалить
  44. а инит ножек МК? Кстати, каким способом подключен 1-wire?

    ОтветитьУдалить
  45. Ножки - как вы и подсказали, сразу за uart`ом - DDRD = 0b00000010; PORTD = 0b00000010; (при PORTD = 0b00000000 картина та же) Подключил по схеме с полевиками, по трем проводам, только BSS138 использовал.

    ОтветитьУдалить
  46. подключите по второй схеме (переделывать не много) и добейтесь стабильной работы. Советую для этого использовать код из статьи

    ОтветитьУдалить
  47. Увы, все варианты пробовал, видно не судьба. Буду свой вариант пилить, спасибо за то, что ответили! =)

    ОтветитьУдалить
  48. Здравствуйте. Помогите пожалуйста разобраться. Собрал проект в Winavr, используется один пин, 8 мгц, запустил на atmega8 - работает как положено. Но мне нужно это все запустить на atmega88, я пересобрал для это мк, подключил к соответствующему пину - устройств не находит, в процедуре OW_Reset переменная status получает значение 0x08, а должен быть, как я понял, ноль. Где может крыться проблема? Спасибо!

    ОтветитьУдалить
  49. а какие регистры поменяли?

    ОтветитьУдалить
  50. Сейчас сконфигурировано так:

    //#define UART_AS_OneWire
    //#define OW_TWO_PINS

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

    DDRB = 0b00000000; PORTB = 0b00000000;
    DDRC = 0b00000000; PORTC = 0b00000000;
    DDRD = 0b00000000; PORTD = 0b00000000;

    Я где-то что-то упустил?

    ОтветитьУдалить
  51. а подключение по какой схеме?

    ОтветитьУдалить
  52. По третьему способу, только к пину PB3, два датчика DS18B20, на atmega8 все отлично работает, меняю в Makefile на atmega88, в протеусе меняю мк, ставлю частоту, подключаю так же - не работают. Где-то что-то не правильно делаю?

    ОтветитьУдалить
  53. Если не ошибаюсь, то в 88 есть фьюз, который делит частоту на 8 и по умолчанию он включен

    ОтветитьУдалить
  54. Спасибо, не внимательность... Скажите, а можно это все запустить на 1 Мгц ?

    ОтветитьУдалить
  55. можно, только смысла не вижу.

    ОтветитьУдалить
  56. У меня есть проект, который работает на 1 Мгц, хотелось бы этот код туда добавить. Там сейчас есть работа по 1-wire, но только с одним устройством. Это очень сложно? UART мне не нужен

    ОтветитьУдалить
  57. попробуй, должно работать

    ОтветитьУдалить
  58. Если ставлю в Makefile F_CPU = 1000000, компилирую, в мк ставлю деление на 8, данных не получаю, сейчас попробую сравнить дебагом..

    ОтветитьУдалить
  59. Срабатывает тут
    if( diff == OW_DATA_ERR ) break;

    ОтветитьУдалить
  60. думаю, что из-за такой малой частоты не корректно работают микросекундные задержки. Сделай через UART

    ОтветитьУдалить
  61. В проекте, в который я хочу добавить этот код, UART уже занят, там много чего занято. А почему задержки могут не корректно работать? ведь util/delay.h работает в зависимости от F_CPU . Спасибо.

    ОтветитьУдалить
  62. как раз он работает зависимо от F_CPU. При такой малой частоте мк просто не успевает сделать задержку.

    ОтветитьУдалить
  63. Скажите пожалуйста, как быть с atmega64 при работе через USART? У него в регистре UCSRnC нету бита URSEL. Спасибо.

    ОтветитьУдалить
  64. а где, собственно, вы увидели использование бита URSEL?

    ОтветитьУдалить
  65. void USART_init()
    {
    // Set baud rate
    UBRRH = 0;
    UBRRL = 51;
    UCSRA = 0;
    // Enable receiver and transmitter
    UCSRB = (1<<TXEN);
    // Set frame format
    UCSRC = (1<<UCSZ1) | (1<<UCSZ0) | (1<<URSEL);
    }

    ОтветитьУдалить
  66. Если используете USART в качестве 1wire, то это функция вовсе не нужна

    ОтветитьУдалить
  67. Спасибо, убрал, запустил на Atmega64, через USART0, способ 2, 8 Мгц. Добавил проверку в цикл. Порты сконфигурированы так: DDRF = 0b00000010; PORTF = 0b00000000; Оставил два датчика температуры DS18B20. Тестирую в Протеусе. Через некоторое, всегда разное, время программа виснет на строке while(!CheckBit(UCSR0A, RXC)); в процедуре OW_ReadBit, а в протеусе, в этов время, иногда падает ошибка (AVR USART 0) RX Frame Error. В чем может быть проблема? Еще раз спасибо.

    ОтветитьУдалить
  68. такое случается когда датчик не отвечает. Попробуйте на реальном устройстве

    ОтветитьУдалить
  69. Иногда виснет на while(!CheckBit(UCSR0A, RXC)) OthersTasks(); в процедуре OW_WriteBit без ошибок в протеусе. С чем это может быть связано?

    ОтветитьУдалить
  70. я сказать не могу, так как нужно протестировать на реальном устройстве. Попробуйте еще отключить сторожевой таймер

    ОтветитьУдалить
  71. Подскажите, надо ли делать какой-то сброс состояния датчика после измерения? Вычитываю данные ds18b20 в цикле и с большой долей вероятности через раз в data[0] находится 0xff. Пауза 1с в цикле не помогла.

    Еще интересует почему на схеме в протеусе используются два пина PB0 и PB1 в статье только PB0? Дело в том что на одном пине у меня не завелся датчик, а на двух и с OW_TWO_PINS завелся, но пока что с проблемами (см выше).

    ОтветитьУдалить
  72. На схемах изображено несколько вариантов подключения, в протеусе - один с них (не помню какой).
    Советую вам использовать код из этой статьи, если заведется, то переносите его в ваш проект.
    А эта пауза 1с у вас между запуском измерения и считыванием данных?

    ОтветитьУдалить
  73. Код точно такой же, за исключением за исключением датчика, подключен у другому порту, поэтому в openwire.h поставил
    #define OW_DDR DDRC
    #define OW_PORT PORTC
    #define OW_PIN PINC

    1с это пауза перед следующим измерением (в конце бесконечного цикла), а между запуском и считыванием как и в статье 800мс.

    ОтветитьУдалить
  74. а каким из вышеперечисленных способов подключен 1wire?

    ОтветитьУдалить
  75. Вот так
    http://imageshack.us/a/img27/6406/lsst.png

    Если использовать классическую схему с одним проводом и резистор 4К7 на "+", то датчик не находится (#define OW_TWO_PINS комментировал).

    В протеусе только в самом начале проскакивает 0xff.

    ОтветитьУдалить
  76. Такс, а частота мк у вас какая?
    OW_BIT_OUT и OW_BIT_IN указаны?

    ОтветитьУдалить
  77. F_CPU = 8000000
    В SinaProg выставил Fuses: Int. 8MHz

    #define OW_TWO_PINS

    #define OW_DDR DDRC
    #define OW_PORT PORTC
    #define OW_PIN PINC

    #define OW_BIT_OUT 1
    #define OW_BIT_IN 0

    ОтветитьУдалить
  78. а в самом протеусе в настройках мк установили частоту 8мгц?

    ОтветитьУдалить
  79. Да, (0100) Int. RC 8MHz
    На всякий случай вот тут весь проект : http://yadi.sk/d/2d5P-zz28zMXV

    ОтветитьУдалить
  80. Вроде все правильно. Попробуйте DS18x20_StartMeasureAddressed(owDevicesIDs[i]); заменить на DS18x20_StartMeasure();
    Я спать, если что, завтра отвечу.

    ОтветитьУдалить
  81. В общем ситуация с DS18x20_StartMeasure() не изменилась.
    Попробую еще раз пересмотреть схему, возможно что-то упустил. Если не получится - придется использовать в качестве датчика температуры термистор :)
    В любом случае спасибо большое за помощь!

    ОтветитьУдалить
  82. Вроде победил, проблема была в использовании прерываний для динамической индикации (о чем собственно и написано в статье.)
    Решилось вешаньем датчика на USART. По крайней мере теперь в протеусе нет глюков. Осталось проверить на макете.
    Еще раз спасибо!

    ОтветитьУдалить
  83. Здравствуйте, искал адекватную библиотеку для работы по 1-wire, ваша понравилась очень, но запустить никак не выходит. Работаю сразу в железе.
    Инициализация:
    // Максимальное количество устройств на шине
    #define MAXDEVICES 8

    // Если для эмуляции шины используется USART
    //#define UART_AS_OneWire

    // Если для эмуляции 1-wire не спольльзуется USART, но используется 2 пина (вход и выход)
    //#define OW_TWO_PINS

    #ifdef UART_AS_OneWire
    #define USART_BAUDRATE_57600 (((F_CPU / (57600 * 16UL))) - 1)
    #define USART_BAUDRATE_115200 (((F_CPU / (115200 * 16UL))) - 1)
    #define USART_BAUDRATE_9600 (((F_CPU / (9600 * 16UL))) - 1)
    #else
    #include
    #define OW_DDR DDRA
    #define OW_PORT PORTA
    #define OW_PIN PINA
    #ifndef OW_TWO_PINS //если используется один пин, укажите его номер
    #define OW_BIT 0
    #else // если используются 2 пина, укажите их номера
    #define OW_BIT_OUT
    #define OW_BIT_IN
    #endif
    #endif

    частота проинициализирована как #define F_CPU 8000000UL

    Ссылка на архив с проектом: https://dl.dropboxusercontent.com/u/34620857/MQ.rar
    Заранее спасибо!

    ОтветитьУдалить
  84. Не находит устройства, хотя на шину повесил 3 штуки, на осцилографе на шине меандр, низкий уровень - 60 мкс, высокий - 580 мкс, по коду проследить не удалось причину этого явления, вроде все правильно

    ОтветитьУдалить
  85. Решил проблему. у меня 6.1 студия и для адекватной работы нужно было сделать глобальный дефайн опорной частоты процессора, иначе onewire либа думала что частота 1мгц.

    ОтветитьУдалить
  86. void DS18x20_ConvertToThemperature(unsigned char* data, unsigned char* themp)
    {
    unsigned int tmp = 0;
    if ((data[0]==0x00)&&(data[1]==0x00)){
    themp[0] = ' ';
    }
    else if(data[1]>0xFB){
    themp[0] = '-';
    tmp = ((unsigned int)data[1]<>8;
    }
    else themp[0] = '+';
    //Store temperature integer digits and decimal digits
    themp[1] = ((data[1]&7)<>4);
    //Store decimal digits
    themp[2] = (data[0]&15);
    themp[2] = (themp[2]<<1) + (themp[2]<>4);
    }
    подправил,при минусовых значениях разница в 1 была

    ОтветитьУдалить
  87. void DS18x20_ConvertToThemperature(unsigned char* data, unsigned char* themp)
    {
    unsigned int tmp = 0;
    if ((data[0]==0x00)&&(data[1]==0x00)){
    themp[0] = ' ';
    }
    else if(data[1]>0xFB){
    themp[0] = '-';
    tmp = ((unsigned int)data[1]<>8;
    }
    else themp[0] = '+';
    //Store temperature integer digits and decimal digits
    themp[1] = ((data[1]&7)<>4);
    //Store decimal digits
    themp[2] = (data[0]&15);
    themp[2] = (themp[2]<<1) + (themp[2]<>4);
    }

    ОтветитьУдалить
  88. чет херня с отображением=)

    ОтветитьУдалить
  89. Подскажите пожалуйста, использую Вашу библиотеку через USART, работает все довольно стабильно и хорошо. Теперь возник вопрос, подключения питания к датчику не отдельным проводом +5В,а брать питание от линии данных, как это возможно реализовать?
    Спасибо.

    ОтветитьУдалить
  90. Может возможно после передачи запроса на запуск измерения подтягивать 1 на ножку, чтобы по линии данных шли 5В, а по достижению 750мс читать?

    ОтветитьУдалить
  91. насколько помню, так и нужно делать, посмотрите в даташите.

    ОтветитьУдалить
  92. да, но сама библиотека будет работать? Т.е используя USART я могу после подачи запроса на измерение перевести ногу (RX) в 1 (как в даташите написанно не познее чем 10мс), подождать 750мс, перевести обратно и читать данные?

    ОтветитьУдалить
  93. нужно просто передавать ноли в порт.

    ОтветитьУдалить
  94. можно пожалуйста поподробнее?
    Пробовал проверить работу в протеус, но незнаю там как не подключи они читаются, даже если Vss и GND не подключать.

    ОтветитьУдалить
  95. для того, чтобы питать устройство через DQ, нужно чтобы он был постоянно в высоком уровне, для этого нужно посылать OW_WriteByte(0xFF).

    ОтветитьУдалить
  96. Как часто посылать? А не легче просто поставить на время задержи по измерению темп порт в 1, чем посылать постоянно OW_WriteByte(0xFF).
    Спасибо

    ОтветитьУдалить
  97. Смотрю в протеусе, у меня и так выходит что после получения и всех монипуляций, все время на DQ подается 5в, ну т.е порт в 1 стоит.

    ОтветитьУдалить
  98. можно, но для этого нужно отключить usart

    ОтветитьУдалить
  99. Ага, а если будем слать команду постоянно OW_WriteByte(0xFF), как часто ее слать?
    Подскажите, для чего именно OW_WriteByte(0xFF).

    Спасибо

    ОтветитьУдалить
  100. постоянно слать, пока идет измерение. Для чего она, писал выше

    ОтветитьУдалить
  101. Ага, понял. Будем слать. А не подскажите еще пожалуйста, как в протеусе можно проверить работу через паразитное питание? то при отключении GND и Vss всеравно все работает, они как я понял питаются через скрытое питание как на МК например.

    ОтветитьУдалить
  102. наверно, никак, можете разве что в ноге DQ подключить осциллограф и посмотреть, есть ли высокий уровень во время измерения.

    ОтветитьУдалить
  103. Спасибо. Пока попробовать в живую нет возможности, нахожусь не дома, а вот протеус и его осциллограф показывает что после получения и отправки команд, нога находиться в 1, и поступает 4,999вольта

    ОтветитьУдалить
  104. тогда должно работать

    ОтветитьУдалить
  105. с отображением кода на сайте, не знаю почему)

    ОтветитьУдалить
  106. Какие файлы нужно добавить в свой проект (Atmel studio 6) для использования библиотеки. Какими функциями пользоваться?

    ОтветитьУдалить
  107. есть библиотека для работы с DS2413?
    какие вообще у вас есть библиотеки по даласу кроме DS18x20?

    ОтветитьУдалить
  108. Скажите как обрабатывать данные с двух датчиков DS18B20 подключенных к одной шине?

    ОтветитьУдалить
  109. Здравствуйте!Возникает странная проблема,при подключении микроконтроллера к компу с помощью преобразователя FT232 и открытии порта из значимых данных приходит только серийный номер,а вместо значения температуры символ '?'.Тестил только на железе,МК AtMega32.Такая же история наблюдалась с датчиком SHT75,но с другой программой.Помогите,пожалуйста,разобраться,в чем может быть проблема такого поведения.

    ОтветитьУдалить
  110. Попробовать другой преобразователь. Я вообще FT232 не применяю из-за его глюков, вместо него применяю CP2102

    ОтветитьУдалить
  111. Он у меня на PinBoard-e стоит,в будущем буду пускать через ENC28J60 сигнал от датчиков по сети,пока хотел отладить по uart-у,попроще думал будет.Спасибо за ответ,попробую сразу через сеть,т.к. cp2102 в наличии нет,а enc уже на плате и работает(тестил udp),может так что путное выйдет!

    ОтветитьУдалить
  112. Для начала хочу сказать спасибо за лаконичную и функциональную библиотеку, аналоги этими качествами не блещут =)

    У меня небольшая проблема:
    в протеусе UART-режим работает крайне нестабильно, при поиске устройств на шине с двумя датчиками часто либо зависает ( while(!CheckBit(UCSRA, T/RXC)) ), либо не находит ни одного (OW_DATA_ERR), либо находит один. Иногда срабатывает как надо. В софтварном режиме всё работает отлично. У вас случаем нет мыслей по поводу того, в чём может быть затык?

    Заранее признаетелен.

    ОтветитьУдалить
  113. поторопился я с выводами, в софтварном режиме тоже нестабильно :( не виснет, но находит от нуля о двух

    ОтветитьУдалить
  114. я тебе больше скажу. в железе оно тоже не хило так сбоит )

    ОтветитьУдалить
  115. А версия протеуса какая? И как вы проверяли в UART режиме?

    ОтветитьУдалить
  116. Аналогичная проблема, в Proteus 7.10 SP0, в режиме UART виснет на ( while(!CheckBit(UCSRA, RXC)) ), в обычном режиме нормально, иногда проскакивают ошибочные значения. На железе через UART пока не проверял.

    ОтветитьУдалить
  117. Как Вы проверяете в протеусе?

    ОтветитьУдалить
  118. http://www.evernote.com/l/AHO6M3KFQ_1KhYXaz40udSEhcxne_J9hXdQ/

    Меняю температуру на датчиках, слежу за изменениями до тех пор пока они не перестанут обновляться

    ОтветитьУдалить
  119. Получается, глюк протеуста, так как у меня нормально работает.
    В реальном устройстве я ставлю резистор не 4,7, а 2,2К. А если использую подключение через транзисторы, как в первом варианте, то вместо 4,7К ставлю 1,5К. У меня так работает не меньше сотни устройств.

    ОтветитьУдалить
  120. Проверил на железе через UARТ, вроде всё отлично!

    ОтветитьУдалить
  121. Взял последний код из прикрепленного архива, у меня почему-то первое значение считывается 85, а потом правильное. С обоих датчиков.

    ОтветитьУдалить
  122. Если использовать _delay_ms вместо timerDelayMs все нормально, для чего был добавлен timerDelayMs?

    ОтветитьУдалить
  123. 85 - это значение темепратуры при инициализации. Тоесть, если подать питание и считать, не запустив измерение, будет получено 85

    ОтветитьУдалить
  124. Для задержки с помощью таймера, чтобы во время задержки можно было что то делать.

    ОтветитьУдалить
  125. Мне не понятно почему оно считывается в таком случае

    // работа с устройствами 1-wire
    void sensors(void){

    timerDelayInit();
    nDevices = search_ow_devices(); // ищем все устройства

    for (unsigned char i=0; i<nDevices; i++){ // теперь сортируем устройства и запрашиваем данные
    // узнать устройство можно по его групповому коду, который расположен в первом байте адресса
    switch (owDevicesIDs[i][0]){
    case OW_DS18B20_FAMILY_CODE: { // если найден термодатчик DS18B20
    DS18x20_StartMeasure(owDevicesIDs[i]); // запускаем измерение
    timerDelayMs(800); // ждем минимум 750 мс, пока конвертируется температура
    // _delay_ms(800);
    unsigned char data[2]; // переменная для хранения старшего и младшего байта данных
    DS18x20_ReadData(owDevicesIDs[i], data); // считываем данные
    float themperature = DS18x20_ConvertToThemperatureFl(data); // преобразовываем температуру в человекопонятный вид
    temper[0+i]=themperature;
    break;
    }
    }
    }
    }

    а если использовать _delay_ms(800); вместо timerDelayMs(800); и timerDelayInit(); все нормально

    Не судите строго, я новичок)

    ОтветитьУдалить
  126. понял, потому, что timerDelayMs не работает у меня

    ОтветитьУдалить
  127. У меня еще один вопрос, как выполнить быстрое прерывание цикла с запуском процедуры считывания температуры. Я разрешаю прерывание по кнопке, но оно срабатывает с третьего раза.

    ОтветитьУдалить
  128. Этого лучше не делать, так как считывание занимает довольно продолжительное время.

    ОтветитьУдалить
  129. Но считывание температуры не главная функция моего устройства, должен ведь быть способ прервать цикл, пусть даже один раз и считается не верное значение.

    ОтветитьУдалить
  130. Или лучше делать 1-wire на отдельном МК и связать их по какому-либо протоколу?

    ОтветитьУдалить
  131. Подскажите пожалуйста как лучше сделать.

    ОтветитьУдалить
  132. Тоже Proteus 7.10 SP0. Проверить не получается нормально, ибо инициализация проходит раз из пяти.

    ОтветитьУдалить
  133. Почему нельзя постоянно измерять температуру? Запускаешь измерение, затем 750 мсек тупишь в цикле, выполняя остальные задачи, потом читаешь измерения и так по кругу. Моментально получить текущее реальное значение температуры все равно не получится из-за температурной инертности датчика (если ты его греешь не газовой горелкой).

    ОтветитьУдалить
  134. Ребят, не знаю, что у вас там сбоит, но у меня работает нормально. Правда, я всегда использую подключение через 2 транзистора и резистор на 1,5К.

    ОтветитьУдалить
  135. Доброго Здоровья!

    Kibermaster!
    Если дляВас не сильно обременительно, не могли-бы Вы пересобрать пример с использованием AVR Studio 4.19 с задействованным вариантом работы с 1Ware по USART?

    ОтветитьУдалить
  136. А что если вы сами это сделаете?

    ОтветитьУдалить
  137. Дело в том, что я пишу в среде Bascom, с "Си" не знаком абсолютно. Единственное, что стоит, так это AVR Studio 4.19, да и то, только, как программатор.

    Прошу прощения за безпокойство, уже не надо. Написал реализацию работы сам, согласно документации "#AN124 (Using a UART to Implement a 1-Wire Bus Master)".

    Если Вас не сильно затруднит, алгоритм поиска ID устройств больше 1? Что-то этот момент никак не хочет поддаваться. Принимаю всё время "1", хотя в то-же время, поиск и чтение одного устройства, работает без проблем.

    ОтветитьУдалить
  138. Вопрос может показаться глупым, но прошу простить, я начинающий.
    DS18x20_ReadData(owDevicesIDs[i], data); // считываем данные
    float t = DS18x20_ConvertToThemperatureFl(data); // преобразовываем температуру в человекопонятный вид
    printf(": %3.2f C", t);
    Если не ошибся, переменная t и есть значение температуры. Это значение нужно вывести на LCD дисплей с помощью функции lcd_string(0x93, ); Как это можно осуществить?

    ОтветитьУдалить
  139. Вместо последней строки:
    char str[20];
    sprintf(str, "t = %3.2f C", t);
    lcd_string(0x93, str);

    ОтветитьУдалить
  140. Спасибо! Правильно понял, что это перевод из float в char? Правда на дисплей все-равно не выводится, черные квадраты вместо значений (остальные слова и символы выводятся нормально).

    ОтветитьУдалить
  141. это переводит число в строку, почему на дисплее не видно - смотрите функцию lcd_string

    ОтветитьУдалить
  142. Перевел Вашу библиотеку в CodeVisionAVR. Эмуляция USARTом. Схема 2. Запуск измерения DS18x20_StartMeasure, программная задержка 750 мс - тогда работает. Если запуск измерения делаю по прерыванию INT1 (запуск от внешнего таймера 1Гц) - перестает работать. Другие функции в прерывании тоже перестают обрабатываться. Идея - раз в секунду запускать измерение (не надо ждать 750 мс, пока конвертируется температура), а потом вывод на LCD. Подкажите, пожалуйста, в чем может быть дело.

    ОтветитьУдалить
  143. В функции запуска измерения есть цикл while, для ожидания приема данных, поэтому использовать функцию в прерывании нельзя

    ОтветитьУдалить
  144. Замечательная библиотека, отлично работает. Но подключил датчик DS18B20 с паразитным питанием и не работает. Пробовал ардуиновскую бибилиотеку, работает. Что нужно поменять в библиотеке?

    ОтветитьУдалить
  145. Во время измерения надо отправлять датчику положительный уровень на линии, чтобы ему было от чего питаться.

    ОтветитьУдалить
  146. Добрый день. Большое спасибо вам за библиотеку.

    У меня такая проблема при подключении.

    Подключаюсь методом 3 (одна ножка МК работает в качестве и входа, и выхода). Питание не паразитное. Найдено 1 устройство, как и ожидалось, но вот вместо температуры возвращается пустое значение:

    ---------- Found 1 devices ----------
    28 61 4A AB 06 00 00 52 - Thermometer DS18B20: ? C


    Можете ли подсказать, в чем может быть причина?
    Спасибо.

    ОтветитьУдалить
  147. Поправка. Возвращается не пустое значение. Сделал вывод первых 2х байтов, вот что получилось:

    28 FF C5 1B A3 15 03 F7 - Thermometer DS18B20: data[0]: cd, data[1]: 1
    28 FF C5 1B A3 15 03 F7 - Thermometer DS18B20: data[0]: cd, data[1]: 1
    28 FF C5 1B A3 15 03 F7 - Thermometer DS18B20: data[0]: cc, data[1]: 1
    28 FF C5 1B A3 15 03 F7 - Thermometer DS18B20: data[0]: cc, data[1]: 1
    28 FF C5 1B A3 15 03 F7 - Thermometer DS18B20: data[0]: cc, data[1]: 1

    ОтветитьУдалить
  148. Проблема решена. Причина в printf. См. http://www.avrfreaks.net/forum/problems-float-printf-solved

    ОтветитьУдалить
  149. В функции search_ow_devices выполняем поиск устройств пока diff != OW_LAST_DEVICE && sensors_count < MAXDEVICES. При этом OW_LAST_DEVICE всегда = 0, соответственно и вся правая часть всегда = 0? Я правильно понял?
    Проблема - находит только одно устройство...

    ОтветитьУдалить
  150. Как я понимаю, если 0, значит нового устройства не найдено.

    ОтветитьУдалить
  151. Так в чем смысл такого кода?

    ОтветитьУдалить
  152. Почитайте доку на DS18B20, многое станет ясно)))
    PS: есть на русском.

    ОтветитьУдалить
  153. Читал, и не раз. И на разных языках..
    Хочется понять этот код. Он несколько шире чем DS18B20.

    ОтветитьУдалить
  154. А Вы за основу что брали? Какой AppNote?

    ОтветитьУдалить
  155. Это было лет 5 назад, я уже не помню))).
    Данный код использую во всех твоих разработках, где есть OW, там поиск всегда происходил без сбоев со стороны программной части

    ОтветитьУдалить
  156. Через USART у меня тоже все работает. Теперь пробую через DS2482-100. Возникли проблемы, стал подробно изучать код. Появились дополнительные вопросы. Сами как думаете, какая идея заложена в diff != OW_LAST_DEVICE && sensors_count < MAXDEVICES ?

    ОтветитьУдалить
  157. sensors_count < MAXDEVICES думаю, понятно))).
    diff != OW_LAST_DEVICE нужен для обнаружения последнего найденного устройства.

    ОтветитьУдалить
  158. Совершенно бы согласился. Но OW_LAST_DEVICE константа...

    ОтветитьУдалить
  159. Я в курсе, и если diff равно 0 (этой константе), то новых устройств не обнаружено и цикл завершается

    ОтветитьУдалить
  160. Тогда условие цикла сокращается до diff != 0.
    diff - номер бита последнего несоответствия (от 64 до 1). Ниже 2, а тем более = 0, diff как бы и не может... И цикл получается бесконечным. Но на деле он завершатся. Как не пойму.

    ОтветитьУдалить
  161. Подскажите почему при компиляции Вашего проекта все нормально работает, но переношу Ваш код к себе в проект ругается на delay.c не определен F_CPU, в этом файле пишу F_CPU 8000000UL компилируется но не работает пишет foud 0 device в консоле протеуса? Может где то нужно глобально объявить я новичек подскажите пожалуйста?

    ОтветитьУдалить
  162. F_CPU надо определить в настройках проекта

    ОтветитьУдалить
  163. Здравствуйте! Не могу вывести доли градусов на семисегментный индикатор. Целые числа выводятся правильно. Пробовал так: raz4 = ((temp & 0x0F)*625/1000);

    ОтветитьУдалить
  164. Пожалуйста, подскажите формулу?

    ОтветитьУдалить
  165. http://www.codenet.ru/progr/cpp/sprd/modf.php (не пробовал).

    ОтветитьУдалить
  166. У меня atmega32 макетная плата+lcd1602. Нужно прикрутить датчик ds18b20. Пишу на С в Atmel Studio 4. Но как-то все не получается. Очень нужна помощь!!! У кого есть рабочий пример на С??? Что-то я на этом датчике затормозился. Пример куча в интернете, но что-то не как работать их заставить не могу.
    Нужно помощь....

    ОтветитьУдалить
  167. В статье как раз рабочий пример на си)))

    ОтветитьУдалить
  168. Можно по поподробней, это значение взамен owDevicesIDs[i] ?

    ОтветитьУдалить
  169. Здесь хранится id датчиков.

    ОтветитьУдалить
  170. Доброго Здоровья!

    Если Вам не сильно затруднительно, не могли бы Вы пересобрать исходники с USART вариантом работы с Ds18b20.

    Спасибо!

    ОтветитьУдалить
  171. А здесь случайно не ошибка у Вас:
    #ifdef UART_AS_OneWire
    #define USART_BAUDRATE_57600 (((F_CPU / (57600 * 16UL))) - 1)
    #define USART_BAUDRATE_115200 (((F_CPU / (115200 * 16UL))) - 1)
    #define USART_BAUDRATE_9600 (((F_CPU / (9600 * 16UL))) - 1)
    #else
    #include
    #define OW_DDR DDRC
    #define OW_PORT PORTC
    #define OW_PIN PINC
    #ifndef OW_TWO_PINS //если используется один пин, укажите его номер
    #define OW_BIT 0
    #else // если используются 2 пина, укажите их номера
    #define OW_BIT_OUT 1
    #define OW_BIT_IN 0
    #endif
    #endif

    Если задан макрос #define OW_TWO_PINS то мы используем 2 пина, для интерфейса 1-wire, так же,
    а у вас написано:
    #ifndef OW_TWO_PINS //если используется один пин, укажите его номер
    #define OW_BIT 0
    #else // если используются 2 пина, укажите их номера
    #define OW_BIT_OUT 1
    #define OW_BIT_IN 0
    #endif
    то есть если есть макрос #ifndef OW_TWO_PINS то задаётся номер пина контроллера на котором будет 1-wire, а должны задавать если есть этот макрос не один, а два пина, а одни задавать если этого макроса нет.

    Может должно быть вот так:
    #ifndef OW_TWO_PINS //если используется один пин, укажите его номер
    #define OW_BIT_OUT 1
    #define OW_BIT_IN 0
    #else // если используются 2 пина, укажите их номера
    #define OW_BIT 0
    #endif

    ОтветитьУдалить
  172. Великодушно простите, там написано #ifndef всё верно!

    ОтветитьУдалить

Отправить комментарий

Популярные сообщения из этого блога

Прием команд с пульта дистанционного управления

STM32F4. Обновление прошивки с карты памяти (Bootloader SD)