Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: 1-wire+микроконтроллер
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
ks007
Здравствуйте, есть проблема не могу связать DS2431 и микроконтроллер. Моделирую в Протеусе работу микроконтроллера с DS2431. DS2431 отвечает, что оно присутствует, потом хочу записать данные видно, что данные идут а в ответ ничего подскажите как быть. код программы привел и схема.
CODE
#define OW_RESET() DDRD|=(1<<DDD0);\
PORTD&=~(1<<PD0);\
DELAY_US(500)


#define OW_SEND_ONE() DDRD|=(1<<DDD0);\
PORTD&=~(1<<PD0);\
DELAY_US(10);\
DDRD&=~(1<<DDD0);\
PORTD|=(1<<PD0);\
DELAY_US(10)

#define OW_SEND_ZERO() DDRD|=(1<<DDD0);\
PORTD&=~(1<<PD0);\
DELAY_US(100);\
DDRD&=~(1<<DDD0);\
PORTD|=(1<<PD0);\
DELAY_US(10)

typedef unsigned char BYTE;


int main(void)
{
//DDRD|=(1<<DDD1);

BYTE DevDetect;
OW_RESET();
DDRD&=~(1<<DDD0);
PORTD|=(1<<PD0);
DELAY_US(65);
if((PIND&(1<<PIND0))==0)
{
DevDetect=1;
}

else
DevDetect=0;
DELAY_US(415);
//OW_SendByte(0x55);
//OW_SendByte(0xF0);
OW_SendByte(0x0F);

OW_SendByte(0x20);
OW_SendByte(0x00);

OW_SendByte(0x8C);

return DevDetect;
}

void OW_SendByte(BYTE val)
{
for(int i=0; i<8; ++i)
{
if(val&(1<<i))
{
OW_SEND_ONE();
}
else
{
OW_SEND_ZERO();
}
}
}
Палыч
Цитата(ks007 @ Jun 9 2011, 14:36) *
...хочу записать данные видно, что данные идут а в ответ ничего подскажите как быть
Вы, вероятно, хотели повторить пример из DS со стр.22. Что же Вы его бросили на пол-пути? Реализовали хотя бы “Write Scratchpad” и “Read Scratchpad”. Да и “Skip ROM” выбросили... Что Вы хотели увидеть "в ответ"? Что бы увидеть ответ см. Figure 11. Read/Write Timing Diagrams "READ-DATA TIME SLOT"

Кстати, времена, приведенные на стр.2 и 3, нужно соблюдать!
ks007
Цитата(Палыч @ Jun 9 2011, 15:36) *

Спасибо за ответ.
Тайминги все выдерживаются, которые приведены на стр 2 и 3(проверял на временной диаграмме). А пример который, я делал на стр 21 "Write Scratchpad" (там несколько примеров), в ответ хотел видеть "CRC-16" и "FF Loop", на временной диаграмме я их не увидел.
У самого MAXIM есть примеры записи данных и считывания, пробовал не получается. Также вы подсказали хорошую идею которая на странице 22, попробую.
Палыч
Цитата(ks007 @ Jun 9 2011, 16:56) *
Тайминги все выдерживаются, которые приведены на стр 2 и 3(проверял на временной диаграмме).
Позволю себе усомниться: не выдерживается Tslot при передаче единицы...

Цитата(ks007 @ Jun 9 2011, 16:56) *
...на временной диаграмме я их не увидел.
Как же вы их увидете, если:
1. Выбросили ”Skip ROM”
2. Не выдали восемь(!) байт данных
3. Не произвели чтение. При чтении мастер (МК в этом случае - мастер) не "сидит сложа руки". Грубо говоря он формирует "Write-one time slot" (формирует короткий импульс, а затем "отпускает" линию: переводит на чтение с подтяжкой к питанию), а DS2431 "задерживает" низкий уровень на линии, если читается с неё ноль, или - "отпускает", если читается с неё единица. Мастер определяет это по состоянию линии в "Master sampling window".
ks007
Цитата(Палыч @ Jun 9 2011, 17:25) *

Восемь байт данных я отослал, понимаю код тяжко читается, но в программе это "OW_SendByte(0x8C);" а c Tslot точно не выдержал я думал, что Trec и все можно дальше кидать данные.
как я понял например: отослал 1 байт надо выждать Tslot и засылать след байт.
попробую все исправить, о результатах напишу.
Палыч
Цитата(ks007 @ Jun 9 2011, 18:12) *
Восемь байт данных я отослал, понимаю код тяжко читается, но в программе это "OW_SendByte(0x8C);"
Не-а... Функция OW_SendByte выводит один байт (или восемь бит).

Цитата(ks007 @ Jun 9 2011, 18:12) *
как я понял например: отослал 1 байт надо выждать Tslot и засылать след байт.
У Вас мешанина между байтами и битами...
При выдаче бита устанавливается низкий уровень на время Tw1L (или Tw0L, в зависимости от значения выводимого бита), затем устанавливается высокий уровень и ждём Tslot - Tw1L (или Tslot - Tw0L). Т.е. время между началом передачи двух соседних битов (или время передачи одного бита с любым значением) должно быть равным Tslot.
ks007
Цитата(Палыч @ Jun 9 2011, 17:48) *
У Вас мешанина между байтами и битами...

