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

Обсуждаем контроллеры компании Atmel.
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

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

Сообщение OKF »

Just_Fluffy, Вы забыли о system clock prescaler-е. Мы ведь хотим аппаратно получить 1 Гц - неважно какой ценой.)
А ещё есть 128 кГц intrc, который легко делится на 1024.)
Реклама
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

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

Сообщение Just_Fluffy »

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
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

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

Сообщение OKF »

[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4484437#p4484437"]OKF, топикстартер зозвучил тактирование - 9600кГц, поэтому 128кГц не подходят.[/uquote]
Да ладно! Какая разница какой intrc! К тому же, ТС не говорит о погрешности формирования 1 сек. Это относительно OSCCAL. Ага?)
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

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

Сообщение Just_Fluffy »

OKF, ну без постановки задачи можно долго гадать, какие требования.
Хотя да, при тактировании от intrc сложно говорить о точности временнЫх интервалов.
У меня была Мега8, которая молотила от intrc аж на 9,5 МГц.
Белая и Пушистая
Реклама
Эиком - электронные компоненты и радиодетали
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

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

Сообщение OKF »

[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4484463#p4484463"]У меня была Мега8, которая молотила от intrc аж на 9,5 МГц.[/uquote]
Это да, насколько помню, у старых Мег было несколько intrc, но калибровался только дефолтный на 1 мГц - остальные были +/- лапоть.(
Реклама
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

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

Сообщение veso74 »

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.

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

#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
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

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

Сообщение Just_Fluffy »

veso74, ого. Для тиньки с килобайтом флеша отдать четверть на генератор - жырно.
И я выше писала - при должном подборе прескалера можно обойтись однобайтной переменной.
Белая и Пушистая
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

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

Сообщение veso74 »

Еще есть свободное место в 4/5 Flash и 15/16 RAM :). Начинаю оптимизировать, когда место /Flash, RAM/ заканчивается. В остальном часто ставляю код так, как заботал правильно с "первого раза" алгоритмически/математически. Метод интересен, точен и легко использовать с любыми clock. И можно добавить коррекцию, напр. наименьший шаг: 1/Fclock сек /что с коеффициентов таймера/прекалера невозможно/.
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

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

Сообщение Starichok51 »

Just_Fluffy, 208 байтов - это тупо на Си.
если делать на ассемблере, то это же самое займет примерно в 10 раз меньше.
на 1200000 хватит 3 байта - вместо 4-байтовой переменной.
сравнить 3 байта (3 команды - 6 байтов кода),
если меньше - выйти из прерывания (1 команда - 2 байта кода),
иначе вычесть 3 байта (3 команды - 6 байтов кода),
и операции с портом - тоже несколько байт.
итого может оказаться даже меньше 20 байтов.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

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

Сообщение Just_Fluffy »

Starichok51, не возражаю. Но меньше 20 байт не будет, ибо таблица прерываний.
Но на Си проще. Мы уже обсуждали, грамотный код на Си на 20-30% больше такого же грамотного кода на асме.
Но вот такая сферически-вакуумная задача - не знаю. Поскольку вопрошающий в тему не смотрит (или смотрит, но молчит) - значит его все устраивает.
А наши полторы страницы трепа - сродни челенжу Романа ARV - сделать меандр на тини.
Белая и Пушистая
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

[uquote="OKF",url="/forum/viewtopic.php?p=4484326#p4484326"]Если сильно захотеть, то можно всё.)[/uquote]Голословно.
Вариант программного формирования 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
.EXIT
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

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

Сообщение OKF »

[uquote="akl",url="/forum/viewtopic.php?p=4484683#p4484683"]Голословно.[/uquote]
Вы что издеваетесь! Столько прожевали, а ему голословно.)
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

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

Сообщение Starichok51 »

Just_Fluffy писал(а):Но меньше 20 байт не будет, ибо таблица прерываний.
я говорил про сам код.
а всю таблицу прерываний, как это делает компилятор Си, заполнять не нужно.
на ассемблере - если, допустим, используется только одно прерывание от таймера, то заполняем только адрес вектора этого прерывания, и сразу же после этого вектора начинаем основной код.
в моих проектах используется несколько векторов прерываний, и в некоторых проектах самый "дальний" - от готовности еепрома, и за ним сразу же начинается мой код.
а есть проекты, где используется только Таймер2 (в АТмега8), а это всего 6 байт "пропадает", считая от нулевого адреса.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

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

Сообщение OKF »

[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4484633#p4484633"]Но меньше 20 байт не будет, ибо таблица прерываний.[/uquote]
"Да сьто вы говолите!") Уже было.

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

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)
PS. Исправил.
Аватара пользователя
Viper_Snake
Электрический кот
Сообщения: 1046
Зарегистрирован: Вс мар 01, 2009 19:47:16
Откуда: Ростов-на-Дону

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

Сообщение Viper_Snake »

А подскажите пожалуйста, как можно реализовать перестройку таймера в 328 меге на лету. Смысл такой: ловим прерывание по INT0, Выключаем прерывания по ногам, запускаем таймер на 1 отсчет допустим на 20 мс, после сработки прерывания меняем частоту на 10 мс.
Не важно чем все начнется. Важно чем кончится!
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

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

Сообщение OKF »

А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...
Аватара пользователя
Viper_Snake
Электрический кот
Сообщения: 1046
Зарегистрирован: Вс мар 01, 2009 19:47:16
Откуда: Ростов-на-Дону

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

Сообщение Viper_Snake »

[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]
Ммм, забыл сказать, настройки прескалера тоже меняются.
Не важно чем все начнется. Важно чем кончится!
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

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

Сообщение OKF »

Прескалер тоже можно сбрасывать. Ну и для 10 и 20 мс наверняка можно выбрать один прескалер.
Аватара пользователя
Viper_Snake
Электрический кот
Сообщения: 1046
Зарегистрирован: Вс мар 01, 2009 19:47:16
Откуда: Ростов-на-Дону

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

Сообщение Viper_Snake »

Да все можно сбрасывать и все прекрасно работает, просто программист д...б. В своем же коде запутался. Наплодил переменных с почти одинаковыми названиями и репу чешет - "А ЧО не работает?" Вся программа на прерываниях работает в итоге как часики, надо было всего лишь глаза разуть. Это я изобретаю очередной костыль для ремонта холодильника - надо было протокол связи между процессорами пощупать. Таки удачно пощупал, спасибо за то, что мои вопросы терпите!
Не важно чем все начнется. Важно чем кончится!
ciaas
Нашел транзистор. Понюхал.
Сообщения: 152
Зарегистрирован: Вт окт 11, 2022 13:45:06

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

Сообщение ciaas »

[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 секунды. Тоже нашлось им применение :) :beer:
Ассемблер, кстати.
Ответить

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