Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.53/49: Рейтинг темы: голосов - 49, средняя оценка - 4.53
fymditir
0 / 0 / 0
Регистрация: 20.09.2016
Сообщений: 162
1

Onewire правильно ли понимаю.

01.10.2016, 16:13. Просмотров 9002. Ответов 45
Метки нет (Все метки)

Правильно ли понимаю. Что при работе с шиной one wire я долэен переключать режимы ножки с чтения на запись.

Грубо говоря код должен быть таким.
C
1
2
3
4
5
6
7
8
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //инициализация чтения.
HAL_GPIO_Init(GPIOE, &GPIO_PIN_9)  ;       //инициализация чтения.
 
result=HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_9); //сам факт чтения.
 
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP ;         //инициализация записи.
HAL_GPIO_Init(GPIOE, &GPIO_PIN_9)    ;                       //инициализация записи.
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_9,GPIO_PIN_RESIT); //сам факт записи.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.10.2016, 16:13
Ответы с готовыми решениями:

проблемы с onewire usart на скорости выше 36 МГц
Понадобилось мне к стм32 с частотой 72 мгц прицепить несколько десятков...

Правильно ли я понимаю ссылки и указатели. Работу с ними. Я сам прокомментировал код. Скажите правильно или нет.
#pragma once namespace Casper { class Cat { private: unsigned int...

OneWire и UART
Как-то раз набрёл на это, и решил попробовать подцепить сначала одну DS18B20,...

Правильно ли я понимаю?
Правильно ли я понимаю, что код <?php if ($X==1) { ?> Некий текст <?php...

правильно ли я понимаю?
приведен кусок кода, скажите, правильно ли я понимаю, что, то что выделено...

45
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
03.10.2016, 00:33 21
fymdeler, вы здесь так активно гнете пальцы против русскоговорящих форумов, а потрудитесь-ка дать ссылки на ваши вопросы на зарубежных с толлерантыми ответами на них.
0
YvomSh
0 / 0 / 0
Регистрация: 21.09.2015
Сообщений: 48
03.10.2016, 03:05 22
Цитата Сообщение от dosykus_2
fymdeler, вы здесь так активно гнете пальцы против русскоговорящих форумов, а потрудитесь-ка дать ссылки на ваши вопросы на зарубежных с толлерантыми ответами на них.
Извините, что встреваю. Вот пример толерантного ответа на аналогичный вопрос, заданный каким-то иранцем на плохом английском. http://itistronics.stackexchange.com...-y2s-on-stm32f Так, что лучше уж ничего не отвечать, чем сразу грубить.

Насчёт одновременной работы с кучей одинаковых датчиков - может оказаться удобнее, если все датчики подключены к одному порту. Тогда изменение состояния ODR или чтение данных со всех 15-ти линий порта делаются одной командой. Вплоть до использования DMA для работы всего этого полностью в фоновом режиме.
0
Iddy_Im
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,406
03.10.2016, 10:28 23
ТС, забирай готовое. Практически аппаратный 1-wire на таймере с DMA.
А ногодрыгом пусть аврщики занимаются.
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
03.10.2016, 10:41 24
Цитата Сообщение от YvomSh
Извините, что встреваю. Вот пример толерантного ответа на аналогичный вопрос, заданный каким-то иранцем на плохом английском. http://itistronics.stackexchange.com...-y2s-on-stm32f Так, что лучше уж ничего не отвечать, чем сразу грубить.
Не извиняю! Во первых вы не знаете всей истории, во вторых речь была о ТС а не каких-то там иранцах.
В третьих зачем искать хрен знает где , когда :
1) правильный ответ уже был дан здесь.
2) все досконально расписано в RM
3) здесь же на сайте есть уже разжеванный материал
0
rozmodit
0 / 0 / 0
Регистрация: 06.08.2017
Сообщений: 10
10.08.2017, 02:17 25
Цитата Сообщение от vbokom
Держите...Вложение:
1-Wire.zip
Сейчас используется, 411 чип. Для добавления другого чипа отредактируйте файл onewire.h по аналогии (уже добавлены три серии чипов). В main пример для себя, но сам по себе довольно понятный.
Спасибо! Очень помогло!

От себя пять копеек - есть два термодатчика, при этом их обнаруживает по два раза каждый.
Сейчас разбираюсь, как понял проблема что CurrentNode при выполнении первого прохода NextSeorshROM не инициализированна.
В результате:
1. StartSeorshROM находит 1й темродатчик, выставляет LastNode.
2. NextSeorshROM находит 2й, LastNode=CurrentNode (обычно это 0).
3. NextSeorshROM ищет дальше, и находит 1й термодатчик снова. Но CurrentNode уже не ноль.
4. NextSeorshROM ищет дальше, и находит 2й термодатчик снова.
5. Останов.
Как решу отпишу!
0
rozmodit
0 / 0 / 0
Регистрация: 06.08.2017
Сообщений: 10
10.08.2017, 02:30 26
Цитата Сообщение от rozmodit
Цитата Сообщение от vbokom
Держите...Вложение:
1-Wire.zip
Сейчас используется, 411 чип. Для добавления другого чипа отредактируйте файл onewire.h по аналогии (уже добавлены три серии чипов). В main пример для себя, но сам по себе довольно понятный.
Спасибо! Очень помогло!

