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

 
 
> Програмный 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
 
Start new topic
Ответов
Arlleex
сообщение Sep 28 2018, 11:15
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 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, 12:02
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 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
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 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
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 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

Сообщений в этой теме
- pokk   Програмный 1-wire на прерываниях таймера   Sep 25 2018, 09:18
- - Forger   Цитата(pokk @ Sep 25 2018, 12:18) Как мож...   Sep 25 2018, 12:46
- - pokk   ЦитатаВзять что-нибудь уже готовое: тыц. Ну так та...   Sep 26 2018, 01:15
|- - Forger   Коли вы так боитесь RTOS, то пользуйтесь и дальше ...   Sep 26 2018, 05:22
|- - jcxz   Цитата(pokk @ Sep 26 2018, 04:15) Ну так ...   Sep 26 2018, 06:30
|- - MegaVolt   Цитата(jcxz @ Sep 26 2018, 09:30) Учитесь...   Sep 26 2018, 09:49
|- - jcxz   Цитата(MegaVolt @ Sep 26 2018, 12:49) С ч...   Sep 26 2018, 09:51
|- - Forger   Имхо, вся эта тема какая-то бессмысленная. Как-буд...   Sep 26 2018, 09:55
- - pokk   ЦитатаУчитесь обходиться без задержек, это я умею ...   Sep 26 2018, 07:33
- - uriy   При отсутствии аппаратного 1wire принято использов...   Sep 26 2018, 18:45
|- - jcxz   Цитата(uriy @ Sep 26 2018, 21:45) При отс...   Sep 26 2018, 22:07
|- - Forger   Цитата(jcxz @ Sep 27 2018, 01:07) то объя...   Sep 27 2018, 05:04
|- - Smen   Цитата(Forger @ Sep 27 2018, 10:04) для э...   Sep 27 2018, 05:23
|- - Forger   Цитата(Smen @ Sep 27 2018, 08:23) Т.е. ис...   Sep 27 2018, 05:30
- - Aner   Да использовал я такое ранее, инвертора от тини-ло...   Sep 26 2018, 19:08
|- - Forger   Цитата(Aner @ Sep 26 2018, 22:08) Особенн...   Sep 26 2018, 19:13
|- - Aner   QUOTE (Forger @ Sep 26 2018, 22:13) Какие...   Sep 26 2018, 19:36
|- - Forger   Цитата(Aner @ Sep 26 2018, 22:36) Ну ка р...   Sep 26 2018, 19:48
- - k155la3   Цитата(pokk @ Sep 25 2018, 12:18) . . . К...   Sep 26 2018, 19:35
- - Aner   Потому вы и есть любители, не разу не прошедшие се...   Sep 26 2018, 19:51
- - rx3apf   Т.е. по делу сказать нечего ? Кто б сомневался...   Sep 26 2018, 19:55
- - VAI   Когда-то я выкладывал сюда код, работающий на STM3...   Sep 27 2018, 10:50
- - toweroff   1-Wire вполне себе реализовывался на SPI 32bit. Пр...   Sep 27 2018, 11:03
|- - AlexandrY   Цитата(toweroff @ Sep 27 2018, 14:03) 1-W...   Sep 27 2018, 11:17
|- - toweroff   Цитата(AlexandrY @ Sep 27 2018, 14:17) Лу...   Sep 27 2018, 11:25
|- - Integro   ЦитатаКрасивый выход из прерывания с переключением...   Sep 27 2018, 12:29
- - uriy   Решение на uart 1wire Отлично работает даже с usb-...   Sep 28 2018, 04:54
|- - jcxz   Цитата(uriy @ Sep 28 2018, 07:54) Решение...   Sep 28 2018, 05:24
- - jcxz   Цитата(Arlleex @ Sep 28 2018, 14:15) Не з...   Sep 28 2018, 11:21
|- - Arlleex   Цитата(jcxz @ Sep 28 2018, 14:21) Вы наве...   Sep 28 2018, 11:54
|- - toweroff   Цитата(jcxz @ Sep 28 2018, 14:21) Вообще ...   Sep 28 2018, 20:35
|- - Forger   Цитата(toweroff @ Sep 28 2018, 23:35) пре...   Sep 28 2018, 20:55
|- - jcxz   Цитата(toweroff @ Sep 28 2018, 23:35) пре...   Sep 28 2018, 21:54


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

 


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


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