Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: UART->1-Wire
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Veg@
Соединяю ATMega8 с датчиком DS18B20, используя UART. Изучив данный материал (appnote, форум) написал под WinAVR несколько процедур для работы:
Код
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <util/delay.h>
#include "DS18B20.h"

void DS18B20_Reset(void);
void DS18B20_Write0(void);
void DS18B20_Write1(void);
void DS18B20_WriteByte(char cByte);
static unsigned char DS18B20_ReadByte(void);
void USART_vInit(void);
void USART_vSetUBBR(char cUBBRVal,char bDelay);
void USART_vSendByte(char u8Data);
static unsigned char OWByte(unsigned char b);
static unsigned char OWReset(void);

int main(void) {
    USART_vInit();
    DS18B20_Reset();
    DS18B20_WriteByte(0x33);
    unsigned char c1,c2,c3,c4,c5,c6,c7,c8;
    c1=DS18B20_ReadByte();
    c2=DS18B20_ReadByte();
    c3=DS18B20_ReadByte();
    c4=DS18B20_ReadByte();
    c5=DS18B20_ReadByte();
    c6=DS18B20_ReadByte();
    c7=DS18B20_ReadByte();
    c8=DS18B20_ReadByte();
    USART_vSetUBBR(25,1);
    USART_vSendByte(c1);
    USART_vSendByte(c2);
    USART_vSendByte(c3);
    USART_vSendByte(c4);
    USART_vSendByte(c5);
    USART_vSendByte(c6);
    USART_vSendByte(c7);
    USART_vSendByte(c8);
    USART_vSetUBBR(1,1);
    while (1);
    return 0;
}

void DS18B20_Reset(void) {
    USART_vSetUBBR(25,0);
    USART_vSendByte(0xF0);
    _delay_ms(1);
    while (!(UCSRA&(1<<TXC)));
    while (!(UCSRA&(1<<RXC)));
    USART_vSetUBBR(1,1);
}

void DS18B20_Write0(void) {
    USART_vSendByte(0x00);
}

void DS18B20_Write1(void) {
    USART_vSendByte(0xFF);
}

void DS18B20_WriteByte(char cByte) {
    for (char i=0;i<8;i++) {
        if (cByte%2) DS18B20_Write1();
        else DS18B20_Write0();
        cByte=cByte/2;
    }    
    _delay_ms(1);
}

static unsigned char DS18B20_ReadByte(void) {
    unsigned char cByte=0;
    for (char i=0;i<8;i++) {
        UDR=0xFF;    
        UCSRA=(1<<TXC);    
        while(!(UCSRA&(1<<TXC)));
        cByte>>=1;
        if (UDR>0xFE) cByte|=128;
    }    
    return cByte&255;
}

void USART_vInit(void) {
    USART_vSetUBBR(1,0);
    UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);
    UCSRB = (1<<RXEN)|(1<<TXEN);
}

void USART_vSetUBBR(char cUBBRVal,char bDelay) {
    if (bDelay)    {
        _delay_ms(1);
        while (!(UCSRA&(1<<TXC)));
    }
    UBRRH = 0;
    UBRRL = cUBBRVal; // 1-115200, 25-9600
}

void USART_vSendByte(char u8Data) {
    while (!(UCSRA&(1<<UDRE)));
    UDR = u8Data;
}

Сигнал RESET проходит и в ответ приходит 0xE0 - вроде бы как и надо, хотя при подключениии второго устройства приходит тоже самое, что, по идее, противоречит appnote'у.
Проверил датчик на работу с командой 0x33 (чтение адреса устройства), в ответ получил неверный адрес:
__реальный: FC 28 00 00 00 00 00 11 (получен с помощью программной реализации 1-Wire - работает нормально)
__полученный: A2 F0 03 00 00 00 00 44
В чем может быть причина? Выполняется ли неверно чтение данных или до этого команда 0x33 неверно воспринимается датчиком? Спасибо.
Кварц: 4 МГц, резистор(между TXD и RXD (RXD-подключен напрямую к DQ)): 180 Ом.
Rst7
В портянке кода нет желания разбираться, но вот резистор в 180ом - очень мало. Я обычно ставлю 2.2К
Laptop
Вроде все правильно. Времянки в бите порой сильно плавают. У меня аналогичный код работает. Подключайте осциллограф и вперед.
Veg@
Цитата
Вроде все правильно. Времянки в бите порой сильно плавают. У меня аналогичный код работает. Подключайте осциллограф и вперед.

Что значит "плавают" и почему только у меня?
ILYAUL
Цитата(Veg@ @ Nov 29 2009, 01:43) *
Сигнал RESET проходит и в ответ приходит 0xE0 - вроде бы как и надо, хотя при подключениии второго устройства приходит тоже самое, что, по идее, противоречит appnote'у.


Я так понял у Вас два DS18 , но тогда

Чтение ROM [33h] (Read) используется, чтобы прочитать ROM память устройства, если на шине оно только одно. После посылки этой команды Главное устройство должен генерировать 64 слота времени считывания. iButton пошлет содержимое его ROM памяти младшим битом вперед, начиная с кода семейства, сопровождаемого серийным номером и байтом циклического контроля избыточности.
Если на шине несколько iButtons устройств, то для чтения ROM памяти необходимо воспользоваться командой Поиск ROM [F0h] (Search), чтобы определить содержание ROM памяти устройств прежде, чем к ним можно будет обратиться.
Veg@
Цитата
Я так понял у Вас два DS18

