Свежие обсуждения
Микроконтроллеры

Разработка таймера на основе PIC16F628(A) с программой на языке С

1 8 21

Сергей К: Хочу предложить свой вариант обработки прерывания
Всё-таки я сначала граф нарисую. Так оно ИМХО нагляднее. Код потом.

Чё-то АВРщики в своих ветках притииихли...

 

Не притихли, а затаились

 

А вобще, потом, я бы не отказался от функции цифрового термометра Выход есть, еще одну кнопку приспособить - не проблема;)

 

picmaniac: А если подумать? Прерывание по таймеру происходит строго через каждые 4 мс, и этот интервал не зависит от времени входа в прерывание, определения источника и т.п. Промежуток времени между моментами инкремента переменной всё равно останется 4 мс. На то он и таймер.
Так, ежели источник прерываний - TMR0, его ж еще предустанавливать надо после входа в прерывание. И если между моментом входа в прерывание и предустановкой проделывается некое количество команд, то период прерывания (по сравнению с расчетным) увеличится ровно на время выполнения этих команд. Разве не так?

 

Именно. Вектор прерываний у нас только 1. Во-первых уйдет время на распознание прерывания от таймера if (T0IF==1). Затем мы икрементируем нашу переменную(например A), каждые 4мс. Если мы хотим инкрементировать переменную каждую секунду, то нам это значение A нужно сравнить с цифрой 250, на это тоже уходит время. Вот пример обработчика прерываний
#int_rtcc
void clock_isr()
{
RTC++;
if ((RTC^14649)==0)
LMin++;
RTC=0;

}
Тут LMin инкрементируется каждую минуту, прерывания каждые 4мс. Как видите я беру XOR не от 15000 как следовало, а от такого вот числа подобранного экспериментально. Попробуйте поставить там 15000 и брекпоинт на LMin++ Посмотрите что получится.

 

Zandy: TMR0, его ж еще предустанавливать надо после входа в прерывание
В общем случае да.
И если между моментом входа в прерывание и предустановкой проделывается некое количество команд, то период прерывания (по сравнению с расчетным) увеличится ровно на время выполнения этих команд. Разве не так?
Тут лучше нарисовать и посмотреть. От момента входа в обработчик проходит фиксированное время до предустановки таймера. От момента предустановки таймера до момента следующего входа в прерывание - также фиксированный интервал времени (на то он и таймер, он же независимо работает). Подбором числа, записываемого в регистр таймера в момент предустановки, подбираем период прерываний. От того, сколько будет команд в обработчике прерываний после предустановки таймера, период прерываний уже зависеть не будет.

Ну, в общем-то, всё правильно. Формулировка мне не вполне понятна была.

Сергей К: я бы не отказался от функции цифрового термометра
Тут проблем не вижу. Позже сможем добавить. Датчик подключить к RA4 через дополнительную кнопку.

 

предложение по выводу цифр-инициализировать массив значениями кодов символов,потом просто указывать индекс:

....
PORTB=Digit[4];//цифра 4
....

тогда кейсы не надо использовать

 

Может не совсем по теме, но что будет, если прерывание совпадет с выполнением двухтактовой команды? Может быть ошибка в один такт?

 

Zandy: Может не совсем по теме, но что будет, если прерывание совпадет с выполнением двухтактовой команды? Может быть ошибка в один такт?

Всенепременно

Maksim_86: Именно. Вектор прерываний у нас только 1. Во-первых уйдет время на распознание прерывания от таймера if (T0IF==1). Затем мы икрементируем нашу переменную(например A), каждые 4мс.

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

Zandy: И если между моментом входа в прерывание и предустановкой проделывается некое количество команд, то период прерывания (по сравнению с расчетным) увеличится ровно на время выполнения этих команд.

То есть, если перегружать счётчик в самом начале обработчика прерывания, и учесть при перезагрузке время выполнения команд до этой перезагрузки, то всё будет работать как часы

 

Кстати, вспомнил хитрый приём, который применял на сцениксах:


mov w,#-intPeriod ;1 ; return and add -intPeriod to the RTCC
retiw ;3 ; using the retiw instruction.

там была спец. команда возврата из прерываения retiw, которая вычитала из счётчика таймера число в аккумуляторе (период прерывания). Получалось совершенно неважно, сколько длился обработчик прерывания, лишь бы не дольше периода.
Можно попробовать такой же фокус и для обычных пиков, типа:


TMR0 -= INTERRUPT_PERIOD;

Я этого не пробовал, но, по идее, работать должно