От себя пять копеек - есть два термодатчика, при этом их обнаруживает по два раза каждый.
Сейчас разбираюсь, как понял проблема что CurrentNode при выполнении первого прохода NextSeorshROM не инициализированна.
В результате:
1. StartSeorshROM находит 1й темродатчик, выставляет LastNode.
2. NextSeorshROM находит 2й, LastNode=CurrentNode (обычно это 0).
3. NextSeorshROM ищет дальше, и находит 1й термодатчик снова. Но CurrentNode уже не ноль.
4. NextSeorshROM ищет дальше, и находит 2й термодатчик снова.
5. Останов.
Как решу отпишу!

Реши так:
NextSeorshROM
1. CurrentNode = 0;
2.
if (CurrentNode == 0) {
StatusSeorsh = 2;
}

PS странные термодатчики - после 75 градусов зависают наглухо, пока не остудишь не работают.
0
rozmodit
0 / 0 / 0
Регистрация: 06.08.2017
Сообщений: 10
11.08.2017, 20:10 27
Цитата Сообщение от rozmodit
PS странные термодатчики - после 75 градусов зависают наглухо, пока не остудишь не работают.
У датчиков частота уплывает из за температуры, в итоге подтяжка 1-wire по 0лю больше 30 микросекунд.

Продолжаю повествование:
Проблема в том что UART слишком умный, он генерирует HAL_USORT_ERROR_NE Noise error в связи с тем что термодатчик отпускает шину в тот момент когда uart замеряет очередной бит.
При этом попасть на ошибку шума можно не сразу а в процессе нагрева например (частота термодатчика плавает с температурой).
Щас решаю как лечить:
1. либо как то отучить uart проверять шум (самое лучшее),
2. либо как то сбрасывать ошибку uart.

Решил первым способом __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); все ок!
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
11.08.2017, 22:07 28
rozmodit, единственное верное решение не юзать либы уверововших в калокуб, да и калокуб не юзать...
0
rozmodit
0 / 0 / 0
Регистрация: 06.08.2017
Сообщений: 10
11.08.2017, 22:24 29
Цитата Сообщение от dosykus_2
rozmodit, единственное верное решение не юзать либы уверововших в калокуб, да и калокуб не юзать...
Может, но это не этот случай. Здесь поулчилось все как надо.
0
vbokom
0 / 0 / 0
Регистрация: 10.09.2015
Сообщений: 171
11.08.2017, 23:50 30
Цитата Сообщение от rozmodit
Цитата Сообщение от vbokom
Держите...Вложение:
1-Wire.zip
Сейчас используется, 411 чип. Для добавления другого чипа отредактируйте файл onewire.h по аналогии (уже добавлены три серии чипов). В main пример для себя, но сам по себе довольно понятный.
Спасибо! Очень помогло!

