Обсуждаем контроллеры компании Atmel.
Вт окт 03, 2023 16:13:48
Just_Fluffy, Вы забыли о system clock prescaler-е. Мы ведь хотим аппаратно получить 1 Гц - неважно какой ценой.)
А ещё есть 128 кГц intrc, который легко делится на 1024.)
Вт окт 03, 2023 16:55:05
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 кГц...
Вт окт 03, 2023 17:06:43
OKF, топикстартер зозвучил тактирование - 9600кГц, поэтому 128кГц не подходят.
Да ладно! Какая разница какой intrc! К тому же, ТС не говорит о погрешности формирования 1 сек. Это относительно OSCCAL. Ага?)
Вт окт 03, 2023 17:37:06
OKF, ну без постановки задачи можно долго гадать, какие требования.
Хотя да, при тактировании от intrc сложно говорить о точности временнЫх интервалов.
У меня была Мега8, которая молотила от intrc аж на 9,5 МГц.
Вт окт 03, 2023 17:56:27
У меня была Мега8, которая молотила от intrc аж на 9,5 МГц.
Это да, насколько помню, у старых Мег было несколько intrc, но калибровался только дефолтный на 1 мГц - остальные были +/- лапоть.(
Вт окт 03, 2023 18:17:19
Zero-error 1 second Timer
http://www.romanblack.com/one_sec.htmFclock = 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);
}
Вт окт 03, 2023 20:10:49
veso74, ого. Для тиньки с килобайтом флеша отдать четверть на генератор - жырно.
И я выше писала - при должном подборе прескалера можно обойтись однобайтной переменной.
Вт окт 03, 2023 20:16:58
Еще есть свободное место в 4/5 Flash и 15/16 RAM
. Начинаю оптимизировать, когда место /Flash, RAM/ заканчивается. В остальном часто ставляю код так, как заботал правильно с "первого раза" алгоритмически/математически. Метод интересен, точен и легко использовать с любыми clock. И можно добавить коррекцию, напр. наименьший шаг: 1/Fclock сек /что с коеффициентов таймера/прекалера невозможно/.
Вт окт 03, 2023 22:41:08
Just_Fluffy, 208 байтов - это тупо на Си.
если делать на ассемблере, то это же самое займет примерно в 10 раз меньше.
на 1200000 хватит 3 байта - вместо 4-байтовой переменной.
сравнить 3 байта (3 команды - 6 байтов кода),
если меньше - выйти из прерывания (1 команда - 2 байта кода),
иначе вычесть 3 байта (3 команды - 6 байтов кода),
и операции с портом - тоже несколько байт.
итого может оказаться даже меньше 20 байтов.
Вт окт 03, 2023 23:01:44
Starichok51, не возражаю. Но меньше 20 байт не будет, ибо таблица прерываний.
Но на Си проще. Мы уже обсуждали, грамотный код на Си на 20-30% больше такого же грамотного кода на асме.
Но вот такая сферически-вакуумная задача - не знаю. Поскольку вопрошающий в тему не смотрит (или смотрит, но молчит) - значит его все устраивает.
А наши полторы страницы трепа - сродни челенжу Романа ARV - сделать меандр на тини.
Ср окт 04, 2023 06:34:27
Если сильно захотеть, то можно всё.)
Голословно.
Вариант программного формирования 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
Ср окт 04, 2023 07:15:03
Голословно.
Вы что издеваетесь! Столько прожевали, а ему голословно.)
Ср окт 04, 2023 10:01:21
Just_Fluffy писал(а):Но меньше 20 байт не будет, ибо таблица прерываний.
я говорил про сам код.
а всю таблицу прерываний, как это делает компилятор Си, заполнять не нужно.
на ассемблере - если, допустим, используется только одно прерывание от таймера, то заполняем только адрес вектора этого прерывания, и сразу же после этого вектора начинаем основной код.
в моих проектах используется несколько векторов прерываний, и в некоторых проектах самый "дальний" - от готовности еепрома, и за ним сразу же начинается мой код.
а есть проекты, где используется только Таймер2 (в АТмега8), а это всего 6 байт "пропадает", считая от нулевого адреса.
Ср окт 04, 2023 13:24:47
Но меньше 20 байт не будет, ибо таблица прерываний.
"Да сьто вы говолите!") Уже было.
- Код:
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. Исправил.
Чт окт 05, 2023 15:55:03
А подскажите пожалуйста, как можно реализовать перестройку таймера в 328 меге на лету. Смысл такой: ловим прерывание по INT0, Выключаем прерывания по ногам, запускаем таймер на 1 отсчет допустим на 20 мс, после сработки прерывания меняем частоту на 10 мс.
Чт окт 05, 2023 16:16:43
А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...
Чт окт 05, 2023 17:04:40
А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...
Таймер 1 в режиме CTC
Добавлено after 1 minute 3 seconds:А, по моему, ничто не мешает просто писать другое значение счётчика == 10мс во время прерывания. Вы бы пример привели, а то неизвестно какой таймер, в каком режиме...
Ммм, забыл сказать, настройки прескалера тоже меняются.
Чт окт 05, 2023 17:14:06
Прескалер тоже можно сбрасывать. Ну и для 10 и 20 мс наверняка можно выбрать один прескалер.
Чт окт 05, 2023 19:58:28
Да все можно сбрасывать и все прекрасно работает, просто программист д...б. В своем же коде запутался. Наплодил переменных с почти одинаковыми названиями и репу чешет - "А ЧО не работает?" Вся программа на прерываниях работает в итоге как часики, надо было всего лишь глаза разуть. Это я изобретаю очередной костыль для ремонта холодильника - надо было протокол связи между процессорами пощупать. Таки удачно пощупал, спасибо за то, что мои вопросы терпите!
Пт окт 06, 2023 22:54:48
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 секунды. Тоже нашлось им применение
Ассемблер, кстати.
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.