реклама на сайте
подробности

 
 
> Програмный 1-wire на прерываниях таймера, Красивый выход из прерывания с переключением контекста
pokk
сообщение Sep 25 2018, 09:18
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



Моя первая реазилация 1-wire была на прерываниях от таймера и чисто на switch case,
это было дикая спагетти кода, потом частично завернул в функции, но все равно не нравилось как получилось,
последний раз написал на protothreads, уже как-то глаз радует, а теперь сижу и опять не доволен
не охото к каждому проекту пихать protothreads, + оборачивать макросами PT_BEGIN,PT_END

Как можно красиво написать похожее чисто на си ? Думаю в сторону переключения адреса, но как это сделать красиво ?
на protothreads получилось такое:
Код
//PT_YIELD(pt); - выход из функции, + сохранение место выхода
#define SetDelay_us(value) TCCR3B=0x01; TCNT3H=(0xFFFF-value*(CPU_CLK/1000000))>>8;\
                           TCNT3L=(0xFFFF-value*(CPU_CLK/1000000));\
                           PT_YIELD(pt);\    

PT_THREAD(Wire_Reset_thread(struct pt *pt,unsigned char *ReturnValue)){
static unsigned short int Ack[2];
PT_BEGIN(pt);
    //---------------------------------------------
    Ack[0]=0;
    Ack[1]=0;
    //--Переключаем линию на выход и записываем 0--
    Switch_Out();
    SetDelay_us(480);
    //--Переключаем линию на выход-----------------
    Switch_In();
    //---------------------------------------------
    SetDelay_us(80);
    //---------------------------------------------
    Ack[0]=T1;
    //---------------------------------------------
    SetDelay_us(250);
    //---------------------------------------------
    Ack[1]=T1;
    //---------------------------------------------
    if((Ack[0] == 0)&&(Ack[1] ==1)){
        *ReturnValue=SENSOR_INIT_VALIDATION_SUCCESS;
    }else{
        //------------------------------------------------------------------------------------------
        //*ReturnValue=SENSOR_INIT_VALIDATION_FAIL;
        if((Ack[0]==1)&&(Ack[1]==1)){
            *ReturnValue=TYPE_T_SHORT_CIRCUIT_1;
        }else{
            *ReturnValue=TYPE_T_SHORT_CIRCUIT_0;
        }
        //------------------------------------------------------------------------------------------
    }
    //---------------------------------------------
PT_END(pt);
}
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 36)
Forger
сообщение Sep 25 2018, 12:46
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(pokk @ Sep 25 2018, 12:18) *
Как можно красиво написать похожее чисто на си ?

Взять что-нибудь уже готовое: тыц.
А вопросы красиво/некрасиво - это все индивидуально и крайне субъективно laughing.gif


Цитата
не охото к каждому проекту пихать protothreads
Так поставьте нормальную RTOS


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
pokk
сообщение Sep 26 2018, 01:15
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



Цитата
Взять что-нибудь уже готовое: тыц.

Ну так там везде в функции tickDelay, ставят цикл ожидания, и все остальные процессы останавливаются на это время.
Цитата
Так поставьте нормальную RTOS

