Aner 7 26 сентября, 2018 Опубликовано 26 сентября, 2018 · Жалоба Потому вы и есть любители, не разу не прошедшие сертификацию ваших поделок - недоделок. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rx3apf 0 26 сентября, 2018 Опубликовано 26 сентября, 2018 · Жалоба Т.е. по делу сказать нечего ? Кто б сомневался... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 26 сентября, 2018 Опубликовано 26 сентября, 2018 · Жалоба При отсутствии аппаратного 1wire принято использовать uart https://www.maximintegrated.com/en/app-note...ndex.mvp/id/214 Кем принято? Открываем указанную ссылку, читаем: Для сброса и обнаружения устройства нужно послать код 0xF0 на скорости 9600. И: 1) "если устройства нет, то на RX получим 0xF0"; Утверждение не вызывает сомнения. 2) "если устройство есть, то на RX получим что-то отличное от 0xF0"; А вот тут уже - фиг вам! Открываем описание интерфейса 1-wire, читаем: Чтобы сформировать сигнал «Reset», — «Мастер» должен притянуть уровень на шине к нулю на время не менее 480 мкс и не более 960 мкс (480 мкс ≤ TRSTL < 960 мкс). После этого он должен отпустить шину и, не менее, чем на 480 мкс, прекратить свою активность на шине (TRSTH > 480 мкс). «Слэйвы», не ранее, чем через 15 мкс, но и не позднее, чем через 60 мкс после того, как «Мастер» отпустит шину (15 мкс < TPDH < 60 мкс), должны сформировать на шине низкий уровень (это и есть сигнал присутствия), длительностью от 60 до 240 мкс (60 мкс < TPDL < 240 мкс), после чего они также отпускают шину. Оп-ля - приехали! :05: При скорости 9600 длительность бита == 104мкс. Предположим что частоты генераторов мастера и слэйва идеально совпадают. Тогда, после завершения передачи мастером младших 4-х бит кода 0xF0, на шине наступит фронт сигнала. И в это время UART мастера начнёт приём 4-го бита. Точка сэмплирования этого бита находится на расстоянии 104/2=52мкс от указанного фронта (конца RESET). Но ведь из описания выше следует, что слэйв имеет право начать формировать сигнал присутствия через 60мкс после завершения RESET. Т.е. - уже после того как мастер считает с шины состояние 4-го бита! И мастер получит в 4-м бите лог.1. :smile3009: Окей, ладно - может хоть в следующем бите мастер сможет узреть на шине несчастного слэйва?? :fman: Но опять же - из описания выше можно узнать, что сигнал присутствия генерируемый слэйвом, может быть длительностью всего 60мкс. Но ведь мы помним, что между точками сэмплирования RX-битов мастером расстояния == 104 мкс (1 бит UART). Получается, что если импульс присутствия начнётся через 60 мкс после конца RESET и продлится всего 60 мкс, то он аккурат проскочит между двумя точками сэмплирования UART.RX мастера. И мастер его просто не заметит! Хотя мальчик-то есть, но вот колхоз на UART его не видит.... :crying: А значит такую реализацию уже нельзя считать 1-wire. Ну никак нельзя. И это мы ещё даже не учли влияния разности частот генераторов мастера и слэйва, а также влияние ёмкости линии. А также не учли, что делитель UART-а может быть дробным (а длина бита UART - переменной). Там будет ещё веселее. После этого дальше читать указанную ссылку смысла уже нет. Да этому "стандарту" уже почти 30 лет, обсосан до костей. Тайминги такие, что заведется с полпинка на любом античном МК даже на встроенном RC-генераторе. Да ладно? Не будем углубляться в приём/передачу, но раз "обсосан", то объясните как с помощью UART хотя-бы обнаружить такой слэйв-девайс, который в полном соответствии с мануалом, формирует импульс присутствия с началом через 15...60 мкс после завершения RESET, и длительностью 60...240 мкс? Это ведь как ловить рыбку сетью, у которой размер ячеи больше размера самой рыбки - конечно есть вероятность что поймаешь, но можно и с голоду опухнуть :biggrin: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 27 сентября, 2018 Опубликовано 27 сентября, 2018 · Жалоба то объясните как с помощью UART хотя-бы обнаружить такой слэйв-девайс,Я не использую для этого UART, для этого есть аппаратные таймеры. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Smen 3 27 сентября, 2018 Опубликовано 27 сентября, 2018 · Жалоба для этого есть аппаратные таймерыТ.е. используются и таймеры и УАРТ? В чём смысл? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 27 сентября, 2018 Опубликовано 27 сентября, 2018 · Жалоба Т.е. используются и таймеры и УАРТ?Цитирую: Я не использую для этого UART Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VAI 0 27 сентября, 2018 Опубликовано 27 сентября, 2018 · Жалоба Когда-то я выкладывал сюда код, работающий на STM32 и на MSP430. Вот, смотрите, может подойдёт для Вас. http://electronix.ru/forum/index.php?showt...p;#entry1089884 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 27 сентября, 2018 Опубликовано 27 сентября, 2018 · Жалоба 1-Wire вполне себе реализовывался на SPI 32bit. Правда, делал его на древнем уже LPC2103 Главное - пин MOSI правильно настроить, чтобы только вниз тянул, push-pull отключить, если возможно, или сгородить на двух транзисторах Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 27 сентября, 2018 Опубликовано 27 сентября, 2018 · Жалоба 1-Wire вполне себе реализовывался на SPI 32bit. Правда, делал его на древнем уже LPC2103 Главное - пин MOSI правильно настроить, чтобы только вниз тянул, push-pull отключить, если возможно, или сгородить на двух транзисторах Лучше вот такая схема: По I2C работает идеально. ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 27 сентября, 2018 Опубликовано 27 сентября, 2018 · Жалоба Лучше вот такая схема: По I2C работает идеально. ;) Не, ну кто бы спорил :) Вопрос в том, что у меня без всяких +200р к стоимости девайса... Хотя, если ценник ему ковырнадцать тысяч, то и DS2484 вполне себе уместна :biggrin: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Integro 0 27 сентября, 2018 Опубликовано 27 сентября, 2018 · Жалоба Красивый выход из прерывания с переключением контекста Вам нужно посмотреть на примеры реализации механизма callback. Вкратце, реализовываете функцию для настройки таймера в one shot режиме и в прерывании таймера (через n us) вызываете необходимый вам callback static void (*_cb)(void) = NULL; void TIMERn_Handler(void) { // TODO: Clear timer status or stop if neccesary if( _cb ) { _cb(); } } void setup_timer(uint32_t delay_us, void *callback ) { _cb = callback ; //TODO: configure hardware timer } Далее, набрасываем функции которые будут вызываться последовательно: static void _save_t1(void); static void _reset(void); void start(void) { Switch_Out(); setup_timer(480, _reset); } static void _reset(void) { Switch_In(); setup_timer(80, _save_t1); } static void _save_t1(void) { Ack[0]=T1; //TODO ... if(Ack[0] == 1) { setup_timer(80, _something1); } else { setup_timer(10, _something2); } } Думаю суть ясна, для начала транзакиции нужно вызвать start(), а дальше все пойдет по реализованной вами цепочке. Если таких "прижков" выйдет много, локаничней релизовать таблицы для "линейных участков": static struct { uinr32_t delay_us; void *next_cb; }_chain_init[] = { {.delay_ms = 480, .next_cb = _reset}, {.delay_ms = 80, .next_cb = _save_t1}, }; Пользовать это можно так: index++; setup_timer(_chain_init[index].delay_ms , _chain_init[index].next_cb); Ну и понятно функция setup_timer, должны бать быстрой, что бы не поплыли микросекундные тайминги. Код писал без проверки компиляции, так что извиняйте за описки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 5 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба Решение на uart 1wire Отлично работает даже с usb-uart преобразователем CP2102. CP2102 работает без кварца и скорее всего подстраивает частоту по SOF кадрам, думаю там разброс больше чем 20 ppm. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба Решение на uart 1wire Отлично работает даже с usb-uart преобразователем CP2102.Кроме пустословия, по делу, есть что сказать? Ещё раз читаем: Почему UART - не 1-wire CP2102 скорее всего подстраивает частоту по SOF кадрам.Бред. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба Не знаю, зачем выделять на это целый UART... Я сделал на таймере в режиме сравнения. Благодаря этому можно использовать любую ножку свободную на МК. Обработчик таймера: #define T1 4 #define T2 7 #define T3 51 #define T4 59 #define T5 89 #define T6 409 #define T7 499 // TypeOperation - тип запрашиваемой операции: // ONE_WIRE_INIT - формирование импульса сброса; // ONE_WIRE_GET_TIME_SLOT - формирование тайм-слота чтения; // ONE_WIRE_SET_TIME_SLOT_0 - формирование тайм-слота записи лог. 0; // ONE_WIRE_SET_TIME_SLOT_0 - формирование тайм-слота записи лог. 1. // // ResultOperation - результат чтения тайм-слота (только при чтении). // // StatusOperation - флаг завершенности работы автомата. // // Перед использованием автомата необходимо указать тип операции и включить // таймер TIMER_START(). Затем дождаться завершения работы автомата. void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) { static unsigned char FSMState = 0; switch(TypeOperation) { // автомат формирования импульса сброса case ONE_WIRE_INIT: { switch(FSMState) { case 0: TIM2->ARR = T7; RESET_LINE(WIRE); break; case 1: TIM2->ARR = T5; SET_LINE(WIRE); break; case 2: TIM2->ARR = T6; ResultOperation = GET_LINE(WIRE); break; case 3: TIMER_STOP(); TIM2->ARR = T1; StatusOperation = 1; break; } FSMState = (FSMState + 1) & 0x3; break; } // автомат формирования тайм-слота чтения case ONE_WIRE_GET_TIME_SLOT: { switch(FSMState) { case 0: TIM2->ARR = T1; RESET_LINE(WIRE); break; case 1: TIM2->ARR = T2; SET_LINE(WIRE); break; case 2: TIM2->ARR = T3; ResultOperation = GET_LINE(WIRE); break; case 3: TIMER_STOP(); TIM2->ARR = T1; StatusOperation = 1; break; } FSMState = (FSMState + 1) & 0x3; break; } // автомат формирования тайм-слота записи case ONE_WIRE_SET_TIME_SLOT_0: case ONE_WIRE_SET_TIME_SLOT_1: { switch(FSMState) { case 0: TIM2->ARR = (TypeOperation == HW_ONE_WIRE_SET_TIME_SLOT_0) ? T4 : T1; RESET_LINE(GPIO_ONE_WIRE); break; case 1: TIM2->ARR = (TypeOperation == HW_ONE_WIRE_SET_TIME_SLOT_0) ? T1 : T4; SET_LINE(GPIO_ONE_WIRE); break; case 2: TIMER_STOP(); TIM2->ARR = T1; ++FSMState; StatusOperation = 1; break; } FSMState = (FSMState + 1) & 0x3; break; } } TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } } } Кстати, попутно тут хочу узнать, как красиво организовать счётчик, который считает до, например, 5 и сбрасывается в 0 без условия if(). Ну то есть вычитая, сдвигая... Интересно можно ли так сделать. Для ровных битовых чисел, как в коде выше, как видно, я битовой маской обнуляю. А вот интересно, как быть с числами, не являющихся степенями 2. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 28 сентября, 2018 Опубликовано 28 сентября, 2018 · Жалоба Не знаю, зачем выделять на это целый UART... Я сделал на таймере в режиме сравнения. Вы наверное перепутали: наверное всё-таки в режиме захвата (capture), а не сравнения (compare). :rolleyes: Да, это стандартное решение. Вообще не понимаю здешних товарищей, которые пытаются колхозить на чём угодно, только не делать как надо. :cranky: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться