|
вопрос по Си небольшой. |
|
|
|
Sep 6 2006, 06:24
|

Профессионал
    
Группа: Модераторы
Сообщений: 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
|
|
|
|
|
Sep 6 2006, 06:55
|
Местный
  
Группа: Участник
Сообщений: 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; } Ну и все это, разумеется, крутится в бесконечном цикле.
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Sep 6 2006, 08:29
|
Профессионал
    
Группа: Свой
Сообщений: 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
|
|
|
|
|
Sep 6 2006, 11:41
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(Метценгерштейн @ Sep 6 2006, 12:29)  ясно, с этим вроде разобрался, вот ещё не ясно как лучше сделать. Уже, наверное, понятно, что я пишу под ключ- таблетку. У меня есть мастер ключ, и есть юзер ключи. Теперь я хочу, чтобы если приложил кратковременно мастер, просто поменяло состояние на другое, а если его удерживаю хотя бы 5 сек, сразу попадаю в др. подпрограмму записи USER ключа. Как это лучше реализовать? ... Кстати, а как Вы собираетесь определять, что в течение всех этих 5 секунд был приложен мастер ключ? Постоянно считывать и проверять его код? - неудобно. В многих подобных системах используется след. алгоритм: 1. При кратковременном замыкании контактов считывателя переходим в режим ожидания мастер-ключа. 2. Если в течение заданного интервала обнаружили мастер - переходим в режим записи USER-ключа, иначе - возвращаемся в режим ожидания. 3. Ну, и если в режиме программирования в течение разумного промежутка не был обнаружен новый ключ или же при повтороном замыкании контактов считывателя - также возвращаемся в дежурный режим.
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Sep 8 2006, 07:35
|
Профессионал
    
Группа: Свой
Сообщений: 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 сек, оно прыгал в ту ф-ю, а не ждало пока я ключ отпущу, и потом только прыгало?
|
|
|
|
|
Sep 8 2006, 12:41
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(Метценгерштейн @ Sep 8 2006, 11:35)  ... Как лучше тут описать? Чтобы я держал ключ, как только время достигло 4 сек, оно прыгал в ту ф-ю, а не ждало пока я ключ отпущу, и потом только прыгало? По логике нужно использовать 1-й вариант - а то как пользователь узнает, что мастер-ключ уже можно отпускать.
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Sep 11 2006, 10:23
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
while ( MasterKey () ) { //пока ещё приложен ключ CntT0= 0; if (CntT0 == 95) { //если не досчитал до 5 сек., то меняю сост. на IDLE_HAS_KEY WRITE_KEY (); } } такая конструкция была бы правильной? В ф-ии WRITE_KEY (); я просто мигаю лампочкой. Но вот что- то оно не мигает....
|
|
|
|
|
Sep 11 2006, 10:54
|
Группа: Новичок
Сообщений: 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 (); я просто мигаю лампочкой. Но вот что- то оно не мигает....  Не так это делается После проверки ключа на валидность надо секунды на три блокировать ввод. Иначе можно нарваться на двойное переключение состояния, люди по разному ключ прикладывают. После ввода ключа, блокируешь ввод, очищаешь счетчик в таймерном прерывании, отсчитываешь 3 - 4 секунды и разрешаешь ввод ключа. Если ключ все еще приложен, он тут же считается и вот тут то и надо принимать решение о переходе в режим ввода новых ключей. Успехов
|
|
|
|
|
Sep 14 2006, 11:17
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
ещё вопрос по Си (простой) в таком виде
case ARMED: // этот код выполняется под охраной
if(signal(SENS)) { on(SIRENA); CntT0= 0; if (CntT0 == 700) { // продолжительность воя сирены - подобрать off(SIRENA); } }
это фрагмент, попал я в режим под охраной, как только поступил сигнал с датчика, включаю сирену, теперь надо, чтобы она либо сама отключилась через время, либо я ключом её выключил. Считает счетчик, если равно количесву прерываний счетчика 700, сирена выключается. Не понятно по скобкам, этот таймер у меня внутри ф-ии, я туда всегда буду попадать по прерыванию счетчика? или я там буду, пока SENS (датчик) сработал? Вот здесь непонятность небольшая
|
|
|
|
|
Sep 14 2006, 11:44
|
Участник

Группа: Свой
Сообщений: 66
Регистрация: 27-09-05
Пользователь №: 9 012

|
Цитата Не понятно по скобкам, этот таймер у меня внутри ф-ии, я туда всегда буду попадать по прерыванию счетчика? Таймера внутри функции лично я не вижу. По прерыванию от него вы будете попадать в соответствующую ISR (программу обслуживания прерываний). А вот, что вы будуте в этой ISR делать (просто отключать сирену, флаг какой-то устанавливать, что пора бы её выключить) - это уже ваше дело.
|
|
|
|
|
Sep 14 2006, 12:02
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
всё правильно, я немного не так выразился, по прерыванию от таймера я попадаю сюда
#pragma vector = TIMER0_OVF0_vect __interrupt void overflow_timer1(void) { CntT0++; }
Здесь увеличиваю переменную А что у меня получилось? Сначала сработал датчик, я попал в эту ф-ю, включил сирену, обнулил CntT0=0; теперь надо, чтобы при проверке при количеству подсчетов =700, выполнялось отключить сирену. Уже вижу, что запутался. Я хотел вот что спросить, здесь if(signal(SENS)) { я буду считать до 700 если это условие постоянно истина? Т.е. все время идет сигнал от датчика? как только нет, я вываливаюсь из цикла и уже не проверяю на 700?
|
|
|
|
|
Sep 14 2006, 12:21
|
Местный
  
Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219

|
Цитата(Метценгерштейн @ Sep 14 2006, 15:02)  всё правильно, я немного не так выразился, по прерыванию от таймера я попадаю сюда
#pragma vector = TIMER0_OVF0_vect __interrupt void overflow_timer1(void) { CntT0++; }
Здесь увеличиваю переменную А что у меня получилось? Сначала сработал датчик, я попал в эту ф-ю, включил сирену, обнулил CntT0=0; теперь надо, чтобы при проверке при количеству подсчетов =700, выполнялось отключить сирену. Уже вижу, что запутался. Я хотел вот что спросить, здесь if(signal(SENS)) { я буду считать до 700 если это условие постоянно истина? Т.е. все время идет сигнал от датчика? как только нет, я вываливаюсь из цикла и уже не проверяю на 700? Может невпопад, за веткой не слежу. Я бы сделал так: Код #pragma vector = TIMER0_OVF0_vect __interrupt void overflow_timer1(void) { static CntT0 = 0;
if (State == ST_DELAY) { if (++CntT0 >= DELAY_5S) { CntT0 = 0; State = ST_WRITE; } } }
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|