реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Инициализация 1wire
zheka
сообщение Mar 26 2006, 10:17
Сообщение #1


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



Пытаюсь поработать с датчиком DS1820. Использую готовый рабочий пример. Не работает - вначале думал, датчик не исправен. А потом понял что

проблема с 1wire.

Вот файл onewire.h
Код
#ifdef IAR

  /* запись */
  #ifndef DQW
  #define DQW     PORTD_Bit5
  #endif
  /* чтение */
  #ifndef DQR
  #define DQR     PIND_Bit5
  #endif
  /* установка направления чтение/запись */
  #ifndef DQD
  #define DQD     DDRD_Bit5
  #endif
  
  #include <inavr.h>
  
#endif

#ifdef CV

  /* запись */
  #ifndef DQW
  #define DQW     PORTD.5
  #endif
  /* чтение */
  #ifndef DQR
  #define DQR     PIND.5
  #endif
  /* установка направления чтение/запись */
  #ifndef DQD
  #define DQD     DDRD.5
  #endif
  
  #include <delay.h>
  
#endif

/********************************************************************************
**************
    Переменные для функции задержки

              a = 10us
              c = 70us
              d = 120us
              e = 410us
              f = 480us

********************************************************************************
**************/
/*
================================================================================
=======================================
    Функция задержки для кварца 4.000 МГц.
    CodeVision -> задержка равна ( 11,75 + 2,75*Х ) мкс
    IAR        -> задержка равна ( 10 + 1,5*Х ) мкс
================================================================================
=======================================
*/
//void delay(unsigned int useconds)
//{
    /*~~*/
    //int s;
    /*~~*/
    
    //for(s = 0; s < useconds; s++)
    //{
    //};
//}

/*
================================================================================
=======================================
    Функция OW_RESET -> сбрасывает шину 1-Wire и определяет наличие подключенных устройств.
    Сигнал сброса должен быть длинной минимум 480 мкс.
================================================================================
=======================================
*/
unsigned char ow_reset(void)
{
    /*~~~~~~~~~~~~~~~~~~~~~*/
    unsigned char    presence;
    /*~~~~~~~~~~~~~~~~~~~~~*/

    DQW = 0;
    DQD = 1;            /* устанавливаем низкий уровень на линии данных (DQ) */
                        /* задержка 480us */
    #ifdef    IAR
    
        __delay_cycles(1920);
    
    #endif
    
    #ifdef    CV
    
        delay_us(480);
    
    #endif
    
    DQD = 0;            /* возвращаем на линию данных высокий уровень */
                        /* ждем ответа 70us */
    #ifdef    IAR
    
        __delay_cycles(280);
    
    #endif
    
    #ifdef    CV
    
        delay_us(70);
    
    #endif
    
    presence = DQR;        /* определяем наличие устройств на линии */
                        /* ждем окончания временного промежутка (410us) */
    #ifdef    IAR
    
        __delay_cycles(1640);
    
    #endif
    
    #ifdef    CV
    
        delay_us(410);
    
    #endif
    
    return(presence);    /* возвращаем наличие устройств на шине */
}                        /* 0 = на шине есть устройства, 1 = нет устройств */

/*
================================================================================
=======================================
    WRITE_BIT -> запись бита в шину.
================================================================================
=======================================
*/
void write_bit(char bitval)
{
    _DISABLE_INTERRUPT;
    DQW = 0;
    DQD = 1;                /* устанавливаем низкий уровень линии данных (DQ) */
                            /* пауза 10us */
    #ifdef    IAR
    
        __delay_cycles(40);
    
    #endif
    
    #ifdef    CV
    
        delay_us(10);
    
    #endif
    
    if(bitval == 1) DQD = 0;/* устанвливаем высокий уровень линии данных (DQ),если записывается 1 */
                            /* ждем окончания временного интервала (70us) */
    #ifdef    IAR
    
        __delay_cycles(280);
    
    #endif
    
    #ifdef    CV
    
        delay_us(70);
    
    #endif
    
    DQD = 0;                /* устанвливаем высокий уровень линии данных (DQ) */
    _ENABLE_INTERRUPT;
}

/*
================================================================================
=======================================
    WRITE_BYTE -> запись байта в шину.
================================================================================
=======================================
*/
void write_byte(char val)
{
    /*~~~~~~~~~~~~~~~~~*/
    unsigned char    i;
    unsigned char    temp;
    /*~~~~~~~~~~~~~~~~~*/

    for(i = 0; i < 8; i++)    /* запись по одному биту */
    {
        temp = val >> i;    /* сдвигаем байт вправо на величину 'i' */
        temp &= 0x01;        /* копируем младший бит в temp */
        write_bit(temp);    /* записываем бит в шину */
    }

                            /* ожидаем окончания временного интервала */
    #ifdef    IAR
    
        __delay_cycles(480);
    
    #endif
    
    #ifdef    CV
    
        delay_us(120);
    
    #endif
    
}

/*
================================================================================
=======================================
    READ_BIT -> чтение бита из шины.
================================================================================
=======================================
*/
unsigned char read_bit(void)
{
    _DISABLE_INTERRUPT;
    DQW = 0;
    DQD = 1;    /* устанавливаем низкий уровень линии данных (DQ) */
    _NOP;
    DQD = 0;    /* устанвливаем высокий уровень линии данных (DQ) */
                /* задержка 10us */
    #ifdef    IAR
    
        __delay_cycles(40);
    
    #endif
    
    #ifdef    CV
    
        delay_us(10);
    
    #endif
    
    _ENABLE_INTERRUPT;
    return(DQR);/* возвращаем значение линии данных (DQ) */
}