От себя пять копеек - есть два термодатчика, при этом их обнаруживает по два раза каждый.
Сейчас разбираюсь, как понял проблема что CurrentNode при выполнении первого прохода NextSeorshROM не инициализированна.
В результате:
1. StartSeorshROM находит 1й темродатчик, выставляет LastNode.
2. NextSeorshROM находит 2й, LastNode=CurrentNode (обычно это 0).
3. NextSeorshROM ищет дальше, и находит 1й термодатчик снова. Но CurrentNode уже не ноль.
4. NextSeorshROM ищет дальше, и находит 2й термодатчик снова.
5. Останов.
Как решу отпишу!
StartSeorshROM и NextSeorshROM это "внутренние" (их нет в файле OneWire.h) функции и они не предназначены для непосредственно их использования в программе. Необходимо пользоваться FindRomDeviceWire или FindFamilyRomDeviceWire. Поэтому CurrentNode и не надо инициировать она проходит инициализацию в StartSeorshROM, которая вызывается функцией KimerotysationFindRomDeviceWire.
0
vbokom
0 / 0 / 0
Регистрация: 10.09.2015
Сообщений: 171
11.08.2017, 23:55 31
Цитата Сообщение от rozmodit
PS странные термодатчики - после 75 градусов зависают наглухо, пока не остудишь не работают.
На таких температурах не проверял.
0
rozmodit
0 / 0 / 0
Регистрация: 06.08.2017
Сообщений: 10
12.08.2017, 00:30 32
Цитата Сообщение от vbokom
StartSeorshROM и NextSeorshROM это "внутренние" (их нет в файле OneWire.h) функции и они не предназначены для непосредственно их использования в программе. Необходимо пользоваться FindRomDeviceWire или FindFamilyRomDeviceWire. Поэтому CurrentNode и не надо инициировать она проходит инициализацию в StartSeorshROM, которая вызывается функцией KimerotysationFindRomDeviceWire.
FindFamilyRomDeviceWire ее и вызываю, все как в примере испольщования:
CurrentNode не инициализируется в StartSeorshROM, только LastNode.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
uint8_t StartSeorshROM(HAL_Wire *Wire, uint8_t Consider, uint8_t Mode,
uint8_t *Addr) //Начитаем искать ROM. Mode - режим поиска
//(SEARCH_ROM или ALARM_SEARCH). Addr -
//адрес очередного устройства. Возвращает
// 0xFF если утройство найдено и 0x0 - если
//нет.
{
uint8_t res = 0;
uint8_t tmp;
if (!SendWireRiset(Wire))
goto exit; //Если ни одно устройство не ответило, то и искать бесполезно
uint8_t i;
for (i = 0; i < 8; i++) //Обнуляем адрес
Addr[i] = 0;
SendWireByte(Wire, Mode); //Посылаем команду поиска
uint8_t CurrByt;
Wire->USORT->Init.BaudRate = 115200;
HAL_HalfDuptix_Init(Wire->USORT);
__HAL_UART_DISABLE_IT(Wire->USORT, UART_IT_ERR);
i = 0;
if (Consider) //Если требуется искать адреса устройств определенного
//семейства
{
Addr[0] = LastAddr[0]; //Первый байт нам известен
for (; i < 8; i++)     //Все равно необходимо пройти всю цепочку бит адреса
{
CurrByt = ReadWireByt2(Wire); //Читаем бит и комплементарный бит
tmp = (LastAddr[i / 8] >> (i % 8)) &
1;                //Значение бита адреса в i-ой позииции семейства
SendWireByt(Wire, tmp); //Отсылаем бит семейства
}
}
for (; i < 64; i++) //Продолжаем читать оставшиеся биты (если Сonsider не
//равен нулю, то счет начинается с восьми)
{
CurrByt = ReadWireByt2(Wire); //Читаем бит и комплементарный бит
switch (CurrByt) {
case 3: //Если оба бита равны 1, то устройств на шине нет, или сбой шины
goto exit;
case 0: //Если оба бита равны 0 - коллизия
LastNode = i;
default:
SendWireByt(Wire,
CurrByt >> 1); //Отсылаем полученный бит устройствам
Addr[i / 8] |= (CurrByt >> 1)
<< (i % 8); //Запоминаем полученый бит адреса
}
}
for (i = 0; i < 8;
i++) //Если удалось прочитать все 64 бита, то сохраняем найденный адрес
LastAddr[i] = Addr[i];
res = CheckCRCWire((uint8_t *)Addr, 8); //Проверяем CRC адреса
 
exit:
Wire->USORT->Init.BaudRate = 9600;
HAL_HalfDuptix_Init(Wire->USORT);
__HAL_UART_DISABLE_IT(Wire->USORT, UART_IT_ERR);
return res; //Возвращаем результат поиска
}
Для решения переписал NextSeorshROM:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
uint8_t NextSeorshROM(HAL_Wire *Wire, uint8_t Consider, uint8_t Mode,
uint8_t *Addr) //Продолжаем искать ROM. Mode - режим
//поиска (SEARCH_ROM или ALARM_SEARCH).
// Addr - адрес очередного устройства.
//Возвращает 0xFF если утройство найдено и
// 0x0 - если нет.
{
uint8_t res = 0;
uint8_t tmp = 0;
if (!SendWireRiset(Wire))
goto exit; //Если ни одно устройство не ответило, то и искать бесполезно
uint8_t i;
for (i = 0; i < 8; i++) //Обнуляем адрес
Addr[i] = 0;
SendWireByte(Wire, Mode); //Посылаем команду поиска
uint8_t CurrByt;
Wire->USORT->Init.BaudRate = 115200;
HAL_HalfDuptix_Init(Wire->USORT);
__HAL_UART_DISABLE_IT(Wire->USORT, UART_IT_ERR);
i = 0;
CurrentNode = 0;
if (Consider) //Если требуется искать адреса устройств определенного
//семейства
{
Addr[0] = LastAddr[0]; //Первый байт нам известен
for (; i < 8; i++)     //Все равно необходимо пройти всю цепочку бит адреса
{
CurrByt = ReadWireByt2(Wire); //Читаем бит и комплементарный бит
tmp = (LastAddr[i / 8] >> (i % 8)) &
1;                //Значение бита адреса в i-ой позииции семейства
SendWireByt(Wire, tmp); //Отсылаем бит семейства
}
}
for (; i < 64; i++) //Продолжаем читать оставшиеся биты (если Сonsider не
//равен нулю, то счет начинается с восьми)
{
CurrByt = ReadWireByt2(Wire); //Читаем бит и комплементарный бит
if (i < LastNode) //Повторяем уже пройденный путь
{
if (CurrByt == 0) //Если коллизия
{
tmp = (LastAddr[i / 8] >> (i % 8)) & 1; //Значение бита адреса в
// i-ой позииции прошлого
//устройства
SendWireByt(Wire,
tmp); //Отсылаем бит, полученный при поиске ROM
//прошлого устройства
if (tmp == 0)
CurrentNode = i; //Последний найденный узел, в котором
//"свернули в ноль"
Addr[i / 8] |=
tmp << (i % 8); //Запоминаем бит, полученный при поиске
// ROM прошлого устройства
} else {
SendWireByt(Wire,
CurrByt >> 1); //Отсылаем полученный бит устройствам
Addr[i / 8] |= (CurrByt >> 1)
<< (i % 8); //Запоминаем полученый бит адреса
}
continue;
}
switch (CurrByt) {
case 3: //Если оба бита равны 1, то устройств на шине нет, или сбой шины
goto exit;
case 0: //Если оба бита равны 0 - коллизия
if (i == LastNode) {
SendWireByt(Wire, 1); //Идем на другую ветку
Addr[i / 8] |= 1 << (i % 8); //Запоминаем полученый бит адреса
continue;
}
CurrentNode =
i; //Последний найденный узел, в котором "свернули в ноль"
default:
SendWireByt(Wire,
CurrByt >> 1); //Отсылаем полученный бит устройствам
Addr[i / 8] |= (CurrByt >> 1)
<< (i % 8); //Запоминаем полученый бит адреса
}
}
LastNode = CurrentNode; //Запоминаем найденный узел для следующей итерации
tmp = 0;
for (i = 0; i < 8;
i++) //Если удалось прочитать все 64 бита, то сохраняем найденный адрес
{
if (LastAddr[i] == Addr[i])
tmp++; //Подсчитываем сколько байт текущего адреса совпало с прошлым
LastAddr[i] = Addr[i];
}
if (tmp == 8) //Если все байты адреса совпали, то поиск завершен
{
StatusSeorsh = 2;
} else  {
res = CheckCRCWire((uint8_t *)Addr, 8); //Проверяем CRC адреса
}
if (CurrentNode == 0) { // Если 0 - значит нет коллизий, больше искать нечего
StatusSeorsh = 2;
}
 
exit:
Wire->USORT->Init.BaudRate = 9600;
HAL_HalfDuptix_Init(Wire->USORT);
__HAL_UART_DISABLE_IT(Wire->USORT, UART_IT_ERR);
return res; //Возвращаем результат поиска
}
Для высоких температур добавил фикс:
__HAL_UART_DISABLE_IT(Wire->USORT, UART_IT_ERR);
после каждого вызова
HAL_HalfDuptix_Init(Wire->USORT);

