Страница 1 из 1
Mega16, таймер. Непонятное поведение
Добавлено: Пн июн 18, 2007 00:09:51
proton
При создании устройства, где используются таймеры, наткнулся на непонятный отсчёт времени. При запуске таймера время отсчёта гуляло, то на 1 сек. меньше, а то на две скинет (в данном случае минимальная дискретность 1 сек). Вернулся к азам - взял макетку, смонтировал схему, удалил весь код не относящийся к данной проблеме, но к сожалению проблема осталась. В прикрепленном файле описал схему, порядок работы и код. Обойти этот случай можно уменьшив дискретность счёта, но в данном случае мне важно где я "вспоткнулся". Спасибо всем кто поможет!

Добавлено: Пн июн 18, 2007 08:04:51
ARV
проблема по-моему кроется в том, что перед разрешением прерываний по "совпадению" не проверяется состояние флага запроса этого прерывания. Если кнопка не нажималась довольно долго, то этот флаг обязательно будет стоять (т.к. совпадений было много-много), а значит прерывание возникнет сразу же после его разрешения, что и исказит минимум на 1 секунду временной интервал. По-моему, надо просто сбросить флаг запроса перед тем, как разрешить прерывания.
Сейчас так:
Код: Выделить всё
ldi Temp0,0
out TCNT1L,Temp0 ;обнуление таймера перед запуском
out TCNT1H,Temp0
ldi Temp0,timer_on ;разрешить прерывание таймера_1A по совпадению
out TIMSK,Temp0
Надо так:
Код: Выделить всё
ldi Temp0,0
out TCNT1L,Temp0 ;обнуление таймера перед запуском
out TCNT1H,Temp0
ldi Temp0,timer_on
out TIFR, Temp0 ; сбросим флаг запроса прерывания
out TIMSK,Temp0 ;разрешить прерывание таймера_1A по совпадению
Добавлено: Пн июн 18, 2007 11:20:57
proton
Всё естественно, а прописную истину забыл. Спасибо. Как говорится "решая забачи по высшей математике, ошибка будет в использовании таблицы умножения"
Добавлено: Пн июн 18, 2007 19:20:50
proton
Вечером всё проверил в "железе" - часть проблеммы снялось(считает правильно 3-2-1-стоп) кроме первого раза. После включения питания или после сброса (ресет) первый раз считает на 1 сек меньше, т.е. 2-1-стоп. Себе мозги этой простой программой уже настолько замылил, что не вижу никаких ошибок.
Добавлено: Пн июн 18, 2007 20:55:02
ARV
proton, попробуй таймер запускать тогда, когда надо, а не заранее, т.е. после нажатия кнопки своей, а после отработки задержки - останавливай его.
Добавлено: Вт июн 19, 2007 17:03:57
proton
Код (как должно быть):
ldi Temp0,0
out TCNT1H,Temp0 ;обнуление таймера перед запуском
out TCNT1L,Temp0
ldi Temp0,timer_on
out TIFR, Temp0 ; сбросим флаг запроса прерывания
out TIMSK,Temp0 ;разрешить прерывание таймера_1A по совпадению
Все оказалось как всегда не очень сложно. А всеошибки в первую очередь от невнимательности. В исходном файле первую ошибку помог найти AVR за что ему большое спасибо. А вторая ошибка - это очерёдность обнуления 16 разрядного регистра таймара_1. Спасибо всем кто помог или попытался помочь.
tych: По поводу перейти на язык СИ. Я и на СИ могу написать эту программу. На СИ обращение к 16разрядному регистру идёт как к единому целому регистру. Меня зацепило вроде правильно написанная програмка, а не работает. Не разберёшься сразу в проблемме, значит в последствии сложности могут возникнуть.
Добавлено: Вт июн 19, 2007 17:13:18
ARV
И тебе спасибо, что не перепутал мой ник...
Добавлено: Вт июн 19, 2007 20:10:35
tych
proton писал(а):На СИ обращение к 16разрядному регистру идёт как к единому целому регистру.
Это от компилятора зависит - к некоторым можно обратится как к одному а обычно обращаются к L и H раздельно.
Добавлено: Вт июн 19, 2007 21:49:56
proton
ARV: в жизни всякое бывает, в том числе и ошибки в никах.

Извини. [/b]
Добавлено: Ср июн 20, 2007 08:21:24
ARV
proton писал(а):ARV: в жизни всякое бывает, в том числе и ошибки в никах.

Извини.
Все нормально, просто были у меня неприятности от подобных ошибок, потому так и реагирую.