Страница 1 из 1

16 битный таймер T1 ATmega8

Добавлено: Вс мар 30, 2008 13:36:30
UR4QBP
Как прочитать 16 битный результат вычислений таймера T1 в МК ATmega8 и поместить его в переменную, например "с".
Что я неправильно делаю:

c= TCNT1L; //Чтение младших 8 битов результата
с+=((int)TCNT1H<<8); //Плюс 8 старших битов результата

У меня в программе выглядит вот так, но результат получается не тот что надо. И еще, можно ли в любом месте программы извлечь результат вычисления таймера T1 ?

Добавлено: Вс мар 30, 2008 14:07:21
Brutaller
А что мешает сделать просто так:

Код: Выделить всё

с = TCNT1;
:)

Это на асме надо по отдельности считывать младшую и старшую часть регистра. А на сях это проще. Между прочим с чтением этого регистра есть кое какие грабли, так что если что, очень внимательно читать даташит. Ключевые слова "Accessing 16-bit Registers"

Re: 16 битный таймер T1 ATmega8

Добавлено: Вс мар 30, 2008 14:13:47
tych
UR4QBP писал(а):Как прочитать 16 битный результат вычислений таймера T1 в МК ATmega8 и поместить его в переменную, например "с"
Убедитесь что с у вас 16 битная беззнаковая.

Добавлено: Вс мар 30, 2008 14:13:49
UR4QBP
Подскажите переполнение таймера Т1 происходит при значени FFFF (65535), это правильно? И можно ли в любой момент прочитать значение регистра TCNT1?

Добавлено: Вс мар 30, 2008 14:29:43
Brutaller
UR4QBP писал(а):Подскажите переполнение таймера Т1 происходит при значени FFFF (65535), это правильно?
Не во всех режимах.
UR4QBP писал(а):И можно ли в любой момент прочитать значение регистра TCNT1?
Да. Но если используются прерывания, то их надо запрещать на момент считывания. Это связано с особенностями доступа к 16-битным регистрам. Еще раз повторяю, ищите в даташите слова Accessing 16-bit Registers, чтоб не нарваться на эти грабли.

Между прочим в даташите примеры есть и на асме и на сях.

Добавлено: Вс мар 30, 2008 14:40:59
UR4QBP
Brutaller писал(а):
UR4QBP писал(а):Подскажите переполнение таймера Т1 происходит при значени FFFF (65535), это правильно?
Не во всех режимах.
UR4QBP писал(а):И можно ли в любой момент прочитать значение регистра TCNT1?
Да. Но если используются прерывания, то их надо запрещать на момент считывания. Это связано с особенностями доступа к 16-битным регистрам. Еще раз повторяю, ищите в даташите слова Accessing 16-bit Registers, чтоб не нарваться на эти грабли.
У меня таймер начинает считать с нуля TCNT1=0x00, клок идет от внешнего генератора. Прерывания запрещаю устанавливая регистр TIMSK=0x00 и TIMSK=0x44 разрешаю, можно это делать в теле самой программы и с какого значения будет считать таймер после разрешения прерывания? Скажите, считывать значение счетного регистра TCNT1 нужно до или после запрета прерывания?

Добавлено: Вс мар 30, 2008 14:44:39
tych
UR4QBP писал(а):Подскажите переполнение таймера Т1 происходит при значени FFFF (65535), это правильно? И можно ли в любой момент прочитать значение регистра TCNT1 ?
Наверно при переходе в 0 - в ДШ должна быь временнАя диаграмма. Читать можно всегда но вероятна ошибка хотя и маловероятна.

Добавлено: Вс мар 30, 2008 15:02:35
Brutaller
Вообще то разговор идет о глобальном запрещении прерываний.

Запретили прерывания.
Прочитали регистр.
Разрешили прерывания.

А таймер как отсчитывает так и будет продолжать, пока его не остановить. При чем тут прерывания то?