Что бы потом пихать в проект ещё и RTOS, когда надо снять данные с датчика температуры и выдать их в usart =)
Прерывания от таймера, это отдельный процесс как в RTOS, только без сохранения контекста =(
+ это очень легко можно запустить на любом процессоре, разобравшись только в таймере и кинув в него 1 функцию.
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 26 2018, 05:22
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Коли вы так боитесь RTOS, то пользуйтесь и дальше неким protothreads. В чем проблема?


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 26 2018, 06:30
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(pokk @ Sep 26 2018, 04:15) *
Ну так там везде в функции tickDelay, ставят цикл ожидания, и все остальные процессы останавливаются на это время.

Учитесь обходиться без задержек. "Везде ставят цикл ожидания" только чайники.
Go to the top of the page
 
+Quote Post
pokk
сообщение Sep 26 2018, 07:33
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



Цитата
Учитесь обходиться без задержек
, это я умею (см первый пост там их нету).
Go to the top of the page
 
+Quote Post
MegaVolt
сообщение Sep 26 2018, 09:49
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 779
Регистрация: 3-01-05
Из: Минск
Пользователь №: 1 783



Цитата(jcxz @ Sep 26 2018, 09:30) *
Учитесь обходиться без задержек. "Везде ставят цикл ожидания" только чайники.
С чего это? Решение задачи определяется задачей. И если хватает времени ждать и нет необходимости делать в это время что-то ещё то задержки могут быть самым надёжным решением.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 26 2018, 09:51
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(MegaVolt @ Sep 26 2018, 12:49) *
С чего это? Решение задачи определяется задачей.

Обратите внимание на слово "везде".
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 26 2018, 09:55
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Имхо, вся эта тема какая-то бессмысленная. Как-будто ТС чем-то хотел похвастать, но не ясно чем именно wacko.gif


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
uriy
сообщение Sep 26 2018, 18:45
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



При отсутствии аппаратного 1wire принято использовать uart https://www.maximintegrated.com/en/app-note...ndex.mvp/id/214
Go to the top of the page
 
+Quote Post
Aner
сообщение Sep 26 2018, 19:08
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 4 869
Регистрация: 28-02-08
Из: СПБ
Пользователь №: 35 463



Да использовал я такое ранее, инвертора от тини-лоджик брал. Особенность в точности UARTа, кварц у проца должен быть точный, с малым разбросом +/-20ppm или лучше и кратный стандарту скорости UARTA. Иначе чудеса.
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 26 2018, 19:13
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Aner @ Sep 26 2018, 22:08) *
Особенность в точности UARTа, кварц у проца должен быть точный, с малым разбросом +/-20ppm или лучше и кратный стандарту скорости UARTA. Иначе чудеса.

Какие 20ppm??? У 1-wire требования к таймингам крайне гуманные
О каком МК идет речь? Какой частоты был этот "волшебный" кварц и какая была тактовая частота МК?


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
k155la3
сообщение Sep 26 2018, 19:35
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(pokk @ Sep 25 2018, 12:18) *
. . . Как можно красиво написать похожее чисто на си ? Думаю в сторону переключения адреса, но как это сделать красиво ? . . .

Красота наводит на мысль использования автомата (FSM) + события от таймера по сработке от CCR. CCR - перезагружается на требуемый интервал.
Но красиво не всегда (разве что самолет) оптимально.
Go to the top of the page
 
+Quote Post
Aner
сообщение Sep 26 2018, 19:36
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 4 869
Регистрация: 28-02-08
Из: СПБ
Пользователь №: 35 463



QUOTE (Forger @ Sep 26 2018, 22:13) *
Какие 20ppm??? У 1-wire требования к таймингам крайне гуманные
О каком МК идет речь? Какой частоты был этот "волшебный" кварц и какая была тактовая частота МК?

Ну ка раскажите мне про этот гуманизм, особенно про джиттер фронтов у 1-wire. Даже если от STM 4-е армы, потребуют хороших инверторов перед UART. И не любой частоты кварц даст, через внутренний PLL, нужной точности частоту. Опять таки если придерживаемся стандарта 1-wire, а не его интепретаций, то есть для того чтобы работать с теми 1-wire датчиками, таблетками и тп.
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 26 2018, 19:48
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Aner @ Sep 26 2018, 22:36) *
Ну ка раскажите мне про этот гуманизм,

Да этому "стандарту" уже почти 30 лет, обсосан до костей.
Тайминги такие, что заведется с полпинка на любом античном МК даже на встроенном RC-генераторе.

Цитата
особенно про джиттер фронтов у 1-wire. Даже если от STM 4-е армы, потребуют хороших инверторов перед UART. И не любой частоты кварц даст, через внутренний PLL, нужной точности частоту.

