|
|
|
|
Zandy: К сожалению в си пока не секу. Циклический буфер, это и есть 8 регистров с организацией циклической записи в них? А чего тут сечь-то? Ты читай это просто как описание алгоритма. byte measures[8]; резервируем 8 байтов (регистров), под собственно буфер. byte pos=255; - ещё один регистр, в нём хранится позиция в буфере. Сразу присваиваем начальное значение. if (pos == 255) { : сравнение значения pos с числом 255. Если равно, то выполняем всё что между "{" и "}" measures[0] = длина_интервала; - запись в 1й байт буфера значения из переменной "длина_интервала" (считаем от 0) ... pos = 0; - запись в регистр "pos" значения 0 } конец блока "если" measures[pos] = длина_интервала; запись в байт c номером pos+1 буфера значения из переменной "длина_интервала" pos = pos + 1; увеличение значения регистра pos на 1 if (pos == 8) pos = 0; сравнение значения регистра pos с 8, если равен, то запись в pos 0. ЗЫ. Я не навязываю Си, я алгоритм описываю!  |
|
|
Похоже, я всех распугал?!  |
|
|
Программу писать не дают. Заставляют графы изучать. А теперь еще и си.  picmaniac: Так что я, похоже, поспешил с расстановкой приоритетов тогда. Подумаю ещё... Ждем-с.  |
|
|
Не, мы не из пугливых!  Zandy: Заставляют Ничуть. Лишь советую, рекомендую. Я и сам в графах не силён пока, тоже изучаю. Вот возможный вариант алгоритма для обработчика прерываний. Рисунок большой, поэтому даю ссылку: http://www.pic16.nm.ru/likbez1/algo4_01.gif |
|
|
Я вот тут глянул. Предлагаю упростить алгоритм, чтобы сразу, одним махом отсекать лишние прерывания. OLDPORTB - регистр, где хранится состояние порта в предыдущем прерывании. TEMP и TEMP1 - служебные регистры. итак: movf PORTB,W andlw B'11110000' movwf TEMP xorwf OLDPORTB,W andwf TEMP,W movwf TEMP1 movf TEMP W movwf OLDPORTB ; запись текущего состояния после этого побитно будем проверять четыре старших разряда TEMP1, либо сделаем swapf и организуем вычисляемый переход. Если в каком-то разряде 1, значит был положительный фронт по этому каналу. Выполняем соответствующие действия. Если 0, ничего не делаем и проверяем дальше. Если 0000 спокойненько покидаем прерывание, ну в смысле делаем все остальное. TEMP1 можно использовать как FLAGS на вашем рисунке, только биты будут инверсные. |
|
|
А как в этом случае быть с обнулением таймера тайм-аута? Учитывать только фронты?
|
|
|
Да, вроде нужен специальный регистр. Просто с таймаутом как-то все уж очень замороченно. Не сразу врубился. А нельзя ли как-то попроще? |
|
|
А попробуйте, может как-то и придумаете. |
|
|
А почему все-таки нельзя фронты учитывть? picmaniac: А как в этом случае быть с обнулением таймера тайм-аута? Я все-таки не совсем понимаю терминологии что-ли. Что значит обнуление? Установка числа счета? Разве мы не в каждом прерывании по таймеру это делаем? Нам же всего - навсего надо определять аварийный случай отсутствия сигнала или его очень большой длительности. Ну будем в каждом прерывании смотреть, был ли фронт, т. е. сравнивать TEMP1 с его записанным значением в предыдущем прерывании по таймеру. А если не использовать дополнительный таймер - таймер тайм аута, а делать прерывания по переполнению нашего рабочего таймера заполнения. Ну и типа, если в течении, например одного - двух прерываний, либо изменения, либо передних фронтов не проходило, считать это аварийным случаем? |
|
|
Zandy: Что значит обнуление? Записать число 0 в регистр таймера тайм-аута. Разве мы не в каждом прерывании по таймеру это делаем? У нас два таймера. Физически - два разных регистра. Один - тот, который инкрементируется импульсами заполнения от тактового генератора и применяется для определения периода. Его мы не обнуляем, и прерываний от него не бывает. Он считает себе и считает по кругу, а мы только считываем данные из него в обработчике прерываний. Трогать его (изменять значение принудительно) нельзя, т.к. по его значениям определяются расчётами периоды для всех входов. Второй - таймер тайм-аута, инкрементируется также от тактового генератора с таким расчётом, чтоб его переполнение наступало при отсутствии изменения уровня хотя бы на одном из входов в течение достаточно длительного времени (более длительности самого долгого периода в допустимом диапазоне нормальной работы). При его переполнении и происходит прерывание по тайм-ауту. Так вот, таймер тайм-аута должен быть обнулён, если импульсы на всех входах присутствуют и следуют с достаточно высокой частотой (не менее минимально допустимой по диапазону нормальной работы). Если его не обнулять - получим постоянные ложные прерывания по тайм-ауту. Zandy, не зря ведь я старался - рисовал диаграммы на стр.56. Прикиньте по ним общую картину и то, как должен действовать контроллер. Мысленно (или в paint ) уберите импульсы (начиная со второго слева) на одном входе... на двух входах... и т.д. |
|
|
|
|