Таймеры/счётчики в AVR
Re: Таймеры/счётчики в AVR
Just_Fluffy, Вы забыли о system clock prescaler-е. Мы ведь хотим аппаратно получить 1 Гц - неважно какой ценой.)
А ещё есть 128 кГц intrc, который легко делится на 1024.)
А ещё есть 128 кГц intrc, который легко делится на 1024.)
- Реклама
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 534
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Таймеры/счётчики в AVR
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 кГц...
Клокпрескалер может делить тактовую на 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 кГц...
Белая и Пушистая
Re: Таймеры/счётчики в AVR
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4484437#p4484437"]OKF, топикстартер зозвучил тактирование - 9600кГц, поэтому 128кГц не подходят.[/uquote]
Да ладно! Какая разница какой intrc! К тому же, ТС не говорит о погрешности формирования 1 сек. Это относительно OSCCAL. Ага?)
Да ладно! Какая разница какой intrc! К тому же, ТС не говорит о погрешности формирования 1 сек. Это относительно OSCCAL. Ага?)
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 534
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Таймеры/счётчики в AVR
OKF, ну без постановки задачи можно долго гадать, какие требования.
Хотя да, при тактировании от intrc сложно говорить о точности временнЫх интервалов.
У меня была Мега8, которая молотила от intrc аж на 9,5 МГц.
Хотя да, при тактировании от intrc сложно говорить о точности временнЫх интервалов.
У меня была Мега8, которая молотила от intrc аж на 9,5 МГц.
Белая и Пушистая
Re: Таймеры/счётчики в AVR
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4484463#p4484463"]У меня была Мега8, которая молотила от intrc аж на 9,5 МГц.[/uquote]
Это да, насколько помню, у старых Мег было несколько intrc, но калибровался только дефолтный на 1 мГц - остальные были +/- лапоть.(
Это да, насколько помню, у старых Мег было несколько intrc, но калибровался только дефолтный на 1 мГц - остальные были +/- лапоть.(
- Реклама
-
veso74
- Поставщик валерьянки для Кота
- Сообщения: 1907
- Зарегистрирован: Сб май 05, 2012 20:24:52
- Откуда: KN34PC, Болгария
- Контактная информация:
Re: Таймеры/счётчики в AVR
Zero-error 1 second Timer
http://www.romanblack.com/one_sec.htm
Fclock = 9,6 / 8 = 1,2 MHz, использование одной переменной uint32_t -> Flash: 208 байта, RAM: 4 байта (MicroCore к Arduino IDE) светодиод мигает 1 сек вкл / 1 сек выкл. Фюзы: L: 6А, H: FF.
http://www.romanblack.com/one_sec.htm
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();
while (1);
}- Just_Fluffy
- Вымогатель припоя
- Сообщения: 534
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Таймеры/счётчики в AVR
veso74, ого. Для тиньки с килобайтом флеша отдать четверть на генератор - жырно.
И я выше писала - при должном подборе прескалера можно обойтись однобайтной переменной.
И я выше писала - при должном подборе прескалера можно обойтись однобайтной переменной.
Белая и Пушистая
-
veso74
- Поставщик валерьянки для Кота
- Сообщения: 1907
- Зарегистрирован: Сб май 05, 2012 20:24:52
- Откуда: KN34PC, Болгария
- Контактная информация:
Re: Таймеры/счётчики в AVR
Еще есть свободное место в 4/5 Flash и 15/16 RAM
. Начинаю оптимизировать, когда место /Flash, RAM/ заканчивается. В остальном часто ставляю код так, как заботал правильно с "первого раза" алгоритмически/математически. Метод интересен, точен и легко использовать с любыми clock. И можно добавить коррекцию, напр. наименьший шаг: 1/Fclock сек /что с коеффициентов таймера/прекалера невозможно/.
- Starichok51
- Модератор
- Сообщения: 19053
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Таймеры/счётчики в AVR
Just_Fluffy, 208 байтов - это тупо на Си.
если делать на ассемблере, то это же самое займет примерно в 10 раз меньше.
на 1200000 хватит 3 байта - вместо 4-байтовой переменной.
сравнить 3 байта (3 команды - 6 байтов кода),
если меньше - выйти из прерывания (1 команда - 2 байта кода),
иначе вычесть 3 байта (3 команды - 6 байтов кода),
и операции с портом - тоже несколько байт.
итого может оказаться даже меньше 20 байтов.
если делать на ассемблере, то это же самое займет примерно в 10 раз меньше.
на 1200000 хватит 3 байта - вместо 4-байтовой переменной.
сравнить 3 байта (3 команды - 6 байтов кода),
если меньше - выйти из прерывания (1 команда - 2 байта кода),
иначе вычесть 3 байта (3 команды - 6 байтов кода),
и операции с портом - тоже несколько байт.
итого может оказаться даже меньше 20 байтов.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 534
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Таймеры/счётчики в AVR
Starichok51, не возражаю. Но меньше 20 байт не будет, ибо таблица прерываний.
Но на Си проще. Мы уже обсуждали, грамотный код на Си на 20-30% больше такого же грамотного кода на асме.
Но вот такая сферически-вакуумная задача - не знаю. Поскольку вопрошающий в тему не смотрит (или смотрит, но молчит) - значит его все устраивает.
А наши полторы страницы трепа - сродни челенжу Романа ARV - сделать меандр на тини.
Но на Си проще. Мы уже обсуждали, грамотный код на Си на 20-30% больше такого же грамотного кода на асме.
Но вот такая сферически-вакуумная задача - не знаю. Поскольку вопрошающий в тему не смотрит (или смотрит, но молчит) - значит его все устраивает.
А наши полторы страницы трепа - сродни челенжу Романа ARV - сделать меандр на тини.
Белая и Пушистая
Re: Таймеры/счётчики в AVR
[uquote="OKF",url="/forum/viewtopic.php?p=4484326#p4484326"]Если сильно захотеть, то можно всё.)[/uquote]Голословно.
Вариант программного формирования 1 секундного интервала с реальной частотой
Вариант программного формирования 1 секундного интервала с реальной частотой
Код: Выделить всё
.INCLUDE "tn13Adef.inc"
.equ Fo=9326700
;.equ Fo=9600000
;24 байта
BEGIN:
SBI DDRB,0
LDI R20,BYTE3(Fo/6-1)
LDI R21,BYTE2(Fo/6-1)
LDI R22,BYTE1(Fo/6-1)
SBI PORTB,0
COUNT:
SUBI R22,1
SBCI R21,0
SBCI R20,0
BRCS BEGIN
BRNE COUNT
CBI PORTB,0
RJMP COUNT
.EXITRe: Таймеры/счётчики в AVR
[uquote="akl",url="/forum/viewtopic.php?p=4484683#p4484683"]Голословно.[/uquote]
Вы что издеваетесь! Столько прожевали, а ему голословно.)
Вы что издеваетесь! Столько прожевали, а ему голословно.)
- Starichok51
- Модератор
- Сообщения: 19053
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Таймеры/счётчики в AVR
я говорил про сам код.Just_Fluffy писал(а):Но меньше 20 байт не будет, ибо таблица прерываний.
а всю таблицу прерываний, как это делает компилятор Си, заполнять не нужно.
на ассемблере - если, допустим, используется только одно прерывание от таймера, то заполняем только адрес вектора этого прерывания, и сразу же после этого вектора начинаем основной код.
в моих проектах используется несколько векторов прерываний, и в некоторых проектах самый "дальний" - от готовности еепрома, и за ним сразу же начинается мой код.
а есть проекты, где используется только Таймер2 (в АТмега8), а это всего 6 байт "пропадает", считая от нулевого адреса.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Re: Таймеры/счётчики в AVR
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4484633#p4484633"]Но меньше 20 байт не будет, ибо таблица прерываний.[/uquote]
"Да сьто вы говолите!") Уже было.
PS. Исправил.
"Да сьто вы говолите!") Уже было.
Код: Выделить всё
int main() {
DDRB |= 1<<PB0;
TCCR0A = 1<<COM0A0 | 1<<WGM01; //toggle OC0A, CTC mode
TCCR0B = 1<<CS02 | 0<<CS01 | 0<<CS00; //256
OCR0A = 250 - 1; //128к 1Hz
while (1);
}
avr-gcc -o t13_blink.elf t13_blink.o -nostartfiles
avr-objcopy -O ihex t13_blink.elf t13_blink.hex
avr-size -C --mcu=attiny13 t13_blink.elf
AVR Memory Usage
----------------
Device: attiny13
Program: 16 bytes (1.6% Full)
(.text + .data + .bootloader)
Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)
- Viper_Snake
- Электрический кот
- Сообщения: 1046
- Зарегистрирован: Вс мар 01, 2009 19:47:16
- Откуда: Ростов-на-Дону
Re: Таймеры/счётчики в AVR
А подскажите пожалуйста, как можно реализовать перестройку таймера в 328 меге на лету. Смысл такой: ловим прерывание по INT0, Выключаем прерывания по ногам, запускаем таймер на 1 отсчет допустим на 20 мс, после сработки прерывания меняем частоту на 10 мс.
Не важно чем все начнется. Важно чем кончится!
Re: Таймеры/счётчики в AVR
А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...
- Viper_Snake
- Электрический кот
- Сообщения: 1046
- Зарегистрирован: Вс мар 01, 2009 19:47:16
- Откуда: Ростов-на-Дону
Re: Таймеры/счётчики в AVR
[uquote="OKF",url="/forum/viewtopic.php?p=4485211#p4485211"]А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...[/uquote]
Таймер 1 в режиме CTC
Добавлено after 1 minute 3 seconds:
[uquote="OKF",url="/forum/viewtopic.php?p=4485211#p4485211"]А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...[/uquote]
Ммм, забыл сказать, настройки прескалера тоже меняются.
Таймер 1 в режиме CTC
Добавлено after 1 minute 3 seconds:
[uquote="OKF",url="/forum/viewtopic.php?p=4485211#p4485211"]А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...[/uquote]
Ммм, забыл сказать, настройки прескалера тоже меняются.
Не важно чем все начнется. Важно чем кончится!
Re: Таймеры/счётчики в AVR
Прескалер тоже можно сбрасывать. Ну и для 10 и 20 мс наверняка можно выбрать один прескалер.
- Viper_Snake
- Электрический кот
- Сообщения: 1046
- Зарегистрирован: Вс мар 01, 2009 19:47:16
- Откуда: Ростов-на-Дону
Re: Таймеры/счётчики в AVR
Да все можно сбрасывать и все прекрасно работает, просто программист д...б. В своем же коде запутался. Наплодил переменных с почти одинаковыми названиями и репу чешет - "А ЧО не работает?" Вся программа на прерываниях работает в итоге как часики, надо было всего лишь глаза разуть. Это я изобретаю очередной костыль для ремонта холодильника - надо было протокол связи между процессорами пощупать. Таки удачно пощупал, спасибо за то, что мои вопросы терпите!
Не важно чем все начнется. Важно чем кончится!
Re: Таймеры/счётчики в AVR
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4482651#p4482651"]ciaas, ставите прескалер 64 (CS0[2:0] = 011) - получаете на вход таймера 9600 кГц / 64 = 150 кГц
Далее, таймер в СТС (WGM0[2:0 = 010) TOP <- OCR0A
В регистр OCR0A пишете 150-1 - получаете тик таймера 1 мс[/uquote]
А сделал я как предложила Just_Fluffy. Перфект! и респект ! Не знаю как поставить плюсик в телефоне.
А по пути бонусом получил 0,25 и 0,3 секунды. Тоже нашлось им применение

Ассемблер, кстати.
Далее, таймер в СТС (WGM0[2:0 = 010) TOP <- OCR0A
В регистр OCR0A пишете 150-1 - получаете тик таймера 1 мс[/uquote]
А сделал я как предложила Just_Fluffy. Перфект! и респект ! Не знаю как поставить плюсик в телефоне.
А по пути бонусом получил 0,25 и 0,3 секунды. Тоже нашлось им применение
Ассемблер, кстати.