Нда, случай крайне сложный, похоже на некий "распил".
Вангую, что для поддержки USB пришлось ставить термостабилизированный кварцевый генератор с 5-й приемкой laugh.gif


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Aner
сообщение Sep 26 2018, 19:51
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 4 869
Регистрация: 28-02-08
Из: СПБ
Пользователь №: 35 463



Потому вы и есть любители, не разу не прошедшие сертификацию ваших поделок - недоделок.
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Sep 26 2018, 19:55
Сообщение #17


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Т.е. по делу сказать нечего ? Кто б сомневался...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 26 2018, 22:07
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(uriy @ Sep 26 2018, 21:45) *
При отсутствии аппаратного 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.gif
При скорости 9600 длительность бита == 104мкс. Предположим что частоты генераторов мастера и слэйва идеально совпадают. Тогда, после завершения передачи мастером младших 4-х бит кода 0xF0, на шине наступит фронт сигнала. И в это время UART мастера начнёт приём 4-го бита. Точка сэмплирования этого бита находится на расстоянии 104/2=52мкс от указанного фронта (конца RESET). Но ведь из описания выше следует, что слэйв имеет право начать формировать сигнал присутствия через 60мкс после завершения RESET. Т.е. - уже после того как мастер считает с шины состояние 4-го бита! И мастер получит в 4-м бите лог.1. smile3009.gif
Окей, ладно - может хоть в следующем бите мастер сможет узреть на шине несчастного слэйва?? fman.gif
Но опять же - из описания выше можно узнать, что сигнал присутствия генерируемый слэйвом, может быть длительностью всего 60мкс. Но ведь мы помним, что между точками сэмплирования RX-битов мастером расстояния == 104 мкс (1 бит UART). Получается, что если импульс присутствия начнётся через 60 мкс после конца RESET и продлится всего 60 мкс, то он аккурат проскочит между двумя точками сэмплирования UART.RX мастера. И мастер его просто не заметит!
Хотя мальчик-то есть, но вот колхоз на UART его не видит.... crying.gif
А значит такую реализацию уже нельзя считать 1-wire. Ну никак нельзя.
И это мы ещё даже не учли влияния разности частот генераторов мастера и слэйва, а также влияние ёмкости линии. А также не учли, что делитель UART-а может быть дробным (а длина бита UART - переменной). Там будет ещё веселее.
После этого дальше читать указанную ссылку смысла уже нет.

Цитата(Forger @ Sep 26 2018, 22:48) *
Да этому "стандарту" уже почти 30 лет, обсосан до костей.
Тайминги такие, что заведется с полпинка на любом античном МК даже на встроенном RC-генераторе.

Да ладно?
Не будем углубляться в приём/передачу, но раз "обсосан", то объясните как с помощью UART хотя-бы обнаружить такой слэйв-девайс, который в полном соответствии с мануалом, формирует импульс присутствия с началом через 15...60 мкс после завершения RESET, и длительностью 60...240 мкс?
Это ведь как ловить рыбку сетью, у которой размер ячеи больше размера самой рыбки - конечно есть вероятность что поймаешь, но можно и с голоду опухнуть biggrin.gif
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 27 2018, 05:04
Сообщение #19


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(jcxz @ Sep 27 2018, 01:07) *
то объясните как с помощью UART хотя-бы обнаружить такой слэйв-девайс,
Я не использую для этого UART, для этого есть аппаратные таймеры.


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Smen
сообщение Sep 27 2018, 05:23
Сообщение #20


Местный
***

Группа: Участник
Сообщений: 211
Регистрация: 18-03-13
Из: Питер
Пользователь №: 76 081



Цитата(Forger @ Sep 27 2018, 10:04) *
для этого есть аппаратные таймеры
Т.е. используются и таймеры и УАРТ?
В чём смысл?
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 27 2018, 05:30
Сообщение #21


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Smen @ Sep 27 2018, 08:23) *
Т.е. используются и таймеры и УАРТ?
Цитирую:
Цитата(Smen)
Я не использую для этого UART


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
VAI
сообщение Sep 27 2018, 10:50
Сообщение #22


Профессионал
*****

Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37



Когда-то я выкладывал сюда код, работающий на STM32 и на MSP430.
Вот, смотрите, может подойдёт для Вас. http://electronix.ru/forum/index.php?showt...p;#entry1089884


--------------------
Если зайца бить, его можно и спички научить зажигать
Сколько дурака не бей - умнее не будет. Зато опытнее
Go to the top of the page
 
+Quote Post
toweroff
сообщение Sep 27 2018, 11:03
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



1-Wire вполне себе реализовывался на SPI 32bit. Правда, делал его на древнем уже LPC2103
Главное - пин MOSI правильно настроить, чтобы только вниз тянул, push-pull отключить, если возможно, или сгородить на двух транзисторах

Прикрепленное изображение
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Sep 27 2018, 11:17
Сообщение #24


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(toweroff @ Sep 27 2018, 14:03) *
1-Wire вполне себе реализовывался на SPI 32bit. Правда, делал его на древнем уже LPC2103
Главное - пин MOSI правильно настроить, чтобы только вниз тянул, push-pull отключить, если возможно, или сгородить на двух транзисторах

Прикрепленное изображение

Лучше вот такая схема:

По I2C работает идеально. wink.gif
Go to the top of the page
 
+Quote Post
toweroff
сообщение Sep 27 2018, 11:25
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(AlexandrY @ Sep 27 2018, 14:17) *
Лучше вот такая схема:
По I2C работает идеально. wink.gif

Не, ну кто бы спорил sm.gif
Вопрос в том, что у меня без всяких +200р к стоимости девайса... Хотя, если ценник ему ковырнадцать тысяч, то и DS2484 вполне себе уместна biggrin.gif
Go to the top of the page
 
+Quote Post
Integro
сообщение Sep 27 2018, 12:29
Сообщение #26


Частый гость
**

Группа: Свой
Сообщений: 167
Регистрация: 25-12-09
Из: Минск
Пользователь №: 54 460



Цитата
Красивый выход из прерывания с переключением контекста

Вам нужно посмотреть на примеры реализации механизма callback.
Вкратце, реализовываете функцию для настройки таймера в one shot режиме и в прерывании таймера (через n us) вызываете необходимый вам callback
CODE
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
}

Далее, набрасываем функции которые будут вызываться последовательно:
CODE
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, должны бать быстрой, что бы не поплыли микросекундные тайминги.
Код писал без проверки компиляции, так что извиняйте за описки.
Go to the top of the page
 
+Quote Post
uriy
сообщение Sep 28 2018, 04:54
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



Решение на uart 1wire Отлично работает даже с usb-uart преобразователем CP2102. CP2102 работает без кварца и скорее всего подстраивает частоту по SOF кадрам, думаю там разброс больше чем 20 ppm.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 28 2018, 05:24
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(uriy @ Sep 28 2018, 07:54) *
Решение на uart 1wire Отлично работает даже с usb-uart преобразователем CP2102.
Кроме пустословия, по делу, есть что сказать?
Ещё раз читаем: Почему UART - не 1-wire

Цитата(uriy @ Sep 28 2018, 07:54) *
CP2102 скорее всего подстраивает частоту по SOF кадрам.
Бред.
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Sep 28 2018, 11:15
Сообщение #29


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Не знаю, зачем выделять на это целый UART... Я сделал на таймере в режиме сравнения. Благодаря этому можно использовать любую ножку свободную на МК. Обработчик таймера:
CODE
#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.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 28 2018, 11:21
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Arlleex @ Sep 28 2018, 14:15) *
Не знаю, зачем выделять на это целый UART... Я сделал на таймере в режиме сравнения.

Вы наверное перепутали: наверное всё-таки в режиме захвата (capture), а не сравнения (compare). rolleyes.gif
Да, это стандартное решение. Вообще не понимаю здешних товарищей, которые пытаются колхозить на чём угодно, только не делать как надо. cranky.gif
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Sep 28 2018, 11:54
Сообщение #31


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(jcxz @ Sep 28 2018, 14:21) *
Вы наверное перепутали: наверное всё-таки в режиме захвата (capture), а не сравнения (compare). rolleyes.gif

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

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

Сообщение отредактировал Arlleex - Sep 28 2018, 11:58
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 28 2018, 12:02
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



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

Код
int i, i1;
i1 = i - 5 >> 31;
i = i - i1 & i1;

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

Цитата(Arlleex @ Sep 28 2018, 14:54) *
Почему? Именно по сравнению: как только заданный период прошёл (счётчик таймера сравнялся с указанным значением сравнения), формируется прерывание, в котором регистр сравнения перенастраивается на следующий интервал, а лапка дергается в соответствующую сторону laughing.gif

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

Цитата(Arlleex @ Sep 28 2018, 14:54) *
А захват - это защёлкивание текущего значения таймера по какому-либо событи'юю, как я понимаю эту всю кухню.

Вот именно. А потом анализируем защёлкнутое значение и решаем что это было - 0 или 1.
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Sep 28 2018, 12:07
Сообщение #33


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(jcxz @ Sep 28 2018, 15:02) *
Код
int i, i1;
i1 = i - 5 >> 31;
i = i - i1 & i1;

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

Благодарю! Потестирую sm.gif
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 28 2018, 13:08
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Arlleex @ Sep 28 2018, 15:07) *
Благодарю! Потестирую sm.gif

Можно ещё проще, но значения чисел будут не через 1, а через большие промежутки. Типа так:
Код
#define LIMIT 5
#define STEP ((u32)(((1u << 31) + LIMIT - 1) / LIMIT))  //значение шага округлённое до ближайшего бОльшего целого
u32 i;
i = __USAT(i + STEP, 31);
Всего две операции. wink.gif Значения шагов будут: STEP*0, STEP*1, STEP*2, STEP*3, STEP*4, а на следующем шаге получим опять STEP*0.
Для switch-а такие значения конечно неудобны. sad.gif

Ещё вариант - использовать отрицательный диапазон чисел:
Код
enum {LIMIT = 5};
int i = -LIMIT;
i -= i >> 31 | LIMIT; //-5,-4,-3,-2,-1,0
Всего 3 операции cool.gif
Go to the top of the page
 
+Quote Post
toweroff
сообщение Sep 28 2018, 20:35
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(jcxz @ Sep 28 2018, 14:21) *
Вообще не понимаю здешних товарищей, которые пытаются колхозить на чём угодно, только не делать как надо. cranky.gif

RTOS
предлагаете всё в SysTick вешать, у которого наивысший приоритет?
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 28 2018, 20:55
Сообщение #36


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(toweroff @ Sep 28 2018, 23:35) *
предлагаете всё в SysTick вешать, у которого наивысший приоритет?

Вы наверно удивитесь, но в RTOS системному таймеру SysTick назначают как раз самый низкий приоритет (наравне с PendSV - переключатель контекста)
И вообще, если не используется RTOS, то ничего не мешает настроить Systick так, чтобы использовать его как самый простой аппаратный таймер, только назначив уже нужный приоритет.
Именно так я сделал в примитивных проектах, где RTOS ни к чему, но нужны простые временные выдержки, в частности с кратностью 1us и 1ms. Systick отлично для этого подходит.


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 28 2018, 21:54
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(toweroff @ Sep 28 2018, 23:35) *
предлагаете всё в SysTick вешать, у которого наивысший приоритет?

SysTick то тут при чём???? wacko.gif Само собой оптимально делается - на режиме захвата таймера.
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th July 2025 - 07:59
Рейтинг@Mail.ru


Страница сгенерированна за 0.02647 секунд с 7
ELECTRONIX ©2004-2016