Таймеры/счётчики в AVR

Обсуждаем контроллеры компании Atmel.
Ответить
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Сообщение kotriks »

COKPOWEHEU писал(а):
OCR2A = 0x1E85;
А ничего что у m168 таймер T2 восьмибитный?
Да и остальная логика на первый взгляд странная.
TCCR2A |= (1 << WGM21);
Чему равны остальные биты этого регистра? Лучше при настройке делать прямое присваивание.
TCCR2B |= (1 << CS21); делитель F_CPU/8 = 125 кГц
OCR2A = 0x1E85; если предположить, что этот регистр 16-битный, делитель равен 7814
Тогда прерывание возникает с частотой F_CPU/8/7814 = 16 Гц, то есть с интервалом 62,5 мс.
делаю так

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

TCCR2A = (1<<WGM21);    // Режим CTC (сброс по совпадению)
//TCCR2B = (1<<CS20);     // Тактирование от CLK.
TCCR2B = (1<<CS20)|(1<<CS21)|(1<<CS22);                         // Если нужен предделитель :
// TCCR2B = (1<<CS21);                     // CLK/8
// TCCR2B = (1<<CS20)|(1<<CS21);           // CLK/32
// TCCR2B = (1<<CS22);                     // CLK/64
// TCCR2B = (1<<CS20)|(1<<CS22);           // CLK/128
// TCCR2B = (1<<CS21)|(1<<CS22);           // CLK/256
// TCCR2B = (1<<CS20)|(1<<CS21)|(1<<CS22); // CLK/1024

OCR2A = 255;            // Верхняя граница счета. Диапазон от 0 до 255.
                        // Частота прерываний будет = Fclk/(N*(1+OCR2A)) 
                        // где N - коэф. предделителя (1, 8, 32, 64, 128, 256 или 1024)
TIMSK2 = (1<<OCIE2A);   // Разрешить прерывание по совпадению
срабатывает через секунду ((
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Через секунду?! Должно быть через четверть секунды. Если нужна какая-то точность, настройте предделитель на 1:64, модуль счета на 125, тогда частота прерываний будет 125 Гц, дальше программно.
Реклама
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Сообщение kotriks »

Разобрался

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

TCNT1H=0xA473 >> 8;
TCNT1L=0xA473 & 0xff;

TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0xA4;
TCNT1L=0x73;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;


interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
соде();
  
}

TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (1<<TOIE1);

Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

TCNT1H=0xA473 >> 8;
TCNT1L=0xA473 & 0xff;
Извращение. У Т1 так же как у Т2 есть режим CTC, то есть можно не дергать TCNT1 в каждом прерывании (что вы и так не делаете, как оно у вас тогда работает?).

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

OCR1A = 15624; //F_CPU/64-1  //здесь лучше десятичная запись, а еще лучше - формула
TCCR1B = (1<<WGM12 | 0b011<<CS10); //CTC-mode ; F_CPU/64
TIMSK = (1<<OCIE1A);
Реклама
Эиком - электронные компоненты и радиодетали
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Сообщение kotriks »

Не знаю как но работает :))
Реклама
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Сообщение kotriks »

COKPOWEHEU писал(а):
TCNT1H=0xA473 >> 8;
TCNT1L=0xA473 & 0xff;
Извращение. У Т1 так же как у Т2 есть режим CTC, то есть можно не дергать TCNT1 в каждом прерывании (что вы и так не делаете, как оно у вас тогда работает?).

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

OCR1A = 15624; //F_CPU/64-1  //здесь лучше десятичная запись, а еще лучше - формула
TCCR1B = (1<<WGM12 | 0b011<<CS10); //CTC-mode ; F_CPU/64
TIMSK = (1<<OCIE1A);
ошибочка, достаточно этого

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

TCCR1B=(1<<CS12);
TCNT1H=0xA4;
TCNT1L=0x73;
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1644
Зарегистрирован: Сб фев 18, 2012 15:42:29
Откуда: Курск

Сообщение mixon46 »

хочу сделать часы. САМ :) . к МК тини 2313 подключить кварц 32.768 гц. подать сигнал на 16 битный таймер. в регистре сравнения пропишу 32768. по сравнению вызвать прерывание что бы записать следующую секунду в переменную unsigned int. по расчетам ее хватит что бы показывать время в 12 часов. на 24 часа не хватит. мне как организовать сброс таймера? прям в прерывании. или можно как то по совпадению с регистром сравнения произвести сброс. потому что если я в прерывании буду сбрасывать то таймер же уже пойдет считать дальше чем 32768. или как :facepalm:

все он сбросится я понял :)) ну нуб точно
в режиме СТС он сбросится по совпадению точняк
akl
Друг Кота
Сообщения: 4453
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Замечу. У tiny2313 нет режима работы с часовым кварцем. Даже если удастся получить генерацию от кварца 32'768, контроллер будет шагать по программе именно с такой частотой. Быстродействия наверняка не хватит .
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Ну можно собрать внешний генератор с нужной частотой и уровнем сигнала и подать ее на вход T1 (PD5). Она же выход таймера 0 OC0B, это тоже можно как то использовать (объединить счетчики).
Можно затактировать МК кварцем 3.2768МГц, не знаю есть такие в продаже или нет. В инете попадались упоминания.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1644
Зарегистрирован: Сб фев 18, 2012 15:42:29
Откуда: Курск

Сообщение mixon46 »

ну я тогда соберу на обычной кмоп логике генератор. подам на вход счетчика. а сам МК пусть работает от внутреннего RC на частоте 8 мгЦ.


Я подумал а что я буду страдать ерундой. делать генератор. возьму кварц на 4 Мгц и через делитель 64 как раз четное подам на вход таймера. как раз 62500 тиков входит в 16 битный регистр таймера.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

mixon46 писал(а):Я подумал а что я буду страдать ерундой.
Раз у Вас, оказывается, нет ограничений по частоте, лучше уж тогда кварц на 20МГц. Используйте МК по быстродействию по максимуму. Ну или хотя бы 16МГц, если 20 не получится точно разделить до секунды.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1644
Зарегистрирован: Сб фев 18, 2012 15:42:29
Откуда: Курск

Сообщение mixon46 »

а зачем мне такое большое быстродействие. мне нужно просто часы :)
Друг Кота
Аватара пользователя
Сообщения: 6329
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

Ну если делать часы на МК, а не на жесткой логике, значит, в МК будет программа :) , и вопрос частоты кварца - не вопрос вовсе. Можно сделать начальную настройку на чуть более "быстрый" ход - 5...10с в сутки. А в программе предусмотреть периодическое - раз в несколько десятков минут - "выкусывание" лишней доли секунды. Поэтому кварц можно ставить любой, не заморачиваясь его кратностью. А изменяя интервал этого "выкусывания", осуществляем цифровую подстройку точности хода. Так сделано в наручных часах фирмы Интеграл ( я схемы не видел, но думаю, по логике - так ) .
Изображение
Вложения
N-1.JPG
(5.5 КБ) 1061 скачивание
Изображение
akl
Друг Кота
Сообщения: 4453
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

mixon46 писал(а):а зачем мне такое большое быстродействие...
Всё равно понадобится какая-то индикация; точность хода часов с кварцем выше чем с "часовыми". Ну и вообще часы на ATtiny2313 c любым, в допустимом диапазоне, кварцем делаются на одном таймере Т1. Пример ниже.
Вложения
freq_8MHz 001_1.jpg
(25.61 КБ) 633 скачивания
CLOCK_FULL.rar
(49.64 КБ) 208 скачиваний
Последний раз редактировалось akl Пт сен 23, 2016 00:52:28, всего редактировалось 1 раз.
Друг Кота
Аватара пользователя
Сообщения: 6329
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

Да кто спорит ? А не совсем понял - индикация чего ? Раз это часы, то индикация у них присутствует по определению. А индикация состояния корректора точности хода - можно, как в наручных часах, загнать ее в отдельный пункт менюшки. Можно и по другому - например, при настройке записать константу в EEPROM - я не думаю, что ее придется часто менять. И наконец - цифровая коррекция точности хода делается все на том же одном таймере Т1 :) - десяток добавочных строк в обработчике.
Изображение
akl
Друг Кота
Сообщения: 4453
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

mixon46 писал(а):...возьму кварц на 4 Мгц и через делитель 64 как раз четное подам на вход таймера. как раз 62500 тиков входит в 16 битный регистр таймера.
Типовое и очень хреновое решение. Реалии таковы, что кварц с надписью 4МГц совсем не обязан иметь частоту 4'000'000Гц. К примеру, частота генерации системы кварц-контроллер 4'009'543Гц будучи поделенной на 64/62500 даст период 997 619,93мкс ну очень мало напоминающий 1 секунду. Вскакивает необходимость в цифровом корректоре, состояние которого нужно как-то устанавливать; где-то хранить. Значит нужно меню, что сразу выбрасывает часы из разряда "простых". В программе, приведённой выше, нужно просто записать 4009543 и, в течение полугода, быть пунктуальным с точностью до 1 секунды.
Друг Кота
Аватара пользователя
Сообщения: 6329
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