Я понял, что отсылал восьмую часть данных. Сейчас все исправил: тайминги выдержал, послал 8 байт данных.
ks007
Тайминги все выдержал(рис3), послал 8 байт данных, хочу прочитать CRC-16 (в коде все написано где), а в ответ ничего. Все делал по примеру стр 22( даташит DS2431). На рисунке 2 представлена работа программы. Устройство отвечает.
Что не так делаю, не пойму?
CODE
#include <avr/io.h>
//#include <avr/interrupt.h>
#define F_CPU 8000000UL
#include <util/delay.h>
//#include <predef.h>

#define DELAY_US(__delay) _delay_us(__delay)


#define OW_RESET() DDRD|=(1<<DDD0);\
PORTD&=~(1<<PD0);\
DELAY_US(500);\
DDRD&=~(1<<DDD0);\
PORTD|=(1<<PD0);\
DELAY_US(65);\
if((PIND&(1<<PIND0))==0)\
{\
DevDetect=1;\
PORTD|=(1<<PD1);\
PORTD&=~(1<<PD1);\
}\
else\
DevDetect=0;\
DELAY_US(420)


#define OW_SEND_ONE() DDRD|=(1<<DDD0);\
PORTD&=~(1<<PD0);\
DELAY_US(10);\
DDRD&=~(1<<DDD0);\
PORTD|=(1<<PD0);\
DELAY_US(100)

#define OW_SEND_ZERO() DDRD|=(1<<DDD0);\
PORTD&=~(1<<PD0);\
DELAY_US(100);\
DDRD&=~(1<<DDD0);\
PORTD|=(1<<PD0);\
DELAY_US(10)

typedef unsigned char BYTE;

int main(void)
{
DDRD|=(1<<DDD1);

BYTE DevDetect;
OW_RESET(); //Reset
OW_SendByte(0xCC); //Skip ROM

OW_SendByte(0x0F); //Write Scratchpad

OW_SendByte(0x20); //TA1
OW_SendByte(0x00); //TA2

// Записываем 8 байт данных
OW_SendByte(0x11);
OW_SendByte(0x22);
OW_SendByte(0x33);
OW_SendByte(0x44);
OW_SendByte(0x55);
OW_SendByte(0x66);
OW_SendByte(0x77);
OW_SendByte(0x88);
// Начинаем чтение
DDRD|=(1<<DDD0);
PORTD&=~(1<<PD0);
DELAY_US(10);
DDRD&=~(1<<DDD0);
PORTD|=(1<<PD0);
DELAY_US(100);

// смотрю где закончилась запись данных
PORTD|=(1<<PD1);
PORTD&=~(1<<PD1);


// !!!Здесь я должен увидеть CRC-16, но но графике нет ответа


/*OW_RESET();
OW_SendByte(0xCC);
OW_SendByte(0xAA);
_delay_ms(30);
PORTD|=(1<<PD1);
PORTD&=~(1<<PD1);

OW_RESET();
OW_SendByte(0xCC);
OW_SendByte(0x55);
OW_SendByte(0x20);
OW_SendByte(0x00);
OW_SendByte(0x07);

PORTD|=(1<<PD1);
PORTD&=~(1<<PD1);

DELAY_US(200);

PORTD|=(1<<PD1);
PORTD&=~(1<<PD1);

OW_RESET();
OW_SendByte(0xCC);
OW_SendByte(0xF0);
OW_SendByte(0x00);
OW_SendByte(0x00);

PORTD|=(1<<PD1);
PORTD&=~(1<<PD1);*/

return DevDetect;
}

void OW_SendByte(BYTE val)
{
//for(int i=7; i>=0; --i)
for(int i=0; i<8; ++i)
{
if(val&(1<<i))
{
OW_SEND_ONE();
}
else
{
OW_SEND_ZERO();
}
}
}
Палыч
Длина CRC составляет два байта. В Вашей программе - заготовка для приёма одного бита.
xemul
Цитата(ks007 @ Jun 11 2011, 13:59) *
Что не так делаю, не пойму?

Попробуйте посмотреть аппноты производителя - в каких-то есть пример реализации функции типа "uint8_t OW_SendByte(uint8_t)", которая при вызове OW_SendByte(0xff) выполняет роль функции типа "uint8_t OW_ReceiveByte(void)".
В Вашей же программе нет и намёка на приём чего-то вразумительного от слейва.

Достаточно "PORTD&=~(1<<PD0);" сделать единожды в начале программы, и сократить OW_SEND_ONE(), OW_SEND_ZERO() до
Код
#define OW_SEND_x3()    DDRD|=(1<<DDD0);\
                        DELAY_US(t1);\
                        DDRD&=~(1<<DDD0);\
                        DELAY_US(t2)

А можно просто в конфе поискать тома понаписатого про ванварь...
ks007
Спасибо огромное, все заработало. Это мой первый опыт с 1-wire.
Палыч тебе особое спасибо, без твоих подсказок я бы еще долго разбирался, теперь я понял как я тупил.
PS:кому нужны исходники могу поделиться.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.