Лидеры рейтинга

ID: 401284

Михаил Александров

Советник

349

Россия, Санкт-Петербург


ID: 259041

Алексеев Владимир Николаевич

Мастер-Эксперт

296

Россия, пос. Теплоозёрск, ЕАО


ID: 400669

epimkin

Профессионал

289


ID: 405049

vsetin

Студент

240


ID: 226425

Konstantin Shvetski

Модератор

130

Россия, Северодвинск


ID: 137394

Megaloman

Мастер-Эксперт

107

Беларусь, Гомель


ID: 325460

CradleA

Мастер-Эксперт

88

Беларусь, Минск


8.9.6

20.07.2021

JS: 2.9.12
CSS: 4.5.13
jQuery: 3.6.0
DataForLocalStorage: 2021-07-27 20:16:01-standard


Выбор, ремонт, проектирование и изготовление усилителей, акустических систем, аудиоаппаратуры.

Администратор раздела: Цикалов Игорь Константинович (Модератор)

Консультация онлайн # 185455

Раздел: Аудиоаппаратура
Автор вопроса: Дебелов Владимир Валентинович
Дата: 16.02.2012, 22:02 Консультация закрыта
Поступило ответов: 1

Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
Как по считать время между двумя событиями? Используется микроконтроллер AVR ATMega 16. Необходимо осуществить счетчик через таймер. При нажатии на кнопку, подключенную к Int0 запустить и при нажатии на другую Int1 - остановить.
Время необходимо отсчитывать в микросекундах
Диапазон измерения времени 1миллисек-1сек.
Помогите пожалуйста написать машинный си код для данного счетчика.

Ответ # 269986 от vladisslav
Здравствуйте, Дебелов Владимир Валентинович!
Если использовать встроенный генератор на 8 MHz, то на C как-то так:

Код
volatile unsigned long latch=0;

ISR(INT0_vect)
{
	if(TCCR==0)//debounce
	{
		TCNT0=0;
		//start timer 0
		TCCR0=0x02;//clkio/8
	}
}

ISR(INT1_vect)
{
	if(TCCR!=0)//debounce
	{
		//stop timer
		TCCR0=0;
		latch|=TCNT0;
	}
}

ISR(TIMER0_OVF_vect)
{
	latch+=0x100;
}

void main()
{
....

MCUCR&=0xf0;
//falling edge will trigger interrupts
MCUCR|=(1<<ISC11)|(0<<ISC10)|(1<<ISC01)|(0<<ISC00);
//enable interrupts
GICR|=(1<<INT0)|(1<<INT1);
TIMSK|=(1<<TOIE0);

....



Корректное значение в latch будет не сразу после прерывания INT1, так как в очереди может стоять прерывание по переполнению таймера.
Длительность должна измеряться достаточно точно в пределах от примерно 30 микросекунд (надо считать инструкции, чтобы оценить точнее)и до 4294967295 микросекунд, так как задержки до старта таймера/захвата значения должны получиться одинаковыми.
Можно использовать и другой таймер, но с 16-битным задержка при чтении будет немного больше.

vladisslav

Посетитель
16.02.2012, 22:12
5


Спасибо! Начинаю понемногу разбираться в работе внешних прерываний с вашей помощью

Мини-форум консультации # 185455

q_id

Сучкова Татьяна Михайловна

Мастер-Эксперт

ID: 680

1

= общий =    16.02.2012, 22:47

мини-форум вопроса

-----
Прикрепленные файлы:


bb6ce7ce0e75c40f76c4f0e79b968299.rar
скачать (13.3 кб)
неизвестный

2

= общий =    19.02.2012, 20:49

Здравствуйте, vladisslav!
Спасибо за помощь в написании кода
Напишите пожалуйста комментарий к коду
Какой оператор что делает, не могу разобраться.

неизвестный

3

= общий =    19.02.2012, 23:30

Если необходима очень высокая точность. то просто считывайте состояние пинов в обработчике прерывания таймера!!! И время съэкономите и размер кода. А главное не будет возникать вопроса с приоритетом прерывания.

неизвестный

4

= общий =    20.02.2012, 21:02

Приведите пожалуйста пример кода для ATmega16
Как это делается объясните пожалуйста?

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.

Лучшие эксперты раздела

CradleA

Мастер-Эксперт

Рейтинг: 88

Коцюрбенко Алексей Владимирович

Старший модератор

Рейтинг: 41

Лысков Игорь Витальевич

Мастер-Эксперт

Рейтинг: 0

Роман Селиверстов

Советник

Рейтинг: 0

Valery N

Мастер-Эксперт

Рейтинг: 0

Цикалов Игорь Константинович

Модератор

Рейтинг: 0