/*
================================================================================
=======================================
    READ_BYTE -> чтение байта из шины.
================================================================================
=======================================
*/
unsigned char read_byte(void)
{
    /*~~~~~~~~~~~~~~~~~~~~~~*/
    unsigned char    i;
    unsigned char    value = 0;
    /*~~~~~~~~~~~~~~~~~~~~~~*/

    for(i = 0; i < 8; i++)
    {
        if(read_bit()) value |= 0x01 << i;/* читаем один бит и записываем его в разряд i */
        
                                          /* ожидаем окончания временного интервала */
    #ifdef    IAR
    
        __delay_cycles(480);
    
    #endif
    
    #ifdef    CV
    
        delay_us(120);
    
    #endif
        
    }

    return(value);
}

/*
================================================================================
=======================================
    calc_crc -> подсчет контрольной суммы.
================================================================================
=======================================
*/
char calc_crc(unsigned char* buff, char num_vals)
{
    /*~~~~~~~~~~~~~~~~~~~~~~*/
    char    shift_reg = 0,
            data_bit,
            sr_lsb,
            fb_bit,
            i,
            j;
    /*~~~~~~~~~~~~~~~~~~~~~*/

    for(i = 0; i < num_vals; i++)
    {
        for(j = 0; j < 8; j++)
        {
            data_bit = (*buff >> j) & 0x01;
            sr_lsb = shift_reg & 0x01;
            fb_bit = (data_bit ^ sr_lsb) & 0x01;
            shift_reg = shift_reg >> 1;
            if(fb_bit)
            {
                shift_reg = shift_reg ^ 0x8c;
            }
        }
    buff++;
    }

    return(shift_reg);
}





Вот моя программа (часть функций и переменных опущена):
Код
#define CV
#include <delay.h>
#include <stdio.h>
#include "macros.h"
#include "mega8.h"
#include <stdlib.h>
#include <string.h>
#include "NokiaLCD.h"
#include <ctype.h>
#include <onewire.h>

///

void main ()
{

char *s=r;
unsigned char i,j,devices;
int temp;


devices=ow_reset(); // инициализация 1wire, поиск устройств, должна возвращать 0 в случае обнаружения.

LcdInit();                    
Delay();
LcdGotoXY(2,2);

sprintf(s,"%u ",devices);
LcdStr(FONT_1X,s,NORMAL);
LcdUpdate();    
}



На экран вылазит 0 (соответствует обнаружению устройства) даже если к порту ничего не подключено.
Контроллер исправен, порт D исправен, тесты мигалками моргалками проходит
Где ошибка?

Сообщение отредактировал zheka - Mar 26 2006, 10:18
Go to the top of the page
 
+Quote Post
zheka
сообщение Mar 26 2006, 16:38
Сообщение #2


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



Хм... разобрался - все правильно с программной точки зрения.
Не отвечает датчик.

Либо он неисправен, либо я неправильно его питаю. Я сделал небольшие отступления от правил:
-pull-up резистор не 4,7 кОм, а 5,1 кОм (ну не дошел пока до магазина, а поэкспертиментировать невтерпеж)
-питание - от одного с микроконтроллером источника - 3 вольт

Должен ли работать датчик при таком питании?

Как понять фразу в даташите про питание и про резистор :
Цитата
4.7K pullup resistor from a 3V to 5.5V supply rail.


???

Сообщение отредактировал zheka - Mar 26 2006, 16:40
Go to the top of the page
 
+Quote Post
WHALE
сообщение Mar 26 2006, 17:16
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



подтягивающий резистор 4,7к для шины с питанием от 3.3 до 5В.
а вообще пройдись поиском для начала в форуме AVR,крайнем случае Гуглем.Найдеш кучу примеров.Да,CV же имеет библиотечную
поддержку DS1820.


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
zheka
сообщение Mar 26 2006, 17:54
Сообщение #4


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



WHALE

Сорри... ошибка в указании датчика - DS18B20.
Я прочел с десяток тем в форуме и другиз материалов в интернете - часто встречается мысль - НИ В КОЕМ случае не меняйте DS18b20 на DS1820 - у них совершенно разная внутренняя структура.
Так что мне пример от codeVision не подойдет.

К тому - же проблема у меня не с датчиком DS1820, как таковым а с устройством поддерживающим 1wire.


WHALE, огромное спасибо, за бесценный совет пользоваться поиском, который я никак не усвою, но на мой вопрос о том может ли датчик не работать из-за тех изменений, которые я указал - вы так и не ответили.

Аль на форуме была такая же тема? Аль есть аппликухи от Dallas для таких как я? Покажите, плз...


Цитата
4,7к для шины с питанием от 3.3 до 5В.

Ага.. имеется ввиду диапазон. ПРочитав фразу на английском мне показалось что имеется ввиду какое-то согласование двух напряжений - тем более что в даташите пару слов написано про внешнее питание.

Сообщение отредактировал zheka - Mar 26 2006, 17:55
Go to the top of the page
 
+Quote Post
AndyBig
сообщение Mar 27 2006, 18:22
Сообщение #5


Иногдящий
****

Группа: Свой
Сообщений: 691
Регистрация: 28-02-05
Пользователь №: 2 931



DS18S20 работает на паразитном питании при падении питания вплоть до 2 вольт с подтягивающим резистором 4,7К. Правда, при напряжении меньше 2,8 вольта начинает безбожно врать smile.gif.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 17:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01441 секунд с 7
ELECTRONIX ©2004-2016