Добавлено: Вс мар 30, 2008 15:08:26
UR4QBP
Таймер останавливаем записывая в регистр управления
TCCR1A=0x00; TCCR1B=0x00;
запускаем : TCCR1A=0x00; TCCR1B=0x06;
правильно?
И еще, практически какая максимально возможная частота
счета таймера Т1 от внешнего клока? По книжке по мегам в 2,5...3 раза ниже тактовой?

Добавлено: Вс мар 30, 2008 15:20:15
Brutaller
UR4QBP писал(а):Таймер останавливаем записывая в регистр управления
TCCR1A=0x00; TCCR1B=0x00;
запускаем : TCCR1A=0x00; TCCR1B=0x06;
правильно?
Не правильно.

Для запуска и остановки таймера нужен только TCCR1B
За это дело отвечают биты CS12, CS11, CS10
Установили все эти три бита в "0", таймер остановился.
А запускаем сответственно установкой в эти биты нужного значения для нужного источника тактовой(или предделитель или внешний источник). В даташите есть соответствующая табличка на стр. 100

Добавлено: Вс мар 30, 2008 15:26:23
UR4QBP
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
c=?; какое будет значение по прерыванию от переполнения таймера?
}

Добавлено: Вс мар 30, 2008 15:34:53
tych
При переполнении 0 должен быть если до выполнения считывания в процедуре таймер не успеет насчитать уже чего либо.

Добавлено: Вс мар 30, 2008 15:42:41
UR4QBP
В принципе, понятно, я сразу все пробую на тестовой плате. Хочу написать программу для частотомера, до 65536 кГц меряет точнейше, а свыше начинает неправильно считать.
По прерыванию таймера я к переменной "с" инкрементирую 65536, а когда запрещаю прерывание и останавливаю счетчик, значение счетного региста TCNT1 прибавляю к "с":

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
c+=65536;
}
.
.
.
.
TIMSK=0x00; TCCR2=0x00; TCCR1B=0x00;
c+=TCNT1;
Вот так.

Добавлено: Вс мар 30, 2008 15:46:00
tych
UR4QBP писал(а):какая максимально возможная частота
счета таймера Т1 от внешнего клока? По книжке по мегам в 2,5...3 раза ниже тактовой ?
И по даташиту более чем в 2 раза меньше тактовой. А вот у PIC аж 50 МГц ! у стареньких в том числе.

Добавлено: Вс мар 30, 2008 15:48:46
UR4QBP
tych писал(а): И по даташиту более чем в 2 раза меньше тактовой. А вот у PIC аж 50 МГц ! у стареньких в том числе.
Я в курсе что могут PIC, но пока занимаюсь чисто АVR.

Добавлено: Вс мар 30, 2008 16:06:26
tych
UR4QBP писал(а):и останавливаю счетчик
Счет лучше не останавливать.

Добавлено: Вс мар 30, 2008 16:34:25
Barni
Можно сделать так:
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
FREQ_M = FREQ_M + 0xFF;
}
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
TCCR0B = 0x00; //stop Timer0
TCCR1B = 0x00; //stop Timer1
TCNT1H=0x23; // Reinitialize Timer 1 value
TCNT1L=0x67;
FREQ = FREQ + FREQ_M + TCNT0;
TCNT0 = 0;
FREQ_M = 0;
if (OVR) COUNT=1;
OVR=!OVR;
TCCR1B=0x03; //start Timer1
TCCR0B=0x07; //start Timer0
}
//Индикация, FREQ = 0, COUNT=0
Делал частотомер на Тини2313 с кварцем 18МГц. Таймер0 считает по внешнему входу(проверял до 5МГц), а Таймер2 делает 2 интервала по 0,2сек. При COUNT=1 индикация. Точность 2,5Гц. Я добавлял прескалер на 400 и измерял до 2ГГц с точностью 1кГц.

Добавлено: Вс мар 30, 2008 16:41:26
UR4QBP
Спасибо, обязательно попробую, скоро в ночь на работу, еще поговорим.