Страница 1 из 1

CVAVR+Proteus ответ 1-wire устройства - странный

Добавлено: Чт апр 29, 2010 22:59:22
nsl2004
Словил вот такую проблему.
В проекте по 1 -wire соеденены два МК (AtMega32) - один МК эмулятор 1-wire второй ведущий ( мастер)
Проблема вот в чем.
У меня существует два варианта мастера , перивожу все в упрощенном виде только для команд инициализации устройства.
Первый. Использую команду w1_init ( та что является встроенной функцией)

Код: Выделить всё

#include <mega32.h>
#asm
   .equ __w1_port=0x18 ;PORTB
   .equ __w1_bit=0
#endasm
#include <1wire.h>
#include <stdio.h>
#include <delay.h>
void main(void)
{
PORTB=0x00;
DDRB=0x01;
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
while (1)
      {
      w1_init();
      delay_ms(500);

      };
}
[img]
http://www.radiokot.ru/forum/download/f ... w&id=33495[/img]
Картинка отличная - сигнал сброса амплитудой 5 вольт и соответственно ответ такой же все четко.
OWRESET1.jpg
(7.28 КБ) 980 скачиваний
Второй вариант функция ow_reset - из даташета и с помощью более опытных друзей. Выглядит вот так

Код: Выделить всё

#include <mega32.h>
#include <stdio.h>
#include <delay.h>
#define DQ  PORTB |=0<<PB0 //
#define PB0 0
#define _BV(bit) (1 << (bit))// это макрос из WinAvr, что бы работали примеры

//---------------Функция присутствия работает-------//
unsigned char ow_reset(void)                        //
 {                                                  //
    unsigned char presence=0;                       //
        PORTB &= ~_BV(PB0);;                        // опускаем линию к 0
        delay_us(480);                              // задержка 480us 
        PORTB |= _BV(PB0);                          // возвращаем на линию данных 1
        delay_us(70);                               // ждем ответа
        if (PINB & (1<<PB0))presence++; // принимаем ответ 
        delay_us(250);                              // ждем окончания временного промежутка 
        return(presence);                           // возвращаем наличие устройств на шине
    }                 
void main(void)
{
PORTB=0x00;
DDRB=0x01;
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
while (1)
      {
          if (ow_reset()==0)
            printf("Device YES"); else printf("NONE Device");
            printf("\n\r");
          delay_ms(500);       
      };
}

[img]
http://www.radiokot.ru/forum/download/f ... w&id=33494
[/img]
И Вы видете что на картинке ответ эмулятора имеет амплитуду в 2 раза меньше. Не могу понять в чем проблема. Вертится мысль, что чтото не так в настройках портов . Но простым перебором комбинаций конфигурации порта B ( их всего 4) ничего не вышло. Может кто подскажет? такое впечатление что что то не дает просадить шину к нулю.

Re: CVAVR+Proteus ответ 1-wire устройства - странный

Добавлено: Пт апр 30, 2010 07:21:29
ARV
nsl2004 писал(а):Второй вариант функция ow_reset - из даташета и с помощью более опытных друзей.
вас обманули - ваши друзья не настолько опытны!

в даташитах написано черным по белому: наличие импульса - это 0 в линии, отсутствие - это ОТПУСКАНИЕ линии. а что сделали вы? вы ноль подаете нормально, а вместо отпускания подаете глухую ЕДИНИЦУ! и хотите чтобы ведомое устройство передавило эту единицу в ноль!

по-настоящему опытные люди делают так: в PORTx всегда выводят 0 (один раз при инициализации, и потом никогда его не трогают), а работу с линией ведут через DDRx: вывели туда 1 - получили в линии 0, вывели туда 0 - получили отпущенную на волю ветров (т.е. подтягивающего резистора) линию.


удачи!

Re: CVAVR+Proteus ответ 1-wire устройства - странный

Добавлено: Пт апр 30, 2010 10:24:08
nsl2004
Все правильно. Большое спасибо. Переработал вот так

Код: Выделить всё

//---------------Функция присутствия работает ------//
unsigned char ow_reset(void)                        //
{                                                   //
    unsigned char presence=0;                       //
        DDRB|= _BV(PB0);                            // опускаем линию к 0 - единица в DDR это ноль на линии
        delay_us(480);                              // задержка 480us 
        DDRB&=~_BV(PB0);                            // возвращаем линию данных к исходному состоянию 
                                                    //"условно к 1"(отпускаем!)
        delay_us(70);                               // ждем ответа
        if (PINB & (1<<PB0))presence++;             // принимаем ответ 0-есть, 1 нет устройств
        delay_us(480);                              // ждем окончания временного промежутка (480us)
        return(presence);                           // возвращаем наличие устройств на шине
    }   
Сигнал стал четким и устойчивым.