Цитата(yliya @ Nov 29 2012, 22:05)

Написала для себя алгоритмик, а как реализовать не знаю...Хоть в правильном направлении иду?
Юля! Прочтите внимательно! На этом форуме считается "моветон" просить что бы кто-то за вас написал программу. Это не в обиду, просто имейте
ввиду!
Проехали.
Попытаюсь объяснить "на пальцах" что вам нужно. Для примера возьму ситуацию, когда вы отправляете своего молодого человека(мужа) в
магазин, и вам нужно засечь сколько это ему займет времени, дабы установить, не отклонялся ли он от маршрута (не баловался ли пивком
в попутной прилавке, хотя это можно по запаху установить, но допустим у вас нос заложен).
Сначала вам нужно определится с задачей. Если вы хотите засечь время - это и есть ваша главная задача. Придумать список покупок и
подсчитать необходимую сумму(опрашивать кнопки и передавать результат по SPI), это второстепенные задачи. И так, начнем:
Вам нужно засечь время между выходом молодого человека из дома (сигнал на входе INT0) и возвращением его домой (сигнал на входе INT1).
Что бы не пропустить эти две события, находясь в одноклассниках (когда процессор выполняет основную программу), нужно сделать так,
что бы эти события прервали вашу переписку в социальной сети, поставив (например) на дверь маленький колокольчик(нужно разрешить
в регистре IEC0 прерывание INT0 - выставить бит 0, а также в регистре IEC1 прерывание INT1 - выставить бит 4. Естественно, не надо забывать
настроить соответствующие выводы процессора на "вход" - в соответствующих регистрах TRIS).
По рассказам продвинутых девушек, лучше время засекать часами, но допустим, что вам лень доставать часы (у вашего процессора нет часов
реального времени), тогда можно использовать обычный кухонный таймер на 30 минут (лучше использовать Таймер1 процессора, так как он
заточен под измерение временных интервалов, а также пользуется для часов реального времени). Значит, достаем кухонный таймер,
(настраиваем требуемые функции Таймера1, в регистре T1CON, оставив пока бит 15 - 0, так как запустим таймер по первому событию - INT0).
Молодому человеку объясняем, что собираемся варить яйцо, поэтому достали таймер. Поскольку ожидаемое время прибытия подопытного
может оказаться за пределами этого полчаса (измеряемый интервал времени может оказаться больше времени переполнения Таймера1)
ставим кухонный таймер на стол, рядом с компьютером, на котором лазим в одноклассниках, что бы услышать звонок по окончании 30 минут
(в регистре IEC0 выставляем бит 3, что бы разрешить прерывание от Таймера1).
Все это была подготовка. (Всю эту подготовку, нужно сделать в основной программе. Можно, для наглядности ее вынести в отдельную процедуру,
назвав ее InitTimerAndInterrupts и вызвать ее в начале основной программы)
Теперь ждем первого звонка дверного колокольчика(передаем управление основной программе, в которой опрашиваем кнопки и т.д.).
Как только раздается звонок, запускаем кухонный таймер (при возникновении события на входе INT0 исполнение основной программы прерывается
и контроллер прерываний отправляет процессор на вектор соответствующего прерывания. Не надо опрашивать флаги прерываний, в 24-ой серии
об этом заботится контроллер прерываний, ровно как не надо заботится о сохранении статусного регистра и программного счетчика, об этом
заботится компилятор. И так первое что нужно сделать в обработчике прерываний по-вектору INT0 - это запустить Таймер1, выставив
бит 15 в регистре T1CON. После этого, что бы не терять время, нужно обнулить флаг INT0IF в регистре IFS0. Если предполагается что измерение
интервалов времени будет делаться многократно, сначала при входе в прерывание нужно обнулить Таймер1 а также и переменную vremya, в
которую накапливается общее количество времени, а только потом его запускать, так сказать, для чистоты эксперимента. И это все что нужно
сделать в обработчике прерывании INT0. Можно на всякий пожарный запретить прерывания INT0, что бы если произойдет второе событие
на входе INT0, до завершении цикла INT1, оно не сбило счет времени).
Дальше возвращаемся в одноклассники (управление автоматически передается основной программе. Продолжаем опрашивать кнопки и т.д.).
Как только раздается звонок кухонного таймера (если Таймер1 один переполнится - возникает прерывание), заряжаем его на 30 минут опять,
достаем ручку и ставим одну отметку на лист бумаги(в обработчике прерывании по вектору Т1 добавляем к переменной vremya 65536,
сбрасываем флаг T1IF в регистре IFS0 и выходим).
Дальше эта нехитрая процедура повторяется до возвращения любимого.
Как только услышим второй звонок дверного колокольчика, останавливаем кухонный таймер и записываем его показание(в обработчике
прерывании по вектору INT1 добавляем содержимое Таймера1 во vremya и останавливаем Таймер1 сбросив бит 15 в регистре T1CON. Если
запретили прерывание от INT0, здесь его нужно разрешить снова, что бы подготовить систему для следующего измерения).
Дальше делим количество отметок на листе на 2, что бы получить время в часах, добавляем туда последнее значение кухонного таймера,
для точности и звоним маме/продвинутой подруге (делим значение переменной vremya на количество тактов Таймера1 в секунду, что бы
получить время в секундах, а если хотим получить время в десятых секунды, делим на количество тактов Таймера1 в десятую секунды.
Дальше если надо, преобразуем значение времени в десятичное и выставляем флаг, что бы дать основной программе знать, что процедура
измерения закончена, у нас есть готовый результат и можно его передавать по SPI), что бы узнать нормально или нет опоздал наш молодой
человек. В обоих случаях целуем молодого человека и говорим ему, как его ждали с нетерпением, что бы в следующий раз ему тоже было
в нетерпение вернутся домой.
И все. Тут и сказочке конец. Увидели как просто!