Если бы мне пришла блажь делать часы ( как проект - это неинтересно, как способ сэкономить вместо покупки 2..3$ - это несерьезно ), я бы цифровой корректор делал в виде 5..6 джамперов, задающих 32..64 ступени коррекции с шагом, к примеру 100мс в сутки. На Тиньке, конечно, не получится - нужны дополнительные пины - но у меня на антресоли для такого случая завалялось бы пару Мегов-32 :) И менюшка не понадобилась бы.
Ну а 9 kHz (0,2%) отклонение от номинала для 4MHz-вого кварца - это вроде многовато на пару порядков. :( Что ж это за кварц ?
Изображение
akl
Друг Кота
Сообщения: 4453
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Написал же, к примеру. :) Чтобы пример был более убедителен симулировал в студии один из вариантов часов с таким кварцем, показывающий что без джамперов цифровой коррекции на ATtiny2313 можно сделать простые точные часы на любом кварце.
Изображение
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1644
Зарегистрирован: Сб фев 18, 2012 15:42:29
Откуда: Курск

Сообщение mixon46 »

сейчас не о точности. думаю как реализовать динамическую индикацию. мне не помогать! сам уже почти придумал. :)


все сдаюсь что то не получается :))
Спойлер#include <tiny2313.h>
#include <delay.h>

unsigned int se; //объявление глобальной переменной
//для хранения времени
flash unsigned char digits [10] =
{0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111 // 9
};

interrupt [TIM1_COMPA] void sec (void)//вызов прерывания по совпадению
{
se++; //прибавление единицы каждую секунду в регистр se
if (se==43200) //проверка регистра на истинность
{se=0;}; //обнуление регистра
if (PIND.6==0) //опрос кнопки
{delay_ms (3); //задержка анти дребезга
se=se+600; //прибавление 10 мин к регистру se
}
}

void main(void)
{
unsigned int discharge [6] = {4,4,4,0,0,0};

PORTB=0x00;
DDRB=0xFF;

PORTD=0b01000000;
DDRD=0b00111111;

TCCR1A=0x00; //регистр настройки таймера
TCCR1B=(1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10); //режим СТС делитель 64
TCNT1H=0x00; // старший счетный регистр
TCNT1L=0x00; //младший счетный регистр
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0xF4; // старший регистр сравнения А
OCR1AL=0x24; // младший регистр сравнения А или 62500 импульсов
OCR1BH=0x00;
OCR1BL=0x00;

GIMSK=0x00;
MCUCR=0x00;

TIMSK=(1<<OCIE1A); //прерывание по совпадению TCNT1 и OCR1A

USICR=0x00;

UCSRB=0x00;

ACSR=0x80;
DIDR=0x00;

while (1)
{#asm ("sei"); //глобальное разрешение прерывания
discharge [0]=se/36000; //запись десятков часов разряда в ячейку 1
discharge [1]=se%36000/3600; //запись единиц часов разряда в ячейку 2
discharge [2]=se%3600/600; //запись десятков минут разряда в ячейку 3
discharge [3]=se%600/60; //запись единиц минут разряда в ячейку 4
discharge [4]=se%60/10; //запись десятков секунд разряда в ячейку 5
discharge [5]=se%10; //запись единиц секунд в ячейку 6
PORTB=digits[discharge[0]]; //вывод цифры в порт B
PORTD=0b01100000;
delay_ms(3);
PORTB=digits[discharge[1]];
PORTD=0b01010000;
delay_ms(3);
PORTB=digits[discharge[2]];
PORTD=0b01001000;
delay_ms(3);
PORTB=digits[discharge[3]];
PORTD=0b01000100;
delay_ms(3);
PORTB=digits[discharge[4]];
PORTD=0b01000010;
delay_ms(3);
PORTB=digits[discharge[5]];
PORTD=0b01000001;
delay_ms(3);


}
}
помогите а то совсем не показывает как надо :)

ну вроде работает. правда протеус кривоват
akl
Друг Кота
Сообщения: 4453
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Не нравится отсутствие синхронности между отсчетом 1 секунды и выводом на индикатор. В часах должно быть всё синхронно.
Например
- 6 индикаторов полноразмерных часов
- длительность индикации каждого разряда 1'600мкс
- период индикации всех индикаторов 6*1'600мкс=9'600мкс, что составляет 1'000'000/9600~104Гц
- в регистр сравнения таймера при предделителе 64 записано 100-1
- ***число прерываний сравнения таймера 1'000'000/1'600=625, которое заносится в 16-разрядный регистр
- в обработчике производится вывод на следующий по порядку индикатор; определение интервала 1 секунды с помощью 16-разрядного регистра и, если секунда прошла, выход из режима ожидания -> преобразование нового значения времени
- переход на ***
Для большей свободы в выборе кварца таймер переводится в режим работы без предделителя, число 1'600мкс в тиках таймера F_cpu/625-1 заносится в регистр сравнения -> отсчитывается 624 периода индикации, а последнем периоде в регистр сравнения заносится досчет до 1 секунды типа F_cpu-(F_cpu/625)*624-1
Ответить

Вернуться в «AVR»