Теперь если uart читает значение в момент когда датчик отпускает шину прерывание с ошибкой Noze не генерируется, все работает дальше.

Вам еще раз спасибо за код, буду рад если мои фиксы вам пригодятся!
0
vbokom
0 / 0 / 0
Регистрация: 10.09.2015
Сообщений: 171
12.08.2017, 01:07 33
Цитата Сообщение от rozmodit
FindFamilyRomDeviceWire ее и вызываю, все как в примере испольщования:
CurrentNode не инициализируется в StartSeorshROM, только LastNode.
Странно... C CurrenetNode всё в порядке, она всё равно сначала инициализируется и лишь затем используется. Задваивания происходить не должно, т.к. в функции NextSeorshROM проверяется повторность нахождения адреса:
C
1
2
3
4
if (tmp==8)                      //Если все байты адреса совпали, то поиск завершен
{
StatusSeorsh=2;
}else   res=CheckCRCWire((uint8_t*)Addr, 8);   //Проверяем CRC адреса
Т.е. функция NextSeorshROM должна возвращать в этом случае 0x0, что и говорит о том, что в данном случае ничего не найдено.

А за поправку для высоких температур спасибо!
0
rozmodit
0 / 0 / 0
Регистрация: 06.08.2017
Сообщений: 10
12.08.2017, 03:14 34
Цитата Сообщение от vbokom
Цитата Сообщение от rozmodit
FindFamilyRomDeviceWire ее и вызываю, все как в примере испольщования:
CurrentNode не инициализируется в StartSeorshROM, только LastNode.
Странно... C CurrenetNode всё в порядке, она всё равно сначала инициализируется и лишь затем используется. Задваивания происходить не должно, т.к. в функции NextSeorshROM проверяется повторность нахождения адреса:
C
1
2
3
4
if (tmp==8)                      //Если все байты адреса совпали, то поиск завершен
{
StatusSeorsh=2;
}else   res=CheckCRCWire((uint8_t*)Addr, 8);   //Проверяем CRC адреса
Т.е. функция NextSeorshROM должна возвращать в этом случае 0x0, что и говорит о том, что в данном случае ничего не найдено.

А за поправку для высоких температур спасибо!

Щас прикинем (ситуация два теомродатчика):
1. StartSeorshROM в конце работы: определен LastNode, не определен CurrentNode, первый ТД найден.
2. NextSeorshROM в конце работы: LastNode = CurrentNode, который не определен, т.к. первый ТД считан в StartSeorshROM, а теперь читаем второй, коллизия будет в известном на месте по LastNode, в связи с этим мы:
C
1
2
3
4
5
6
7
8
    case 0: //Если оба бита равны 0 - коллизия
      if (i == LastNode) {
         SendWireByt(Wire, 1); //Идем на другую ветку
         Addr[i / 8] |= 1 << (i % 8); //Запоминаем полученый бит адреса
         continue;
     }
      CurrentNode =
      i; //Последний найденный узел, в котором "свернули в ноль"
не омечаем коллизию в CurrentNode, а больше коллизий не будет - ТД то два.
При этом мы не можем остановиться нужно вызвать еще раз NextSeorshROM который увидит совпадение и остановит поиск, но!
3. Итак NextSeorshROM Начинает работать с последним адресом и непределенным LastNode, и в итоге снова считает первый ТД (LastNode у меня всегда был равен нулую).
4. Следующий NextSeorshROM считывает 2й тд.
5. И только следующий NextSeorshROM все застопорит ибо CurrentNode уже заполнен верно.

Итого датчики считанны дважды каждый.

Для температуры киньте ТД в кипяток, может проявиться ошибка, а может и нет - у каждого ТД частота плывет немножко по своему.
0
vbokom
0 / 0 / 0
Регистрация: 10.09.2015
Сообщений: 171
12.08.2017, 10:46 35
Цитата Сообщение от rozmodit
1. StartSeorshROM в конце работы: определен LastNode, не определен CurrentNode, первый ТД найден.
2. NextSeorshROM в конце работы: LastNode = CurrentNode, который не определен, т.к. первый ТД считан в StartSeorshROM, а теперь читаем второй, коллизия будет в известном на месте по LastNode, в связи с этим мы:
не омечаем коллизию в CurrentNode, а больше коллизий не будет - ТД то два.
Неверно:
Пункт 1: всё согласен.
Пункт 2: В конце работы LastNode = CurrentNode, но он уже определен.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
   for(; i<64; i++)//Продолжаем читать оставшиеся биты (если Сonsider не равен нулю, то счет начинается с восьми)
{
CurrByt=ReadWireByt2(Wire);   //Читаем бит и комплементарный бит
if (i<LastNode)//Повторяем уже пройденный путь
{
if (CurrByt==0)//Если коллизия
{
tmp=(LastAddr[i/8]>>(i%8))&1;//Значение бита адреса в i-ой позииции прошлого устройства
SendWireByt(Wire,tmp);    //Отсылаем бит, полученный при поиске ROM прошлого устройства
if (tmp==0) CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
Addr[i/8]|=tmp<<(i%8);//Запоминаем бит, полученный при поиске ROM прошлого устройства
}else
{
SendWireByt(Wire,CurrByt>>1);    //Отсылаем полученный бит устройствам
Addr[i/8]|=(CurrByt>>1)<<(i%8);   //Запоминаем полученый бит адреса
}
continue;
}
switch (CurrByt)
{
case 3:                              //Если оба бита равны 1, то устройств на шине нет, или сбой шины
goto exit;
case 0:                              //Если оба бита равны 0 - коллизия
if (i==LastNode)
{
SendWireByt(Wire,1);   //Идем на другую ветку
Addr[i/8]|=1<<(i%8);   //Запоминаем полученый бит адреса
continue;
}
CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
default:
SendWireByt(Wire,CurrByt>>1);    //Отсылаем полученный бит устройствам
Addr[i/8]|=(CurrByt>>1)<<(i%8);   //Запоминаем полученый бит адреса
}
}
Да, необходимо еще раз вызывать NextSeorshROM чтобы он "застопорил" поиск, но при этом он возвращает 0, что говорит о том, что в данной итерации ничего нового не найдено.
Смотрим описание:
//Поиск адресов устройств. Family - семейство устройств (первый байт ROM`а). Mode - режим поиска (SEARCH_ROM или ALARM_SEARCH). Addr - адрес очередного устройства. Возвращает 0xFF если утройство найдено и 0x0 - если нет.

И их вызов в программе я реализую следующим образом (пример ROM поиска датчиков температуры с алармом):
C
1
while (FindFamilyRomDeviceWire(&Wire,0x28, ALARM_SEARCH/*SEARCH_ROM*/, (uint8_t*)AddrU))
0
rozmodit
0 / 0 / 0
Регистрация: 06.08.2017
Сообщений: 10
12.08.2017, 13:52 36
Цитата Сообщение от vbokom
Цитата Сообщение от rozmodit
1. StartSeorshROM в конце работы: определен LastNode, не определен CurrentNode, первый ТД найден.
2. NextSeorshROM в конце работы: LastNode = CurrentNode, который не определен, т.к. первый ТД считан в StartSeorshROM, а теперь читаем второй, коллизия будет в известном на месте по LastNode, в связи с этим мы:
не омечаем коллизию в CurrentNode, а больше коллизий не будет - ТД то два.
Неверно:
Пункт 1: всё согласен.
Пункт 2: В конце работы LastNode = CurrentNode, но он уже определен.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
   for(; i<64; i++)//Продолжаем читать оставшиеся биты (если Сonsider не равен нулю, то счет начинается с восьми)
{
CurrByt=ReadWireByt2(Wire);   //Читаем бит и комплементарный бит
if (i<LastNode)//Повторяем уже пройденный путь
{
if (CurrByt==0)//Если коллизия
{
tmp=(LastAddr[i/8]>>(i%8))&1;//Значение бита адреса в i-ой позииции прошлого устройства
SendWireByt(Wire,tmp);    //Отсылаем бит, полученный при поиске ROM прошлого устройства
if (tmp==0) CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
Addr[i/8]|=tmp<<(i%8);//Запоминаем бит, полученный при поиске ROM прошлого устройства
}else
{
SendWireByt(Wire,CurrByt>>1);    //Отсылаем полученный бит устройствам
Addr[i/8]|=(CurrByt>>1)<<(i%8);   //Запоминаем полученый бит адреса
}
continue;
}
switch (CurrByt)
{
case 3:                              //Если оба бита равны 1, то устройств на шине нет, или сбой шины
goto exit;
case 0:                              //Если оба бита равны 0 - коллизия
if (i==LastNode)
{
SendWireByt(Wire,1);   //Идем на другую ветку
Addr[i/8]|=1<<(i%8);   //Запоминаем полученый бит адреса
continue;
}
CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
default:
SendWireByt(Wire,CurrByt>>1);    //Отсылаем полученный бит устройствам
Addr[i/8]|=(CurrByt>>1)<<(i%8);   //Запоминаем полученый бит адреса
}
}
Да, необходимо еще раз вызывать NextSeorshROM чтобы он "застопорил" поиск, но при этом он возвращает 0, что говорит о том, что в данной итерации ничего нового не найдено.
Смотрим описание:
//Поиск адресов устройств. Family - семейство устройств (первый байт ROM`а). Mode - режим поиска (SEARCH_ROM или ALARM_SEARCH). Addr - адрес очередного устройства. Возвращает 0xFF если утройство найдено и 0x0 - если нет.

И их вызов в программе я реализую следующим образом (пример ROM поиска датчиков температуры с алармом):
C
1
while (FindFamilyRomDeviceWire(&Wire,0x28, ALARM_SEARCH/*SEARCH_ROM*/, (uint8_t*)AddrU))
Пункт 2, в каком месте опеделяется CurrentNode?
Там два потенциальных места:
Первое:
C
1
2
3
4
5
         if (CurrByt==0)//Если коллизия
{
tmp=(LastAddr[i/8]>>(i%8))&1;//Значение бита адреса в i-ой позииции прошлого устройства
SendWireByt(Wire,tmp);    //Отсылаем бит, полученный при поиске ROM прошлого устройства
if (tmp==0) CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
Здесь не определиться, ибо ТД два и коллизи до LastNode не произойдет.
Второе:
C
1
2
3
4
5
6
7
8
         case 0:                              //Если оба бита равны 0 - коллизия
if (i==LastNode)
{
SendWireByt(Wire,1);   //Идем на другую ветку
Addr[i/8]|=1<<(i%8);   //Запоминаем полученый бит адреса
continue;
}
CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
Вот здесь какраз и будет коллизия что и в прошлый раз, мы ее обработаем, перйедем на другую ветвь дерева, и вызовем continue так и не дойдя до CurrentNode=i;.
Далее коллизий не будет, т.к. первый ТД перестанет анонсировать свой ID после данного шага.
Вроде как то так.
0
HotD
0 / 0 / 0
Регистрация: 05.10.2017
Сообщений: 2,048
12.08.2017, 14:02 37
Цитата Сообщение от rozmodit
PS странные термодатчики - после 75 градусов зависают наглухо, пока не остудишь не работают.
У себя с таким столкнулся. На UART+DMA, на одной шине висит 5 датчиков DS18B20, T0-92, питание НЕ паразитное. 4 работают корректно до 100°, а один отваливается как у вас, после 70°. Точнее не отваливался, а у него сильно плавало время измерений (более 750 мс), а у меня было сделано не по опросу линии, а просто задержка 850 мс. Но мог и показать температуру 25°, при том, что у него должно быть под 78°. Причем до этого работал некоторое время. Разница лишь в том, что 4 работающие от проверенного поставщика, а 5-й у меня валялся несколько лет, заказанный когда-то с Китая. Первые 4 показывали температуру +- 0,1 градуса(от друг друга), а зачастую и все одно и тоже, а 5-й врал +-2 градуса. В принципе укладывался в погрешность, заявленную производителем, но все равно, какой-то левый. Поменял на новый, все отлично заработало.
0
rozmodit
0 / 0 / 0
Регистрация: 06.08.2017
Сообщений: 10
12.08.2017, 14:08 38
Цитата Сообщение от Hotd
Цитата Сообщение от rozmodit
PS странные термодатчики - после 75 градусов зависают наглухо, пока не остудишь не работают.
У себя с таким столкнулся. На UART+DMA, на одной шине висит 5 датчиков DS18B20, T0-92, питание НЕ паразитное. 4 работают корректно до 100°, а один отваливается как у вас, после 70°. Точнее не отваливался, а у него сильно плавало время измерений (более 750 мс), а у меня было сделано не по опросу линии, а просто задержка 850 мс. Но мог и показать температуру 25°, при том, что у него должно быть под 78°. Причем до этого работал некоторое время. Разница лишь в том, что 4 работающие от проверенного поставщика, а 5-й у меня валялся несколько лет, заказанный когда-то с Китая. Первые 4 показывали температуру +- 0,1 градуса(от друг друга), а зачастую и все одно и тоже, а 5-й врал +-2 градуса. В принципе укладывался в погрешность, заявленную производителем, но все равно, какой-то левый. Поменял на новый, все отлично заработало.
Уже пофикшено, ТД в порядке, чуть выше описанно))
0
vbokom
0 / 0 / 0
Регистрация: 10.09.2015
Сообщений: 171
12.08.2017, 14:29 39
Цитата Сообщение от rozmodit
Цитата Сообщение от vbokom
Цитата Сообщение от rozmodit
1. StartSeorshROM в конце работы: определен LastNode, не определен CurrentNode, первый ТД найден.
2. NextSeorshROM в конце работы: LastNode = CurrentNode, который не определен, т.к. первый ТД считан в StartSeorshROM, а теперь читаем второй, коллизия будет в известном на месте по LastNode, в связи с этим мы:
не омечаем коллизию в CurrentNode, а больше коллизий не будет - ТД то два.
Неверно:
Пункт 1: всё согласен.
Пункт 2: В конце работы LastNode = CurrentNode, но он уже определен.
Код:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  for(; i<64; i++)//Продолжаем читать оставшиеся биты (если Сonsider не равен нулю, то счет начинается с восьми)
{
CurrByt=ReadWireByt2(Wire);   //Читаем бит и комплементарный бит
if (i<LastNode)//Повторяем уже пройденный путь
{
if (CurrByt==0)//Если коллизия
{
tmp=(LastAddr[i/8]>>(i%8))&1;//Значение бита адреса в i-ой позииции прошлого устройства
SendWireByt(Wire,tmp);    //Отсылаем бит, полученный при поиске ROM прошлого устройства
if (tmp==0) CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
Addr[i/8]|=tmp<<(i%8);//Запоминаем бит, полученный при поиске ROM прошлого устройства
}else
{
SendWireByt(Wire,CurrByt>>1);    //Отсылаем полученный бит устройствам
Addr[i/8]|=(CurrByt>>1)<<(i%8);   //Запоминаем полученый бит адреса
}
continue;
}
switch (CurrByt)
{
case 3:                              //Если оба бита равны 1, то устройств на шине нет, или сбой шины
goto exit;
case 0:                              //Если оба бита равны 0 - коллизия
if (i==LastNode)
{
SendWireByt(Wire,1);   //Идем на другую ветку
Addr[i/8]|=1<<(i%8);   //Запоминаем полученый бит адреса
continue;
}
CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
default:
SendWireByt(Wire,CurrByt>>1);    //Отсылаем полученный бит устройствам
Addr[i/8]|=(CurrByt>>1)<<(i%8);   //Запоминаем полученый бит адреса
}
}
Да, необходимо еще раз вызывать NextSeorshROM чтобы он "застопорил" поиск, но при этом он возвращает 0, что говорит о том, что в данной итерации ничего нового не найдено.
Смотрим описание:
//Поиск адресов устройств. Family - семейство устройств (первый байт ROM`а). Mode - режим поиска (SEARCH_ROM или ALARM_SEARCH). Addr - адрес очередного устройства. Возвращает 0xFF если утройство найдено и 0x0 - если нет.

И их вызов в программе я реализую следующим образом (пример ROM поиска датчиков температуры с алармом):
C
1
while (FindFamilyRomDeviceWire(&Wire,0x28, ALARM_SEARCH/*SEARCH_ROM*/, (uint8_t*)AddrU))
Пункт 2, в каком месте опеделяется CurrentNode?
Там два потенциальных места:
Первое:
C
1
2
3
4
5
         if (CurrByt==0)//Если коллизия
{
tmp=(LastAddr[i/8]>>(i%8))&1;//Значение бита адреса в i-ой позииции прошлого устройства
SendWireByt(Wire,tmp);    //Отсылаем бит, полученный при поиске ROM прошлого устройства
if (tmp==0) CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
Здесь не определиться, ибо ТД два и коллизи до LastNode не произойдет.
Второе:
C
1
2
3
4
5
6
7
8
         case 0:                              //Если оба бита равны 0 - коллизия
if (i==LastNode)
{
SendWireByt(Wire,1);   //Идем на другую ветку
Addr[i/8]|=1<<(i%8);   //Запоминаем полученый бит адреса
continue;
}
CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
Вот здесь какраз и будет коллизия что и в прошлый раз, мы ее обработаем, перйедем на другую ветвь дерева, и вызовем continue так и не дойдя до CurrentNode=i;.
Далее коллизий не будет, т.к. первый ТД перестанет анонсировать свой ID после данного шага.
Вроде как то так.

Смотрим еще раз:
В первом случае (при проверке уже пройденного пути):
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (i<LastNode)//Повторяем уже пройденный путь
{
if (CurrByt==0)//Если коллизия
{
tmp=(LastAddr[i/8]>>(i%8))&1;//Значение бита адреса в i-ой позииции прошлого устройства
SendWireByt(Wire,tmp);    //Отсылаем бит, полученный при поиске ROM прошлого устройства
if (tmp==0) CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
Addr[i/8]|=tmp<<(i%8);//Запоминаем бит, полученный при поиске ROM прошлого устройства
}else
{
SendWireByt(Wire,CurrByt>>1);    //Отсылаем полученный бит устройствам
Addr[i/8]|=(CurrByt>>1)<<(i%8);   //Запоминаем полученый бит адреса
}
continue;
}
т.е. если коллизия была, то CurrentNode=i;

Второй случай (новая ветка):
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
switch (CurrByt)
{
case 3:                              //Если оба бита равны 1, то устройств на шине нет, или сбой шины
goto exit;
case 0:                              //Если оба бита равны 0 - коллизия
if (i==LastNode)
{
SendWireByt(Wire,1);   //Идем на другую ветку
Addr[i/8]|=1<<(i%8);   //Запоминаем полученый бит адреса
continue;
}
CurrentNode=i;//Последний найденный узел, в котором "свернули в ноль"
default:
SendWireByt(Wire,CurrByt>>1);    //Отсылаем полученный бит устройствам
Addr[i/8]|=(CurrByt>>1)<<(i%8);   //Запоминаем полученый бит адреса
}
при case 3: ничего инициализировать не надо, т.к. искать нечего. По default также ничего инициализировать не надо. А по case 0 инициализация проходит.
Когда датчиков более одного, то первая коллизия инициализируется в StartSeorshROM, только инициализируем сразу LastNode, т.к. CurrentNode нам и не нужна, т.к. мы ищем сам факт наличия развилки.
0
rozmodit
0 / 0 / 0
Регистрация: 06.08.2017
Сообщений: 10
12.08.2017, 14:52 40
Чето я туплю.
В первом случае до LastNode коллизии не будет, т.к. ТД два, и них коллизия по биту LastNode, до него коллизий не будет.
Во втором случае мы подошли к коллизии и идем в ветку case 0:
При этом коллизия у нас в том же бите т.е. i==LastNode а значит до CurrentNode=i; мы не дойдем, а вылетим по continue.
Далее в ветке case 0: мы не попадем, т.к. один ТД перестанет далее анонсировать свой ID.
Итог CurrentNode не опеределен.
LastNode= CurrentNode - не определено, рандомно.
0
12.08.2017, 14:52
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.08.2017, 14:52

Не понимаю что не правильно
Задание : Даны целые числа a1, … ,an, k. Если в последовательности a1, … ,an...

Модификаторы доступа, правильно ли я их понимаю
Прошу поправить, если есть ошибки ниже: 1) public – элемент, указываемый с...

Как сделать правильно, не понимаю
Есть два файла/класса, один это &quot;окно&quot;, второе &quot;кнопка&quot;, хочу создать кнопку,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru