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

 
 
> вопрос по Си небольшой.
Метценгерштейн
сообщение Sep 6 2006, 06:13
Сообщение #1


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

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



У меня организован такой цикл case:

switch(State) {
...
case IDLE: // этот код выполняется если снято с охраны
off(LED);

if( one_wire_main () ) { //если что-то приложили (ключ)

if(USER_KEYS()) {
State = IDLE_HAS_KEY;
}
}

break;

case IDLE_HAS_KEY:
...

Вопрос- вот иду я по проге, приложили USER_KEYS, я сразу прыгаю на метку IDLE_HAS_KEY? Или дохожу до оператора break, потом компилятор анализирует что там было раньше и после break прыгает уже на метку?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
KRS
сообщение Sep 6 2006, 06:24
Сообщение #2


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Что значит цикл case???

на case IDLE_HAS_KEY: вы попадете только когда оператор switch(State) выполнится заново и при этом State будет = IDLE_HAS_KEY

switch - это всего лишь переключатель в зависимости от State делается JUMP в нужную точку

если хотите в этой же итерации попасть туда используйте goto

например так:
Код
switch(State) {
...
case IDLE: // этот код выполняется если снято с охраны
  off(LED);

  if( one_wire_main () ) { //если что-то приложили (ключ)

    if(USER_KEYS()) {
      State = IDLE_HAS_KEY;
      goto _IDLE_HAS_KEY:
    }
  }

break;


case IDLE_HAS_KEY:
_IDLE_HAS_KEY:
...


Сообщение отредактировал KRS - Sep 6 2006, 06:28
Go to the top of the page
 
+Quote Post
Harvester
сообщение Sep 6 2006, 06:55
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



Цитата(KRS @ Sep 6 2006, 10:24) *
Что значит цикл case???

на case IDLE_HAS_KEY: вы попадете только когда оператор switch(State) выполнится заново и при этом State будет = IDLE_HAS_KEY

switch - это всего лишь переключатель в зависимости от State делается JUMP в нужную точку

если хотите в этой же итерации попасть туда используйте goto

например так:
Код
switch(State) {
...
case IDLE: // этот код выполняется если снято с охраны
  off(LED);

  if( one_wire_main () ) { //если что-то приложили (ключ)

    if(USER_KEYS()) {
      State = IDLE_HAS_KEY;
      goto _IDLE_HAS_KEY:
    }
  }

break;


case IDLE_HAS_KEY:
_IDLE_HAS_KEY:
...


Совет правильный, но вообще-то использование команды goto является плохим стилем программирования и очень затрудняет отладку. Лично я построил бы диспетчер следующим образом:
Код
do{

  State = IDLE;
  off(LED); // этот код выполняется если снято с охраны
  ...

  if( one_wire_main ()  && USER_KEYS())  //если приложили правильный ключ
    State = IDLE_HAS_KEY;

  if( ... ) //другое событие
    State = ...;

  if( ... ) //n-е событие
    State = ...;

}while(State == IDLE);

switch(state)
{
  case IDLE_HAS_KEY:
    ...
    break;

  case ...:
    ...
    break;
  
  default:
    ...
    break;
}

Ну и все это, разумеется, крутится в бесконечном цикле.


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Sep 6 2006, 08:29
Сообщение #4


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

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



ясно, с этим вроде разобрался, вот ещё не ясно как лучше сделать.
Уже, наверное, понятно, что я пишу под ключ- таблетку. У меня есть мастер ключ, и есть юзер ключи. Теперь я хочу, чтобы если приложил кратковременно мастер, просто поменяло состояние на другое, а если его удерживаю хотя бы 5 сек, сразу попадаю в др. подпрограмму записи USER ключа. Как это лучше реализовать?

if( MasterKey () ) { //здесь- что, если приложен мастер
//здесь опишем процесс, записи новых ключей, только из IDLE
//если прижали мастер на 5 сек

CntT0= 0;
while (CntT0 !=95) //если в теч. 5 сек. приложили мастер, вызываю запись USERa
...
WRITE_KEY();
...
State = IDLE_HAS_KEY;
...

State = IDLE_HAS_KEY; это состояние, куда я должен попать если кратковременно приложил- отпучтил ключ, а если 5 сек. удерживаю, то в ф-ю WRITE_KEY();

как бы это завернуть покрасивше?

Сообщение отредактировал Метценгерштейн - Sep 6 2006, 08:32
Go to the top of the page
 
+Quote Post
Harvester
сообщение Sep 6 2006, 11:41
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



Цитата(Метценгерштейн @ Sep 6 2006, 12:29) *
ясно, с этим вроде разобрался, вот ещё не ясно как лучше сделать.
Уже, наверное, понятно, что я пишу под ключ- таблетку. У меня есть мастер ключ, и есть юзер ключи. Теперь я хочу, чтобы если приложил кратковременно мастер, просто поменяло состояние на другое, а если его удерживаю хотя бы 5 сек, сразу попадаю в др. подпрограмму записи USER ключа. Как это лучше реализовать?
...


Кстати, а как Вы собираетесь определять, что в течение всех этих 5 секунд был приложен мастер ключ? Постоянно считывать и проверять его код? - неудобно.

В многих подобных системах используется след. алгоритм:
1. При кратковременном замыкании контактов считывателя переходим в режим ожидания мастер-ключа.
2. Если в течение заданного интервала обнаружили мастер - переходим в режим записи USER-ключа, иначе - возвращаемся в режим ожидания.
3. Ну, и если в режиме программирования в течение разумного промежутка не был обнаружен новый ключ или же при повтороном замыкании контактов считывателя - также возвращаемся в дежурный режим.


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Sep 8 2006, 07:35
Сообщение #6


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

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



немного конкретизирую задачу- при приложении мастер- ключа, устойчиво переходит из состояний охрана- снято. Но, я хочу, чтобы если подержал подольше мастер- ключ- секунды 4, то попадаю в ф-ю записи юзер- ключа. Для начала, надо, чтобы я устойчиво попадал в эту прогу, а там мигал хитро светодиодом. Подскажите, плз. Вот образец куска проги общей.

if( MasterKey () ) { //здесь- что, если приложен мастер
//здесь опишем процесс, записи новых ключей, только из IDLE
//если прижали мастер на 5 сек
//**************************** ***************** *******************************
/* CntT0= 0;
if( !one_wire_main () ) { //если отпустили ключ
if (CntT0 < 95) //если не досчитал до 5 сек., то меняю сост. на IDLE_HAS_KEY
State = IDLE_HAS_KEY;
else
WRITE_KEY();
} */
//************************************* **************** ************************
State = IDLE_HAS_KEY;
}
}

здесь закомментировано, так оно просто переключается между состояниями, ф-я записи ключей WRITE_KEY();
попав в неё, я хочу помигать лампочкой.
Как лучше тут описать? Чтобы я держал ключ, как только время достигло 4 сек, оно прыгал в ту ф-ю, а не ждало пока я ключ отпущу, и потом только прыгало?
Go to the top of the page
 
+Quote Post
Harvester
сообщение Sep 8 2006, 12:41
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



Цитата(Метценгерштейн @ Sep 8 2006, 11:35) *
...
Как лучше тут описать? Чтобы я держал ключ, как только время достигло 4 сек, оно прыгал в ту ф-ю, а не ждало пока я ключ отпущу, и потом только прыгало?

По логике нужно использовать 1-й вариант - а то как пользователь узнает, что мастер-ключ уже можно отпускать.


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Sep 11 2006, 10:23
Сообщение #8


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

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



while ( MasterKey () ) { //пока ещё приложен ключ
CntT0= 0;
if (CntT0 == 95) { //если не досчитал до 5 сек., то меняю сост. на IDLE_HAS_KEY
WRITE_KEY ();
}
}

такая конструкция была бы правильной? В ф-ии WRITE_KEY (); я просто мигаю лампочкой.
Но вот что- то оно не мигает.... sad.gif
Go to the top of the page
 
+Quote Post
PaulS
сообщение Sep 11 2006, 10:54
Сообщение #9





Группа: Новичок
Сообщений: 9
Регистрация: 28-01-05
Пользователь №: 2 265



Цитата(Метценгерштейн @ Sep 11 2006, 14:23) *
while ( MasterKey () ) { //пока ещё приложен ключ
CntT0= 0;
if (CntT0 == 95) { //если не досчитал до 5 сек., то меняю сост. на IDLE_HAS_KEY
WRITE_KEY ();
}
}

такая конструкция была бы правильной? В ф-ии WRITE_KEY (); я просто мигаю лампочкой.
Но вот что- то оно не мигает.... sad.gif


Не так это делается
После проверки ключа на валидность надо секунды на три блокировать ввод.
Иначе можно нарваться на двойное переключение состояния, люди по разному
ключ прикладывают. smile.gif
После ввода ключа, блокируешь ввод,
очищаешь счетчик в таймерном прерывании,
отсчитываешь 3 - 4 секунды
и разрешаешь ввод ключа.
Если ключ все еще приложен, он тут же считается и вот тут то и надо принимать решение
о переходе в режим ввода новых ключей.
Успехов
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Метценгерштейн   вопрос по Си небольшой.   Sep 6 2006, 06:13
|- - Метценгерштейн   так корректно будет? CntT0= 0; if( !o...   Sep 6 2006, 09:22
- - Shurmas   Пример с сетью 1-wire с "таблеткой" и др...   Sep 11 2006, 13:41
|- - Метценгерштейн   ещё вопрос по Си (простой) в таком виде case ARME...   Sep 14 2006, 11:17
- - dezzer   ЦитатаНе понятно по скобкам, этот таймер у меня вн...   Sep 14 2006, 11:44
|- - Метценгерштейн   всё правильно, я немного не так выразился, по прер...   Sep 14 2006, 12:02
|- - _Bill   Цитата(Метценгерштейн @ Sep 14 2006, 15:0...   Sep 14 2006, 12:21
- - xemul   2 Метценгерштейн имхо, было бы неплохо нарисовать ...   Sep 14 2006, 15:39


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

 


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


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