Нет
Цитата
Соединяю ATMega8 с датчикОМ...

Только для проверки сигнала RESET я подключил второй датчик.
Veg@
Цитата(Rst7 @ Nov 29 2009, 11:03) *
В портянке кода нет желания разбираться, но вот резистор в 180ом - очень мало. Я обычно ставлю 2.2К

С резистором на 2.2кОм датчик не обнаруживается. Какая у вас длина шины?
Veg@
Еще вопрос: почему в appnote приведена схема подключения сложнее, чем просто соединение резистора между RXD и TXD? Достаточно ли одного резистора?
xemul
Цитата(Veg@ @ Nov 29 2009, 19:37) *
С резистором на 2.2кОм датчик не обнаруживается. Какая у вас длина шины?

Rst7 предположил, что 180 Ом - резистор притяжки.
Если шина наружу не торчит (под iButton), этот резистор можно заменить на перемычку. (а если торчит, то толку от этого резистора 0)
Цитата
Еще вопрос: почему в appnote приведена схема подключения сложнее, чем просто соединение резистора между RXD и TXD? Достаточно ли одного резистора?

Чтобы при случае дохли не контроллеры, а транзисторы. См. выше.

По коду:
_delay_ms(1) в изобилии для надёги?
в приведённом куске откровенных очепяток не видно.

Цитата
или до этого команда 0x33 неверно воспринимается датчиком?

smile.gif внушает. ПрикупИте Maxim при случае.
ILYAUL
Цитата(Veg@ @ Nov 29 2009, 22:35) *
чем просто соединение резистора между RXD и TXD? Достаточно ли одного резистора?

А где Вы нашли такое включение, резистора между RXD и TXD ? Я не нашёл такое вкл ни appnote, ни в DS . Кстати а как Вы питаете датчик
Veg@
Цитата
А где Вы нашли такое включение, резистора между RXD и TXD ?

тут
Цитата
Кстати а как Вы питаете датчик

не паразитно

К вопросу о правильной восприимчивости датчиком команд:
Пробую отправить сначала 0xCC, затем - 0xBE (чтение памяти). Считанные байты всегда приходят одни и те же внезависимости от температуры. С чем все-таки это может быть связано? С программой или "железом"?
xemul
Цитата(Veg@ @ Nov 30 2009, 00:03) *
тут

TxD прямо в шину, RxD, соответственно, через резистор. У Вас, судя по "С резистором на 2.2кОм датчик не обнаруживается", наоборот.
Veg@
Цитата(xemul @ Nov 30 2009, 00:22) *
TxD прямо в шину, RxD, соответственно, через резистор. У Вас, судя по "С резистором на 2.2кОм датчик не обнаруживается", наоборот.

Наоборот, т.к. там написано и во всех аппноутах, что RXD подключается прямо на шину.
Laptop
Цитата(Veg@ @ Nov 30 2009, 00:28) *
Наоборот, т.к. там написано и во всех аппноутах, что RXD подключается прямо на шину.

RXD на шину, TXD через резистор примерно 2-5 кОм. И провода для начала покороче, чтобы не было большой емкости.

P.S. А времянки меняются как раз по причине затягивания фронтов и зависят также от напряжения питания. У далласа ведь нет внутри задающего генератора.
xemul
Цитата(Veg@ @ Nov 30 2009, 00:28) *
Наоборот, т.к. там написано и во всех аппноутах, что RXD подключается прямо на шину.

Цитата(Laptop @ Nov 30 2009, 04:43) *
RXD на шину, TXD через резистор примерно 2-5 кОм. И провода для начала покороче, чтобы не было большой емкости.

Хор поёт про случай без транзисторов по TxD? Тогда вопрос: привязка к +5 5к, с TxD в шину 2.2 к; угадайте напряжение логического нуля в шине от мастера.
Это хорошо, что вы сначала читаете, а потом спрашиваете, но можно попробовать и осмыслить прочитанное.
Цитата
P.S. А времянки меняются как раз по причине затягивания фронтов и зависят также от напряжения питания. У далласа ведь нет внутри задающего генератора.

В далласовских градусниках 3 (три) генератора: один задающий, ещё на двух сделан собственно градусник.
Rst7
Цитата
Хор поёт про случай без транзисторов по TxD? Тогда вопрос: привязка к +5 5к, с TxD в шину 2.2 к; угадайте напряжение логического нуля в шине от мастера.


Разве я говорил про привязку к +5? Никаких дополнительных 5к в +5, ибо резистор в 2.2к и выполняет роль подтягивающего.
xemul
Цитата(Rst7 @ Nov 30 2009, 09:16) *
Разве я говорил про привязку к +5? Никаких дополнительных 5к в +5, ибо резистор в 2.2к и выполняет роль подтягивающего.

Тады ой. Сразу не оценил степень оптимизации.
имхо, при суммарной ёмкости шины 100-150 pF начнутся неоднозначности, т.е. это решение для одного-двух слейвов недалеко от мастера.
Rst7
Цитата
имхо, при суммарной ёмкости шины 100-150 pF начнутся неоднозначности, т.е. это решение для одного-двух слейвов недалеко от мастера.


Нормально работает через бухту UTP длинной под 40 метров. Вообще, ответ на вопрос допустимой емкости легко получить в любом подходящем моделяторе, например, в микрокапе. Да и в любимом многими протеусе - тоже. Хотя, если уж очень стремно, в параллель резистору можно еще подключить диодик, анодом к RXD, катодом к TXD, дабы спад улучшить.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.