Just_Fluffy, Вы забыли о system clock prescaler-е. Мы ведь хотим аппаратно получить 1 Гц - неважно какой ценой.) А ещё есть 128 кГц intrc, который легко делится на 1024.)
OKF, топикстартер зозвучил тактирование - 9600кГц, поэтому 128кГц не подходят. Клокпрескалер может делить тактовую на 1, 2, 4, 8, 16, 32, 64, 128 и 256. Прескалер раймера - на 1, 8, 64, 256 и 1024
Нам нужно тактовую 9600000 разделить так, что бы на вход таймера приходила целочисленная частота от 1 до 256 Гц. Но комбинация прескалеров может дать минимальную целочисленную частоту 9600000/1024 = 9375 Гц. Дальнейшее кратное двум увеличение делителя даст дробную частоту на входе таймера. И мы не сможем таймером сделать ровно 1 Гц.
Так что я буду продолжать утверждать, что точный 1 Гц на 13 тине при идеальном клоке 9,6 МГц аппаратными средствами не достижим. OSCCAL не дает точную подстройку частоты, поэтому подгон клока под целочисленные делители - будет неточен.
Клокпрескалер 64 + прескайлер таймера 1024 дадут нам делитель 65536. И 9600000 / 65536 дадут 146,48 Гц. Деление таймером на 146 или 147 даст почти 1 Гц. Погрешность около 0,35%. Для мигалки этого, в принципе, достаточно.
Но клокпрескалер понизит всю тактовую и вместо 9,6МГц тактовая будет 150 кГц...
OKF, ну без постановки задачи можно долго гадать, какие требования. Хотя да, при тактировании от intrc сложно говорить о точности временнЫх интервалов. У меня была Мега8, которая молотила от intrc аж на 9,5 МГц.
Fclock = 9,6 / 8 = 1,2 MHz, использование одной переменной uint32_t -> Flash: 208 байта, RAM: 4 байта (MicroCore к Arduino IDE) светодиод мигает 1 сек вкл / 1 сек выкл. Фюзы: L: 6А, H: FF.
Код:
#include <avr/io.h> #include <avr/interrupt.h>
#define LED_PIN PB4
uint32_t bres = 0;
ISR(TIM0_OVF_vect) { bres += 256; // add 256 ticks to bresenham total
if (bres >= 1200000) { // if reached 1 second! bres -= 1200000; // subtract 1 second, retain error PORTB ^= _BV(LED_PIN); // toggle LED pin } }
int main(void) { DDRB = 0b00010000; // set LED pin as OUTPUT PORTB = 0b00000000; // set all pins to LOW TCCR0B |= _BV(CS00); // no prescaling TIMSK0 |= _BV(TOIE0); // enable Timer Overflow interrupt sei();
veso74, ого. Для тиньки с килобайтом флеша отдать четверть на генератор - жырно. И я выше писала - при должном подборе прескалера можно обойтись однобайтной переменной.
Еще есть свободное место в 4/5 Flash и 15/16 RAM . Начинаю оптимизировать, когда место /Flash, RAM/ заканчивается. В остальном часто ставляю код так, как заботал правильно с "первого раза" алгоритмически/математически. Метод интересен, точен и легко использовать с любыми clock. И можно добавить коррекцию, напр. наименьший шаг: 1/Fclock сек /что с коеффициентов таймера/прекалера невозможно/.
Just_Fluffy, 208 байтов - это тупо на Си. если делать на ассемблере, то это же самое займет примерно в 10 раз меньше. на 1200000 хватит 3 байта - вместо 4-байтовой переменной. сравнить 3 байта (3 команды - 6 байтов кода), если меньше - выйти из прерывания (1 команда - 2 байта кода), иначе вычесть 3 байта (3 команды - 6 байтов кода), и операции с портом - тоже несколько байт. итого может оказаться даже меньше 20 байтов.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Starichok51, не возражаю. Но меньше 20 байт не будет, ибо таблица прерываний. Но на Си проще. Мы уже обсуждали, грамотный код на Си на 20-30% больше такого же грамотного кода на асме. Но вот такая сферически-вакуумная задача - не знаю. Поскольку вопрошающий в тему не смотрит (или смотрит, но молчит) - значит его все устраивает. А наши полторы страницы трепа - сродни челенжу Романа ARV - сделать меандр на тини.
Но меньше 20 байт не будет, ибо таблица прерываний.
я говорил про сам код. а всю таблицу прерываний, как это делает компилятор Си, заполнять не нужно. на ассемблере - если, допустим, используется только одно прерывание от таймера, то заполняем только адрес вектора этого прерывания, и сразу же после этого вектора начинаем основной код. в моих проектах используется несколько векторов прерываний, и в некоторых проектах самый "дальний" - от готовности еепрома, и за ним сразу же начинается мой код. а есть проекты, где используется только Таймер2 (в АТмега8), а это всего 6 байт "пропадает", считая от нулевого адреса.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
А подскажите пожалуйста, как можно реализовать перестройку таймера в 328 меге на лету. Смысл такой: ловим прерывание по INT0, Выключаем прерывания по ногам, запускаем таймер на 1 отсчет допустим на 20 мс, после сработки прерывания меняем частоту на 10 мс.
_________________ Не важно чем все начнется. Важно чем кончится!
А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...
А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...
А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...
Ммм, забыл сказать, настройки прескалера тоже меняются.
_________________ Не важно чем все начнется. Важно чем кончится!
Да все можно сбрасывать и все прекрасно работает, просто программист д...б. В своем же коде запутался. Наплодил переменных с почти одинаковыми названиями и репу чешет - "А ЧО не работает?" Вся программа на прерываниях работает в итоге как часики, надо было всего лишь глаза разуть. Это я изобретаю очередной костыль для ремонта холодильника - надо было протокол связи между процессорами пощупать. Таки удачно пощупал, спасибо за то, что мои вопросы терпите!
_________________ Не важно чем все начнется. Важно чем кончится!
ciaas, ставите прескалер 64 (CS0[2:0] = 011) - получаете на вход таймера 9600 кГц / 64 = 150 кГц Далее, таймер в СТС (WGM0[2:0 = 010) TOP <- OCR0A В регистр OCR0A пишете 150-1 - получаете тик таймера 1 мс
А сделал я как предложила Just_Fluffy. Перфект! и респект ! Не знаю как поставить плюсик в телефоне. А по пути бонусом получил 0,25 и 0,3 секунды. Тоже нашлось им применение Ассемблер, кстати.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения