А ничего что у m168 таймер T2 восьмибитный? Да и остальная логика на первый взгляд странная.
TCCR2A |= (1 << WGM21);
Чему равны остальные биты этого регистра? Лучше при настройке делать прямое присваивание. TCCR2B |= (1 << CS21); делитель F_CPU/8 = 125 кГц OCR2A = 0x1E85; если предположить, что этот регистр 16-битный, делитель равен 7814 Тогда прерывание возникает с частотой F_CPU/8/7814 = 16 Гц, то есть с интервалом 62,5 мс.
OCR2A = 255; // Верхняя граница счета. Диапазон от 0 до 255. // Частота прерываний будет = Fclk/(N*(1+OCR2A)) // где N - коэф. предделителя (1, 8, 32, 64, 128, 256 или 1024) TIMSK2 = (1<<OCIE2A); // Разрешить прерывание по совпадению
Через секунду?! Должно быть через четверть секунды. Если нужна какая-то точность, настройте предделитель на 1:64, модуль счета на 125, тогда частота прерываний будет 125 Гц, дальше программно.
Извращение. У Т1 так же как у Т2 есть режим CTC, то есть можно не дергать TCNT1 в каждом прерывании (что вы и так не делаете, как оно у вас тогда работает?).
OCR1A = 15624; //F_CPU/64-1 //здесь лучше десятичная запись, а еще лучше - формула TCCR1B = (1<<WGM12 | 0b011<<CS10); //CTC-mode ; F_CPU/64 TIMSK = (1<<OCIE1A);
Извращение. У Т1 так же как у Т2 есть режим CTC, то есть можно не дергать TCNT1 в каждом прерывании (что вы и так не делаете, как оно у вас тогда работает?).
OCR1A = 15624; //F_CPU/64-1 //здесь лучше десятичная запись, а еще лучше - формула TCCR1B = (1<<WGM12 | 0b011<<CS10); //CTC-mode ; F_CPU/64 TIMSK = (1<<OCIE1A);
хочу сделать часы. САМ . к МК тини 2313 подключить кварц 32.768 гц. подать сигнал на 16 битный таймер. в регистре сравнения пропишу 32768. по сравнению вызвать прерывание что бы записать следующую секунду в переменную unsigned int. по расчетам ее хватит что бы показывать время в 12 часов. на 24 часа не хватит. мне как организовать сброс таймера? прям в прерывании. или можно как то по совпадению с регистром сравнения произвести сброс. потому что если я в прерывании буду сбрасывать то таймер же уже пойдет считать дальше чем 32768. или как
все он сбросится я понял ну нуб точно в режиме СТС он сбросится по совпадению точняк
Замечу. У tiny2313 нет режима работы с часовым кварцем. Даже если удастся получить генерацию от кварца 32'768, контроллер будет шагать по программе именно с такой частотой. Быстродействия наверняка не хватит .
Ну можно собрать внешний генератор с нужной частотой и уровнем сигнала и подать ее на вход T1 (PD5). Она же выход таймера 0 OC0B, это тоже можно как то использовать (объединить счетчики). Можно затактировать МК кварцем 3.2768МГц, не знаю есть такие в продаже или нет. В инете попадались упоминания.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
ну я тогда соберу на обычной кмоп логике генератор. подам на вход счетчика. а сам МК пусть работает от внутреннего RC на частоте 8 мгЦ.
Я подумал а что я буду страдать ерундой. делать генератор. возьму кварц на 4 Мгц и через делитель 64 как раз четное подам на вход таймера. как раз 62500 тиков входит в 16 битный регистр таймера.
mixon46 писал(а):Я подумал а что я буду страдать ерундой.
Раз у Вас, оказывается, нет ограничений по частоте, лучше уж тогда кварц на 20МГц. Используйте МК по быстродействию по максимуму. Ну или хотя бы 16МГц, если 20 не получится точно разделить до секунды.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Ну если делать часы на МК, а не на жесткой логике, значит, в МК будет программа , и вопрос частоты кварца - не вопрос вовсе. Можно сделать начальную настройку на чуть более "быстрый" ход - 5...10с в сутки. А в программе предусмотреть периодическое - раз в несколько десятков минут - "выкусывание" лишней доли секунды. Поэтому кварц можно ставить любой, не заморачиваясь его кратностью. А изменяя интервал этого "выкусывания", осуществляем цифровую подстройку точности хода. Так сделано в наручных часах фирмы Интеграл ( я схемы не видел, но думаю, по логике - так ) .
mixon46 писал(а):а зачем мне такое большое быстродействие...
Всё равно понадобится какая-то индикация; точность хода часов с кварцем выше чем с "часовыми". Ну и вообще часы на ATtiny2313 c любым, в допустимом диапазоне, кварцем делаются на одном таймере Т1. Пример ниже.
Да кто спорит ? А не совсем понял - индикация чего ? Раз это часы, то индикация у них присутствует по определению. А индикация состояния корректора точности хода - можно, как в наручных часах, загнать ее в отдельный пункт менюшки. Можно и по другому - например, при настройке записать константу в EEPROM - я не думаю, что ее придется часто менять. И наконец - цифровая коррекция точности хода делается все на том же одном таймере Т1 - десяток добавочных строк в обработчике.
mixon46 писал(а):...возьму кварц на 4 Мгц и через делитель 64 как раз четное подам на вход таймера. как раз 62500 тиков входит в 16 битный регистр таймера.
Типовое и очень хреновое решение. Реалии таковы, что кварц с надписью 4МГц совсем не обязан иметь частоту 4'000'000Гц. К примеру, частота генерации системы кварц-контроллер 4'009'543Гц будучи поделенной на 64/62500 даст период 997 619,93мкс ну очень мало напоминающий 1 секунду. Вскакивает необходимость в цифровом корректоре, состояние которого нужно как-то устанавливать; где-то хранить. Значит нужно меню, что сразу выбрасывает часы из разряда "простых". В программе, приведённой выше, нужно просто записать 4009543 и, в течение полугода, быть пунктуальным с точностью до 1 секунды.
Если бы мне пришла блажь делать часы ( как проект - это неинтересно, как способ сэкономить вместо покупки 2..3$ - это несерьезно ), я бы цифровой корректор делал в виде 5..6 джамперов, задающих 32..64 ступени коррекции с шагом, к примеру 100мс в сутки. На Тиньке, конечно, не получится - нужны дополнительные пины - но у меня на антресоли для такого случая завалялось бы пару Мегов-32 И менюшка не понадобилась бы. Ну а 9 kHz (0,2%) отклонение от номинала для 4MHz-вого кварца - это вроде многовато на пару порядков. Что ж это за кварц ?
Написал же, к примеру. Чтобы пример был более убедителен симулировал в студии один из вариантов часов с таким кварцем, показывающий что без джамперов цифровой коррекции на ATtiny2313 можно сделать простые точные часы на любом кварце.
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);
Не нравится отсутствие синхронности между отсчетом 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