Цитата(demiurg_spb @ Nov 7 2010, 12:28)

Прекрасно изложена суть проблемы - без подробностей...
Какая схема включения?
Как инициализируете контроллер?
Как работаете с датчиком?
Как питаете всё хозяйство?
Схема включения очень проста. Питание берется +5В то же что и питание контроллера
на шину данных вешается подтягивающий резистор 4,7 КОм.
Для работы с датчиком использую готовый модуль
Код
#include "iom128.h"
#include "inavr.h"
#include "stdio.h"
#include "stdlib.h"
#include "stdint.h"
#include "string.h"
#include "ds18b20.h"
#include "stdint.h"
#include "timersw.h"
void DelayMs(uint8_t ms) // Ждать ms милисекунд
{
uint8_t i; // рабочий регистр
for(i=ms;i>0;i--)
__delay_cycles(1000000/TCLK); // Задержка 1мс
}
void Delay01(uint16_t s01) // Ждать s01*0.1 секунд
{
uint8_t i; // рабочий регистр
for(i=s01;i>0;i--) DelayMs(100);
}
uint8_t OW_crc8(uint8_t seed, uint8_t inData)
{
uint8_t bitsLeft;
uint8_t temp;
for (bitsLeft = 8; bitsLeft > 0; bitsLeft--)
{
temp = ((seed ^ inData) & 0x01);
if (temp == 0) seed >>= 1;
else
{
seed ^= 0x18;
seed >>= 1;
seed |= 0x80;
}
inData >>= 1;
}
return seed;
}
//Сброс шины 1-wire
uint8_t OW_reset(void)
{
uint8_t answer;
OW_PORT_SET; // Обеспечить питанием для двух проводного варианта
OW_DDR_SET; // На вывод
DelayMs(10); // 10 ms
OW_PORT_CLR; // Reset
__delay_cycles(510000/TCLK); // 510 us
OW_DDR_CLR; // Освободить шину
OW_PORT_SET; // Подпорка
__delay_cycles(50000/TCLK); // ~50us
answer = ((OW_PIN & (1<<OW_DQ))!=0);
__delay_cycles(430000/TCLK); // ~420us для завершения цикла
OW_DDR_SET; // На вывод
return (answer); // 0-есть устройства, 1-нет устройств
}
//Запись бита
void OW_write_bit(uint8_t bit)
{
OW_DDR_SET; // Порт на вывод
OW_PORT_CLR; // Начало вывода бита
__delay_cycles(2000/TCLK); // 2us
if(bit) OW_DDR_CLR; // Если "1", то освободить шину
__delay_cycles(62000/TCLK); // +62us
OW_DDR_CLR;
OW_PORT_SET; // Завершить цикл
}
//Чтение бита
uint8_t OW_read_bit(void)
{
uint8_t result;
OW_DDR_SET; // Порт на вывод
OW_PORT_CLR; // Начало чтения бита
__delay_cycles(2000/TCLK); // 2us
OW_DDR_CLR; // Освободить шину
OW_PORT_SET; // Подпереть
__delay_cycles(13000/TCLK); // +13us
result = ((OW_PIN & (1<<OW_DQ))!=0); // прочитать
__delay_cycles(43000/TCLK); // +45us завершить операцию
return result;
}
//Запись байта
void OW_write_byte(uint8_t command)
{
for (uint8_t i = 0; i < 8; i++)
{
OW_write_bit(command & 0x01); // передаём бит
command >>= 1; // сдвигаем к следующему
}
}
//Чтение байта
uint8_t OW_read_byte(void)
{
uint8_t i;
uint8_t value = 0;
for(i = 0; i < 8; i++)
value |= OW_read_bit() << i; // читаем один бит и записываем его в разряд i
return(value);
}
//Запуск конвертации температуры (для одного датчика на шине)
void convert_temp_short(void)
{
OW_reset();
OW_write_byte(SKIP_ROM); // skip ROM command (0xCC)
OW_write_byte(CONVERT_T); // convert T (0x44)
}
//Чтение температуры
int16_t read_scratchpad(uint8_t tip)
{
uint8_t scratchpad[8];
uint8_t crc = 0;
OW_write_byte(READ_SCRATCHPAD); // читаем scratchpad 0xBE
for (uint8_t c1 = 0; c1 < 8; c1++)
{
scratchpad[c1] = OW_read_byte(); // Принять данные с 1 Wire шины
crc = OW_crc8(crc, scratchpad[c1]); // Посчитать CRC8 для 1 Wire шины
}
crc=OW_crc8(crc, OW_read_byte());
OW_reset();
if (crc == 0) // Проверить CRC8 для 1 Wire шины
{
if(tip==DS18B20TIP)
//return ((scratchpad[1] << 4) | (scratchpad[0] >> 4));
return ((scratchpad[1] <<8) | (scratchpad[0] ));
else
return ((scratchpad[1] & 0x80) | (scratchpad[0] >> 1));
}
else return ( ERROR_CRC); // Message -80
}
//Чтение температуры (для одного датчика на шине)
int16_t read_temp_short(void)
{
OW_reset();
OW_write_byte(SKIP_ROM); // пропусь ROM
return (read_scratchpad(DS18B20TIP)); // Чтение температуры
}
//Выбор датчика
void MatchRom(uint8_t numb_dev)
{
uint8_t crc,*addr;
crc = 0; // предустановка crc
OW_reset();
OW_write_byte(MATCH_ROM); // match ROM команда (0x55)
// Указатель на начало ROM области данного устройства
for(addr=OW_Rom_Device+numb_dev*7;addr<OW_Rom_Device+numb_dev*7+7;addr++)
{
OW_write_byte(*addr); // вывести байт ROM
crc = OW_crc8(crc,*addr); // посчитать CRC
}
OW_write_byte(crc); // вывести байт crc
}
//Запуск конвертации температуры (для конкретного датчика на шине)
void convert_temp(uint8_t numb_dev)
{
MatchRom(numb_dev); // match ROM команда
OW_write_byte(CONVERT_T); // convert T (0x44)
OW_PORT_SET; // Обеспечить питанием для двух проводного варианта
OW_DDR_SET; // На вывод
}
//Чтение температуры (для конкретного датчика на шине)
int16_t read_temp(uint8_t numb_dev)
{
MatchRom(numb_dev); // match ROM команда
return (read_scratchpad(*(OW_Rom_Device+numb_dev*7)));
}
uint8_t lastDiscrep; // last discrepancy
uint8_t *CurrentAddr;
// NEXT
// Эта функция ищет следующее устройство на 1- проводной шине. Если
// нет больше устройств на 1- проводной шине, тогда возвращается FALSE.
//
uint8_t Next(void)
{
uint8_t crc; // CRC
uint8_t m = 1; // битовый индекс
uint8_t n = 0; // байтовый индекс
uint8_t k = 1; // битовая маска
uint8_t discrepMarker = 0; // "маркер несоответствия" или "развилка" на дереве устройств
uint8_t g; // Рабочий/Выходной бит
crc = 0; // предустановка crc
if(OW_reset()||(lastDiscrep==100)) // Нет устройств (нет ответа) или все устройства перебраны, то выход FALSE
{
lastDiscrep = 0; // Начало поиска
return FALSE;
}
OW_write_byte(SEARCH_ROM); // передать команду SearchROM
do // для всех восьми байтов
{
g = OW_read_bit() << 1; // ответ на "0"
g |= OW_read_bit(); // и на дополнение
if(g ==3) break; // нет устройств - завершить
else
{
if(g>0) // все связанные устройства отвечают на 0 или 1 (нет перекрёстка)
g = g>>1; // битовая величина записи для поиска (идём по ветке)
else
{ // Два устр-ва ответило на разные биты -- перекрёсток
// если этот перекрёсток - перед последним
// перекрёстком на предшествующем NEXT, тогда выберите
// такой же бит как и в прошлый раз
if(m<lastDiscrep) g = (((*(CurrentAddr+n))&k)>0);
else g = (m==lastDiscrep); // если равен последнему отклику ==1
if (g==0) discrepMarker = m; // Выбрать новый перекрёсток
}
if(g==1) (*(CurrentAddr+n)) |= k; // перепешите бит в ROM[n] с маской k
else (*(CurrentAddr+n)) &= ~k;
OW_write_bit(g); // вывести
m++; // следующий бит
k = k<<1; // сдвинуть маску
if(k==0) // если маска переполнилась, то - следующий байт ROM
{ // байт n и инициализация маски
crc = OW_crc8(crc, *(CurrentAddr+n)); // посчитать CRC
n++; k++;
}
}
}while(n<8); // цикл через все байты ROM 0-7
if(m<65||crc){ // если поиск был неудачным, тогда
lastDiscrep=0; // очистка last discrepancy
return FALSE;
}
else
{
lastDiscrep = discrepMarker; // поиск был удачным, так что установлено lastDiscrep,
if(lastDiscrep==0) lastDiscrep=100; // Если перекрёсток был последним, то установить признак выхода в след. NEXT
else
{
CurrentAddr +=7; // Следующий адрес
malloc(7); // Зарезервировать память под ROM
}
return TRUE; // указывает что поиск - не завершен пока,
} // некоторые устройства остаются
}
uint8_t OW_cnt_device(void)
{
uint8_t Cnt_Device; // Число устройств на шине
if(!OW_reset()) // Начинается когда импульс присутствия обнаружен
{
lastDiscrep = 0; // восстановите последнее несоответствие rom поиска глобальное
Cnt_Device=0;
OW_Rom_Device=CurrentAddr=malloc(8); // Зарезервировать память под ROM
while (Next()) // Продолжить пока все дополнительные устройства не будут обнаружены
{
Cnt_Device++;
}
} return(3);
}
в теле программы вызываю процедуру поиска датчиков
Код
OW_cnt_device(void)
и вот она мне ка раз и возвращает количество датчиков большое.
Пробовал симулировать в Протеусе - все то же самое