Перейти к содержанию
    

Програмный 1-wire на прерываниях таймера

Вы наверное перепутали: наверное всё-таки в режиме захвата (capture), а не сравнения (compare). :rolleyes:

Почему? Именно по сравнению: как только заданный период прошёл (счётчик таймера сравнялся с указанным значением сравнения), формируется прерывание, в котором регистр сравнения перенастраивается на следующий интервал, а лапка дергается в соответствующую сторону :laughing:

А захват - это защёлкивание текущего значения таймера по какому-либо событию, как я понимаю эту всю кухню.

 

Хотя, кстати, да, можно (скорее нужно) делать по захвату. Дёрнулась лапка - захватили значение таймера и проконтролировали рамки прихода ожидаемого фронта...

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, попутно тут хочу узнать, как красиво организовать счётчик, который считает до, например, 5 и сбрасывается в 0 без условия if(). Ну то есть вычитая, сдвигая... Интересно можно ли так сделать. Для ровных битовых чисел, как в коде выше, как видно, я битовой маской обнуляю. А вот интересно, как быть с числами, не являющихся степенями 2.

int i, i1;
i1 = i - 5 >> 31;
i = i - i1 & i1;

Будет 3 или 4 команды (в зависимости от оптимизации).

 

Почему? Именно по сравнению: как только заданный период прошёл (счётчик таймера сравнялся с указанным значением сравнения), формируется прерывание, в котором регистр сравнения перенастраивается на следующий интервал, а лапка дергается в соответствующую сторону :laughing:

А чтение значения ноги когда?

Если по этому прерыванию, то так делать - ненадёжно, так как будет зависимо от задержек входа в ISR. К тому же - требует в 2 раза большей частоты прерываний.

 

А захват - это защёлкивание текущего значения таймера по какому-либо событи'юю, как я понимаю эту всю кухню.

Вот именно. А потом анализируем защёлкнутое значение и решаем что это было - 0 или 1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

int i, i1;
i1 = i - 5 >> 31;
i = i - i1 & i1;

Будет 3 или 4 команды (в зависимости от оптимизации).

Благодарю! Потестирую :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Благодарю! Потестирую :)

Можно ещё проще, но значения чисел будут не через 1, а через большие промежутки. Типа так:

#define LIMIT 5
#define STEP ((u32)(((1u << 31) + LIMIT - 1) / LIMIT))  //значение шага округлённое до ближайшего бОльшего целого
u32 i;
i = __USAT(i + STEP, 31);

Всего две операции. ;) Значения шагов будут: STEP*0, STEP*1, STEP*2, STEP*3, STEP*4, а на следующем шаге получим опять STEP*0.

Для switch-а такие значения конечно неудобны. :(

 

Ещё вариант - использовать отрицательный диапазон чисел:

enum {LIMIT = 5};
int i = -LIMIT;
i -= i >> 31 | LIMIT; //-5,-4,-3,-2,-1,0

Всего 3 операции B)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще не понимаю здешних товарищей, которые пытаются колхозить на чём угодно, только не делать как надо. :cranky:

RTOS

предлагаете всё в SysTick вешать, у которого наивысший приоритет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

предлагаете всё в SysTick вешать, у которого наивысший приоритет?

Вы наверно удивитесь, но в RTOS системному таймеру SysTick назначают как раз самый низкий приоритет (наравне с PendSV - переключатель контекста)

И вообще, если не используется RTOS, то ничего не мешает настроить Systick так, чтобы использовать его как самый простой аппаратный таймер, только назначив уже нужный приоритет.

Именно так я сделал в примитивных проектах, где RTOS ни к чему, но нужны простые временные выдержки, в частности с кратностью 1us и 1ms. Systick отлично для этого подходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

предлагаете всё в SysTick вешать, у которого наивысший приоритет?

SysTick то тут при чём???? :wacko: Само собой оптимально делается - на режиме захвата таймера.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Опыт общения с протоколом 1-Wire говорит о том, что самой правильной является реализация с использованием мостов, специально предназначенным для этого. Для I2C это DS2482-100 для одного канала (73,38 руб за 2 штуки на алиэкспрессе) и DS2482-800 для 8 каналов (464,25 за 2 штуки ), для UART это DS2480 (54,7 руб там же). Есть рабочие программные реализации для MCS-51 и STM32 на задержках и на таймере, но при использовании нескольких прерываний при отсутствии синхросигнала (как в других протоколах) тайминги могут не соблюдаться тем не менее.  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Andy_ry сказал:

Для I2C

Что-то недопонял, Вы на I2C 1-Wire реализовывали?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я на мостах DS2482 1-Wire реализовал. А сами мосты имеют интерфейс I2C с микроконтроллером. И, поскольку I2C полностатический протокол (нет тактового - нет передачи, есть тактовый - передача продолжается) то может прерываться в любой момент.

https://www.maximintegrated.com/en/app-notes/index.mvp/id/126

Изменено пользователем Andy_ry
Добавление ссылки

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...