Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: 1-Wire
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Letis
Подключил библиотеку 1wire. Не использовал из CodeVision, так как нужно менять пины порта.
Но функция инициализации не работает, помогите. Что я делаю не так.
Все файлы CodeVision и Протеуса выкладываю ниже.

#define OW_DDR DDRD
#define OW_PIN PIND
#define OW_BUS 0
char count;


//------------------------------------------------------------------------------
// Инициализация
//------------------------------------------------------------------------------
char OW_Initialization(void)
{
char nalichie_ustroystva = 0;
OW_DDR |= (1<<OW_BUS);
delay_us(100);
delay_us(100);
delay_us(100);
delay_us(100);
delay_us(100);
OW_DDR &= ~(1<<OW_BUS);
delay_us(90);
if((OW_PIN&0x01)== 0)
{
nalichie_ustroystva = 1;
}
delay_us(100);
delay_us(100);
return nalichie_ustroystva;
}
//------------------------------------------------------------------------------

kolobok0
Цитата(Letis @ Sep 17 2010, 01:37) *
...Что я делаю не так. ...


наверное стоит почитать про порты МК.
Направление Вы задаёте. а что порт на пин выдаёт? нолик или одын?
предположим нолик. если это вход - отключение подтяжки, если её нет внешней - Z состояние. если это выход - нолик.
предположим одын. если это вход - подтяжка подключена, логический одын. если выход - одын.

как видите и то и то не - работать не будет.


удачи Вам
(круглый)
GDI
Цитата
предположим нолик. если это вход - отключение подтяжки, если её нет внешней - Z состояние. если это выход - нолик.

Именно так и работает порт с 1-wire.

To Letis
Код
if((OW_PIN&0x01)== 0)

должно быть
Код
if((OW_PIN&(1<<OW_BUS))== 0)

но это мелочи наверное.
В свое время использовал библиотеку http://www.microsyl.com/index.php/2010/03/...newire-library/ и переделывал ее под себя в CodeVision.
А еще можете порыться тут http://electronix.ru/forum/index.php?showtopic=10934. В этом разделе выложено несколько реализаций 1-wire.
Палыч
Цитата(GDI @ Sep 17 2010, 15:10) *
Именно так и работает порт с 1-wire.
Выше речь шла о том, что о внешней подтяжке к высокому уровню на линии автор вопроса даже не обмолвился (по-умолчанию - её нет), а внутренняя подтяжка в программе при прослушивании presence pulse со стороны МК не предусмотрена.
GDI
Ну, если топик стартер не знает что для 1-wire нужна подтяжка, тогда и ваши намеки на работу портов бесполезны smile.gif
kolobok0
Цитата(GDI @ Sep 17 2010, 15:10) *
Именно так и работает порт с 1-wire....


ну а теперь смотрите даташит на 1Wire в разделе формирования слота. немного почитав даташит и опять просмотрев вдумчиво мессагу мою, Вы поймёте о чем шла речь. Одним дирекшеном Вы не получите необходимой формы сигнала согласно даташиту(без внешнего резистора. нет конечно же можно как в 51 серии вкрячивать лишнюю детальку, платить лишние бабло за линейку и за пайку 9 точек. а оно нуна в производстве?). увы и ах.

(круглый)
ЗЫ
Библиотеки обычно подходят для ознакомления с рабочим вариантом. В боевых применениях, когда требуется получать каждую секунду несколько значений с маленькой кучки датчиков(с разрешением скажем в 0,01 градус), решать основные задачи, следить за процентом помех на линиях датчиков - увы библиотеки вам не помогут...

(круглый)
Леонид Иванович
У меня код такой:

CODE
//----------------------------------------------------------------------------

//Модуль обслуживания термометра DS18B20

//----------------- Используемые модулем аппаратные ресурсы: -----------------

//1-проводной интерфейс использует порт OWP.
//Порт должен быть настроен на ввод,
//внутренний подтягивающий резистор должен быть отключен,
//используется внешний подтягивающий резистор 4.7 кОм.
//Должны быть определены следующие макросы:
//#define OWP (1 << Pxn)
//#define Port_OWP_OUT (DDRx |= OWP)
//#define Port_OWP_IN (DDRx &= ~OWP)
//#define Pin_OWP (PINx & OWP)
//Термометр должен быть запрограммирован в 12-разрядный режим
//(биты R0, R1 в регистре конфигурации равны единице).
//Считываются только 2 байта темпертуры без проверки CRC.

//----------------------------- Константы: -----------------------------------

#define TCONV 1000 //время преобразования температуры, мс

//---------------------------- Переменные: -----------------------------------

bool Presence; //флаг присутствия термометра
int Temperature; //текущая температура
int TTimer; //таймер термометра

//----------------------------- Функции: -------------------------------------

bool TReset(void); //формирование импульса сброса
char TByte(char dat); //запись/чтение байта
bool TBit(bool cool.gif; //запись/чтение бита
bool Start(void); //запуск преобразования
int Read_T(void); //чтение температуры

//--------------------- Генерация импульса сброса: ---------------------------

bool TReset(void)
{
char si;
Port_OWP_0;
Port_OWP_OUT; //OWP <- 0
Delay_us(500); //delay 500 uS
si = __save_interrupt();
__disable_interrupt(); //запрещение прерываний
Port_OWP_IN; //OWP <- 1
Delay_us(14); //delay 14 uS
if(Pin_OWP) //если OWP = 0, то ошибка
{
Delay_us(52); //delay 52 uS
if(!Pin_OWP) //если OWP = 1, то ошибка
{
__restore_interrupt(si); //восстанавление прерываний
Delay_us(250); //delay 250 uS
if(Pin_OWP) //если OWP = 0, то ошибка
{
return(1); //если ошибок нет, термометр присутствует
}
}
}
__restore_interrupt(si); //восстанавление прерываний в случае ошибки
return(0);
}

//-------------- Запись/чтение байта по однопроводной шине: ------------------

char TByte(char dat)
{
char res;
for(char i = 0; i < 8; i++)
{
res = res >> 1;
if(TBit(dat & 1)) res |= 0x80;
else res &= ~0x80;
dat = dat >> 1;
}
return(res);
}

//--------------- Запись/чтение бита по однопроводной шине: ------------------

bool TBit(bool cool.gif
{
char si;
si = __save_interrupt();
__disable_interrupt(); //запрещение прерываний
Port_OWP_0;
Port_OWP_OUT; //OWP <- 0
Delay_us(2); //delay 2 uS
if(cool.gif Port_OWP_IN; //bit = 1, OWP <- 1
Delay_us(13); //delay 13 uS
bool owp = Pin_OWP; //чтение порта
Delay_us(45); //delay 45 uS
Port_OWP_1; //force pullup
Port_OWP_OUT;
__restore_interrupt(si); //восстанавление прерываний
Delay_us(2); //delay 2 uS
return(owp);
}

//----------------------- Запуск преобразования: -----------------------------

bool Start(void)
{
if(TReset())
{
TByte(0xCC); //skip ROM
TByte(0x44); //start conversion
return(1);
}
return(0);
}

//-------------------------- Чтение термометра: ------------------------------

int Read_T(void)
{
if(TReset())
{
TByte(0xCC); //skip ROM
TByte(0xBE); //read scratchpad
char l = TByte(0xFF); //чтение младшего байта
char h = TByte(0xFF); //чтение старшего байта
return(WORD(h, l));
}
return(0); //ошибка
}

//--------------------- Инициализация термометра: ----------------------------

void DS18B20_Init(void)
{
Presence = Start();
TTimer = ms2sys(TCONV);
}

//----------------------- Измерение температуры: -----------------------------

void DS18B20_Exe(bool t)
{
if(t)
{
if(TTimer) TTimer--;
if(!TTimer)
{
if(Presence) Temperature = Read_T();
Presence = Start();
TTimer = ms2sys(TCONV);
}
}
}

//------------------------- Чтение температуры: ------------------------------

int DS18B20_GetT(void)
{
return(Temperature);
}

//----------------------------------------------------------------------------
ARV
Цитата(Леонид Иванович @ Sep 17 2010, 21:50) *
У меня код такой
а у меня такой http://electronix.ru/forum/index.php?showt...st&p=811157 smile.gif
kolobok0
Цитата(Леонид Иванович @ Sep 17 2010, 21:50) *
У меня код такой:...


вы простите меня. я понимаю что отлаженый код. но всё таки рекомендую подтягивать резистором на плюс 1Wire пин. аргументация проста до безобразия - вы же не собираетесь к нему тупо подключать датчик? нет конечно же для работы на столе до пару метров - без проблем. но в пром. автоматику я бы не рекомендовал. кстати 4,7 кила не обязательно тогда втыкать. он потребуется если только у вас метраж (реально) за 100 метров. ну с перестраховкой 10 метров. тогда Вы понимаете что валятся фронты и помеха даёт о себе знать. Хотя там даже уже и не килы а несколько сот ом уже будет.


ну это чиссо моё имхо. чисса из практики.
(круглый)
ЗЫ
заткнулся smile.gif
ЗЫ ЗЫ
Приведу только кусок вывода (прошу прощение заранее за такую наглость):
Код
;========
; used Z
DSOut0:
; out "0"
    in    ZL,DS_PORT
    andi    ZL,DS_MASKA_AND;
    in    ZH,DS_DIRECTION_PORT
    ori    ZH,DS_MASKA_OR;
    out    DS_PORT,ZL
    out    DS_DIRECTION_PORT,ZH
    ret            ; 4
;========
; used Z
DSOut1:            ; 3
    in    ZL,DS_PORT; 1
    ori    ZL,DS_MASKA_OR; 1
    in    ZH,DS_DIRECTION_PORT; 1
    andi    ZH,DS_MASKA_AND; 1
    out    DS_PORT,ZL; 1=8
    out    DS_DIRECTION_PORT,ZH; 1(9)
    ret            ;
;========
ARV
Цитата(kolobok0 @ Sep 17 2010, 22:13) *
вы простите меня. я понимаю что отлаженый код. но всё таки рекомендую подтягивать резистором на плюс 1Wire пин. аргументация проста до безобразия - вы же не собираетесь к нему тупо подключать датчик? нет конечно же для работы на столе до пару метров - без проблем. но в пром. автоматику я бы не рекомендовал. кстати 4,7 кила не обязательно тогда втыкать. он потребуется если только у вас метраж (реально) за 100 метров. ну с перестраховкой 10 метров. тогда Вы понимаете что валятся фронты и помеха даёт о себе знать. Хотя там даже уже и не килы а несколько сот ом уже будет.
ваши рекомендации не выдерживают никакой критики - потому и не буду критиковать. но лично мое мнение о том, что правильно, а что нет, основывается на простом факте: что рекомендовано в даташите - правильно, остальное - нет. в каждом даташите на девайсы 1-wire показана схема выхода как открытый сток или коллектор, внешний подтягивающий резистор - обязателен. внутренняя подтяжка AVR - это резистор от 30 до 70 килоом, что явно недостаточно для паразитного питания, да и может не обеспечить время восстановления единицы в линии в соответствии со стандартом. вот как-то так...
kolobok0
Цитата(ARV @ Sep 17 2010, 23:09) *
...в каждом даташите на девайсы 1-wire...


пускай будет именно так как Вы сказали smile.gif

удачи вам
(круглый)
SasaVitebsk
Цитата(ARV @ Sep 17 2010, 22:09) *
ваши рекомендации не выдерживают никакой критики - потому и не буду критиковать. но лично мое мнение о том, что правильно, а что нет, основывается на простом факте: что рекомендовано в даташите - правильно, остальное - нет. в каждом даташите на девайсы 1-wire показана схема выхода как открытый сток или коллектор, внешний подтягивающий резистор - обязателен. внутренняя подтяжка AVR - это резистор от 30 до 70 килоом, что явно недостаточно для паразитного питания, да и может не обеспечить время восстановления единицы в линии в соответствии со стандартом. вот как-то так...

+1

Питание необходимо подавать выдав полную единицу перед циклом измерения. Т.о. паразитное питание ч/з подтяжку не осуществляется.
Я, лично, сталкивался с DS18b20, которые неправильно работали если не ставить внешний резистор. Были две разных партии. Показания в этом случае были неправильны. Как только поставили резисторы подтяжки - всё заработало.

Таким образом, ещё и ещё раз убеждаешься, что следование рекомендациям даташита избавляет вас от лишних потерь времени.
kolobok0
Цитата(SasaVitebsk @ Sep 18 2010, 11:27) *
... Т.о. паразитное питание ч/з подтяжку не осуществляется....


а вот теперь ткните меня носом где топикастер указывал про паразитное питание в изначальном посте? или 1Wire всегда = паразитное питание? могу привести куча девайсов для 1Wire БЕЗ паразитного питания (например ds1821).


(круглый)
ARV
топикстартеру было паразитное питание до фени - факт. но вы-то высказались против "отпускания" пина в 3-состояние и предложили взамен использовать встроенную подтяжку и отказаться от внешнего резистора - отсюда и развитие темы.

ds1821 - это какой-то выкидыш 1-Wire, т.к. от этого стандарта использует только две вещи: сигналы RESET-PRESENSE и таймслоты приема-передачи, а главные фичи - адресацию и возможность поиска адресов не реализует...
kolobok0
Цитата(ARV @ Sep 19 2010, 21:52) *
...предложили взамен использовать встроенную подтяжку и отказаться от внешнего резистора...

ds1821 - это какой-то выкидыш 1-Wire...


1) угумс предложил. будет время - кое чаво проверю в железе. то что дышит (условия опущу пока) - факт. Вы правы указывая на значительную разницу в номиналах резисторов. В одном и другом случае. И Ваше замечание родило интересную идею. нуна подумать.
2) вы как то лихо перескакиваете с темы на тему. теперь вам не нравится конкретная модель smile.gif как дети прям. ок. пускай будет по вашему - ds1820 подойдёт (что из линейки термодатчиков, ышо одын типа)? (хотя на мой взгляд двадцатки сильно уступают 21 ну не суть. у каждого портного свой взгляд на исскуство. не бум в сторону отходить.)

кстати вот вопросы лично к Вам уважаемый созрели. Два провода это хорошо. Исходя из Вашего опыта:
1) применяли ли Вы в 'боевых' условиях скажем больше чем 5 датчиков в установке(приборе)? Время получения показаний со всех точек?
2) что нужно сделать при замене датчиков(либо провода - ведь порой не знаешь что глючить начало. дачтики летят чаще конечно же. где то около 10 на тысячу.) подключённых на одну шину в устройстве? кол-во шагов по замене?
3) каким проводом Вы подключаете при таком включении датчики? телефонной лапшой?

удачи вам
(круглый)
ARV
1. мои "боевые" условия ограничивались помещениями типа офис (квартира). большое количество датчиков (9 штук) подключал буквально 1 раз, но по 3-проводной схеме. 9 датчиков подключались гирляндой: 3м хвост, а потом каждые 1,5м датчик. инфа считывалась раз в секунду со всех датчиков. промышленным применением датчиков пока не занимался.

2. понятия не имею, что надо делать smile.gif

3. подключения делаю первым попавшимся под руку проводом, свивая его в "витую тройку" smile.gif
xemul
Цитата(ARV @ Sep 19 2010, 21:52) *
ds1821 - это какой-то выкидыш 1-Wire, т.к. от этого стандарта использует только две вещи: сигналы RESET-PRESENSE и таймслоты приема-передачи, а главные фичи - адресацию и возможность поиска адресов не реализует...

почти оффтоп:
Главная фича ds1821 - режим standalone thermostat. Ванварь - просто интерфейс, по которому программируются параметры термостата, а лишний функционал вырезали.
MBR
Цитата(Letis @ Sep 17 2010, 01:37) *
delay_us(90);

По даташиту устройство отвечает минимум через 15us, минимальной продолжительностью 60us. Собственно, 15+60 < 90 и велик шанс, что через 90us фронт уже подтянулся вверх.
GDI
Цитата(MBR @ Sep 27 2010, 12:24) *
По даташиту устройство отвечает минимум через 15us, минимальной продолжительностью 60us. Собственно, 15+60 < 90 и велик шанс, что через 90us фронт уже подтянулся вверх.

То что вы описали, это прием-передача бита, а код у топикстартера относится к presence, на который устройство должно ответить удержанием линии в 0 на 450мкс.
xemul
Цитата(GDI @ Sep 27 2010, 13:57) *
То что вы описали, это прием-передача бита, а код у топикстартера относится к presence, на который устройство должно ответить удержанием линии в 0 на 450мкс.

Примерно так, но наоборот.
Если "устройство" - это ванварный слэйв, то оно должно ответить PRESENCE PULSE'ом (60..240 мкс) на RESET PULSE мастера (>480 мкс, не вдаваясь в подробности).
MBR
Цитата(GDI @ Sep 27 2010, 13:57) *
То что вы описали, это прием-передача бита, а код у топикстартера относится к presence, на который устройство должно ответить удержанием линии в 0 на 450мкс.

Именно Presence pulse 60..240. У меня DS1820+ отпустило 0 ровно через 60мкс.
GDI
Да, точно... давно не брал я в руки шашку... smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.