Таймеры/счётчики в AVR
- VNS
- Говорящий с текстолитом
- Сообщения: 1627
- Зарегистрирован: Пт дек 10, 2021 12:48:46
- Откуда: Тюмень
Re: Таймеры/счётчики в AVR
[uquote="B@R5uk",url="/forum/viewtopic.php?p=4315356#p4315356"]хотелось бы знать, как работает предделитель таймеров, есть ли у него "железный" сброс?[/uquote]
В даташите наверняка всё описано… не пробовали почитать даташит?
В даташите наверняка всё описано… не пробовали почитать даташит?
- Реклама
- Starichok51
- Модератор
- Сообщения: 19053
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Таймеры/счётчики в AVR
так это же читать надо...
а чукча - писатель, а не читатель...
а чукча - писатель, а не читатель...
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Таймеры/счётчики в AVR
Даташит зачитал до дыр в мониторе. Ничего конкретного не нашёл. Может ап-ноут какой посоветуете почитать про таймеры?
- Starichok51
- Модератор
- Сообщения: 19053
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Таймеры/счётчики в AVR
плохо читал.
есть регистр SFIOR, там есть биты для сброса предделителей таймеров.
если сомневаешься, что после подачи питания предделители в нуле, сбрось их самостоятельно.
есть регистр SFIOR, там есть биты для сброса предделителей таймеров.
если сомневаешься, что после подачи питания предделители в нуле, сбрось их самостоятельно.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Таймеры/счётчики в AVR
Про регистр я в курсе, использую на всякий случай. Вопрос не в том, что я сомневаюсь, а в том, как оно на самом деле.
- Реклама
-
veso74
- Поставщик валерьянки для Кота
- Сообщения: 1907
- Зарегистрирован: Сб май 05, 2012 20:24:52
- Откуда: KN34PC, Болгария
- Контактная информация:
Re: Таймеры/счётчики в AVR
Попробуйте сам написать тест. Просто пишите в UART состояние преди и след установки напр. таймера.
Ниже: на ATmega328 (Arduino UNO):
резултат:
в --- start --- нажимаю кнопку RESET
TCCR1B = 0b00000011 - начальное состояние
TCCR1B = 0b00001100 - после установки для 1 Hz
Ниже: на ATmega328 (Arduino UNO):
Код: Выделить всё
void setup() {
for (uint32_t i = 0; i < 10000000; i++) {
}
Serial.begin(57600);
Serial.println("--- start ---");
Serial.println(TCCR1B, BIN);
noInterrupts(); // initialize timer1 and disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 62500; // compare match register 16 MHz / 256 / 1 Hz
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts
}
void loop() {
}
ISR(TIMER1_COMPA_vect) {
Serial.println(TCCR1B, BIN);
}Код: Выделить всё
21:31:52.575 -> --- start ---
21:31:52.575 -> 11
21:31:53.575 -> 1100
21:31:54.575 -> 1100
21:31:55.575 -> 1100
21:31:56.575 -> 1100
21:31:58.455 -> --- start ---
21:31:58.455 -> 11
21:31:59.455 -> 1100
21:32:00.455 -> 1100
21:32:01.455 -> 1100
21:32:02.455 -> 1100
...TCCR1B = 0b00000011 - начальное состояние
TCCR1B = 0b00001100 - после установки для 1 Hz
Re: Таймеры/счётчики в AVR
Можно понимать, что после внешнего сброса таймер 1 начинает считать тактовую с предделителем 64???veso74 писал(а): в --- start --- нажимаю кнопку RESET
TCCR1B = 0b00000011 - начальное состояние
TCCR1B = 0b00001100 - после установки для 1 Hz
Уточню, для получения интервала 1 секунда, задавать нужноOCR1A = 62500; // compare match register 16 MHz / 256 / 1 Hz
OCR1A = 62500-1, иначе интервал будет на 256 тактов длиннее. https://radiokot.ru/forum/viewtopic.php ... 4#p4222274
-
veso74
- Поставщик валерьянки для Кота
- Сообщения: 1907
- Зарегистрирован: Сб май 05, 2012 20:24:52
- Откуда: KN34PC, Болгария
- Контактная информация:
Re: Таймеры/счётчики в AVR
[uquote="akl",url="/forum/viewtopic.php?p=4315520#p4315520"]... для получения интервала 1 секунда, задавать нужно OCR1A = 62500-1[/uquote]
Это понятно, спс, в спешке, не обращайте внимания
.
Из других систем и языков мне осталос правило: в начале, по возможности: все с первоначальным установлением. Как в случае и с используем Таймер_х: в начальном состоянии все регистры.
Это понятно, спс, в спешке, не обращайте внимания
- B@R5uk
- Собутыльник Кота
- Сообщения: 2896
- Зарегистрирован: Сб ноя 13, 2010 12:53:25
- Откуда: приходит весна?
Re: Таймеры/счётчики в AVR
[uquote="veso74",url="/forum/viewtopic.php?p=4315450#p4315450"]Попробуйте сам написать тест[/uquote]
Да, пожалуй, хороший совет, на корифеев надейся, а сам не плошай. Написал следующую программу. На выводе PB0 весит светодиод. Идея заключается в следующем. Программа инициализирует таймер 0, подключая его к предделителю на 1024, затем выжидает 768 (с хвостиком) тактов и читает значение счётчика этого таймера. Если значение отлично от нуля, то светодиод на PB0 выключается. Смысл в том, чтобы загрузить эту программу в МК и периодически делать reset. Если предделитель аппаратно не сбрасывается, то хотя бы иногда за 3/4 периода он будет выдавать импульс на таймер 0 за счёт того, что его содержимое было отлично от нуля в начале работы МК. Поэтому светодиод иногда будет гаснуть. Если же он аппаратно сбрасывается, то содержимое счётчика таймера в момент чтения программой будет 0 всегда, светодиод будет гореть всегда.
Результат эксперимента: светодиод горит всегда. Конечно, если я ОЧЕНЬ несчастливый человек, и мне жутко не везёт КАЖДЫЙ раз, то это ничего не значит. В противном случае с вероятностью экспоненциально стремящейся к 100%, предделитель таймеров аппаратно сбрасывается при хардовом ресэте. Вопрос решён, всем спасибо за дискуссию!
П.С. Пожелание разрабам: пишите в документацию все подробности работы вашего устройства!
Да, пожалуй, хороший совет, на корифеев надейся, а сам не плошай. Написал следующую программу. На выводе PB0 весит светодиод. Идея заключается в следующем. Программа инициализирует таймер 0, подключая его к предделителю на 1024, затем выжидает 768 (с хвостиком) тактов и читает значение счётчика этого таймера. Если значение отлично от нуля, то светодиод на PB0 выключается. Смысл в том, чтобы загрузить эту программу в МК и периодически делать reset. Если предделитель аппаратно не сбрасывается, то хотя бы иногда за 3/4 периода он будет выдавать импульс на таймер 0 за счёт того, что его содержимое было отлично от нуля в начале работы МК. Поэтому светодиод иногда будет гаснуть. Если же он аппаратно сбрасывается, то содержимое счётчика таймера в момент чтения программой будет 0 всегда, светодиод будет гореть всегда.
Код: Выделить всё
.include"m8def.inc"
;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
; Инициализация периферии МК
; Настройка портов ввода-вывода
ldi r16, 0xFF ; На входах -- подтяжка
out PORTB, r16
out PORTD, r16
out PORTC, r16
ldi r16, 0x01 ; PB0 -- выход, остальные биты
out DDRB, r16 ; порта B -- входы
clr r16 ; Порты C и D -- входы
out DDRC, r16
out DDRD, r16
; Настройка таймера 0
clr r16
out TCNT0, r16
ldi r16, 0x05 ; Предделитель 1024
out TCCR0, r16
;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
; Основная программа
; Выжидание 768 тактов
clr r16
pauseLoop: dec r16
brne pauseLoop
; Проверка содержимого счётчика таймера 0
in r16, TCNT0
tst r16
breq finalLoop
; Если счётчик отличен от нуля, сброс пина PB0 в ноль
ldi r16, 0xFE
out PORTB, r16
; Конец программы
finalLoop: rjmp finalLoop
;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
П.С. Пожелание разрабам: пишите в документацию все подробности работы вашего устройства!
- Мокренькая кисонька
- Открыл глаза
- Сообщения: 59
- Зарегистрирован: Вт сен 27, 2011 07:28:44
- Откуда: Москва
- Контактная информация:
Re: Таймеры/счётчики в AVR
Господа коты, помогите разобраться с формированием интервалов.
Я использую WDT-таймер настроенный на интервал 16мс.
В прерывании таймера я инкрементирую 8-и битную переменную.
А в главном цикле использую такой код:
1. Без явного указания беззнаковости интервала (10U) оно не работает, почему так? Со всякими millis()'ами ведь работает?
2. Экономлю память, поэтому все переменные uint8_t, соотв. ловлю переполнение и происходит "дрыг". Как сделать, чтобы переполнение было пофиг? Самого диапазона интервалов при 1 тике раз в 16мс мне хватает, разобраться бы с переполнением.
Я подсмотрел вот такой код у Гайвера, он работает, но значение интервала желательно выбрать кратным степени двойки, т.к. используется деление, а это не всегда возможно...
Я использую WDT-таймер настроенный на интервал 16мс.
В прерывании таймера я инкрементирую 8-и битную переменную.
Код: Выделить всё
ISR(WDT_vect)
{
WDTCR |=(1<<WDTIE);
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{systime++;}
}
Код: Выделить всё
if (systime - tmr1 >= 10U)
{
tmr1 = systime;
PORTB ^= (1 << PB3);
}
2. Экономлю память, поэтому все переменные uint8_t, соотв. ловлю переполнение и происходит "дрыг". Как сделать, чтобы переполнение было пофиг? Самого диапазона интервалов при 1 тике раз в 16мс мне хватает, разобраться бы с переполнением.
Я подсмотрел вот такой код у Гайвера, он работает, но значение интервала желательно выбрать кратным степени двойки, т.к. используется деление, а это не всегда возможно...
Код: Выделить всё
uint8_t timeLeft = systime - tmr1;
if (timeLeft >=8)
{
tmr1 += 8 * (timeLeft / 8);
PORTB ^= (1 << PB3);
}
ИзвЕните от слова - веник, ИзвИните от слова - вина.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18556
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Таймеры/счётчики в AVR
внутри обработчика прерывания не нужно использовать ATOMIC_BLOCK, поскольку обработчик прерывания уже "атомно" исполняется по отношению к остальному коду.
поскольку я не помню (и не собираюсь запоминать) приоритеты операций, рекомендую взять разность в скобки
влияние U может быть в том, что по умолчанию все результаты и константы имеют тип int, т.е. со знаком, а вам знак не нужен...
поскольку я не помню (и не собираюсь запоминать) приоритеты операций, рекомендую взять разность в скобки
Код: Выделить всё
if ((systime - tmr1) >= 10U)если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Таймеры/счётчики в AVR
кисонька, вы покажите определения переменных, а то по огрызкам сложно судить.
- Мокренькая кисонька
- Открыл глаза
- Сообщения: 59
- Зарегистрирован: Вт сен 27, 2011 07:28:44
- Откуда: Москва
- Контактная информация:
Re: Таймеры/счётчики в AVR
Со скобками полезный совет, спасибо! Т.к. у меня тоже приоритеты не запоминаются, всегда подглядываю в таблицу.
В общем с этим U непонятно, у меня переменная таймера и переменная "подтаймера" строго uint8_t. Значит минус туда не запихнешь.
Но интересно другое! Если используется промежуточная переменная или счет времени обернуть в функцию, то тогда явное указание беззнаковости не нужно.
Например:
Подозреваю эффект открытия новых чудес, когда плохо читал документацию... Но что-то я упускаю.
И еще про этот кусок кода, он корректно отрабатывает переполнение щ0ччика, интервалы все ровные, но смущает вот что:
Изначально было так:
Я на бумажке посчитал, результат такой же, как если бы просто значение этой переменной прибавить к tmr1. Зачем тут эти выкрутасы с делением и умножением?
Добавлено after 7 minutes 45 seconds:
[uquote="OKF",url="/forum/viewtopic.php?p=4328352#p4328352"]кисонька, вы покажите определения переменных, а то по огрызкам сложно судить.[/uquote]
Пардон.
В общем с этим U непонятно, у меня переменная таймера и переменная "подтаймера" строго uint8_t. Значит минус туда не запихнешь.
Но интересно другое! Если используется промежуточная переменная или счет времени обернуть в функцию, то тогда явное указание беззнаковости не нужно.
Например:
Код: Выделить всё
uint8_t timeLeft = systime - tmr1;
if (timeLeft >=10)
{
tmr1 += timeLeft;
PORTB ^= (1 << PB3);
}
И еще про этот кусок кода, он корректно отрабатывает переполнение щ0ччика, интервалы все ровные, но смущает вот что:
Изначально было так:
Код: Выделить всё
tmr1 += 8 * (timeLeft / 8);
Добавлено after 7 minutes 45 seconds:
[uquote="OKF",url="/forum/viewtopic.php?p=4328352#p4328352"]кисонька, вы покажите определения переменных, а то по огрызкам сложно судить.[/uquote]
Пардон.
Код: Выделить всё
volatile uint8_t systime = 0; // глобальная переменная, которую крутит прерывание таймера
int main(void)
{
uint8_t tmr1 = 0; // локальная переменная, для интервала софт-таймера
while(1);
{
if()...
}
}
ИзвЕните от слова - веник, ИзвИните от слова - вина.
-
veso74
- Поставщик валерьянки для Кота
- Сообщения: 1907
- Зарегистрирован: Сб май 05, 2012 20:24:52
- Откуда: KN34PC, Болгария
- Контактная информация:
Re: Таймеры/счётчики в AVR
[uquote="Мокренькая кисонька",url="/forum/viewtopic.php?p=4328358#p4328358"]... как если бы просто значение этой переменной прибавить к tmr1. Зачем тут эти выкрутасы с делением и умножением?[/uquote]
Вероятно "округление" до кратного 8.
Пример:
123 / 8 = 15,375;
15 * 8 = 120;
Я бы удалил последние 3 бита побитово:
Из примера:
123 = 0b01111011;
123 & 0b11111000 = 0b01111011 & 0b11111000 = 0b01111000 = 120;
Я почти уверен, что оптимизатор уже это сделал.
Вероятно "округление" до кратного 8.
Пример:
123 / 8 = 15,375;
15 * 8 = 120;
Я бы удалил последние 3 бита побитово:
Код: Выделить всё
a &= 0b11111000;123 = 0b01111011;
123 & 0b11111000 = 0b01111011 & 0b11111000 = 0b01111000 = 120;
Я почти уверен, что оптимизатор уже это сделал.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18556
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Таймеры/счётчики в AVR
я же вам писал: результат выражения по умолчанию int, т.е. со знаком.
uint8 - uint8 это не uint8, а int! а потом идет сравнение с 10, и это 10 тоже переделывается в int.
а когда вы пишите 10u, вы говорите компилятору: э, дарагой, тут знак нэ нада, давай, досвидания!
Добавлено after 3 minutes 27 seconds:
кстати, 123/8 в целых числах и так 15, а не 15,3.
Добавлено after 1 hour 24 seconds:
[uquote="Мокренькая кисонька",url="/forum/viewtopic.php?p=4328358#p4328358"]Зачем тут эти выкрутасы с делением и умножением?[/uquote]точного ответа у меня нет, но есть предположение.
я думаю, вы просто взяли за основу обучения код такого же, как вы, начинающего. т.е. того, кто "так работает - ну и ладно!". нельзя учиться на коде "от гуру" и на коде от "начинающего", надо учиться на коде опытного, но но не настолько, чтобы свободно применять конструкции типа но уже отказавшегося от конструкций типа
uint8 - uint8 это не uint8, а int! а потом идет сравнение с 10, и это 10 тоже переделывается в int.
а когда вы пишите 10u, вы говорите компилятору: э, дарагой, тут знак нэ нада, давай, досвидания!
Добавлено after 3 minutes 27 seconds:
кстати, 123/8 в целых числах и так 15, а не 15,3.
Добавлено after 1 hour 24 seconds:
[uquote="Мокренькая кисонька",url="/forum/viewtopic.php?p=4328358#p4328358"]Зачем тут эти выкрутасы с делением и умножением?[/uquote]точного ответа у меня нет, но есть предположение.
я думаю, вы просто взяли за основу обучения код такого же, как вы, начинающего. т.е. того, кто "так работает - ну и ладно!". нельзя учиться на коде "от гуру" и на коде от "начинающего", надо учиться на коде опытного, но но не настолько, чтобы свободно применять конструкции типа
Код: Выделить всё
v = {1,2,3,4}[i > 0 ? 17 ^ b * *с[x]++ : 136 / '\012'];Код: Выделить всё
if(x == 0) y = 'a';
else if(x == 1) y = 'b';
else if(x == 2) у = 'c';если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Таймеры/счётчики в AVR
[uquote="ARV",url="/forum/viewtopic.php?p=4328836#p4328836"]uint8 - uint8 это не uint8, а int![/uquote]Вот уж мне эта юношеская категоричность
Смотрим
Смотрим
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18556
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Таймеры/счётчики в AVR
[uquote="VladislavS",url="/forum/viewtopic.php?p=4328900#p4328900"][uquote="ARV",url="/forum/viewtopic.php?p=4328836#p4328836"]uint8 - uint8 это не uint8, а int![/uquote]Вот уж мне эта юношеская категоричность
Смотрим[/uquote]
опять плюсы в сишную тему приносите? integer promotions C
Смотрим[/uquote]
опять плюсы в сишную тему приносите? integer promotions C
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Таймеры/счётчики в AVR
Плюсы там только чтобы тип можно было посмотреть.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18556
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Таймеры/счётчики в AVR
[uquote="VladislavS",url="/forum/viewtopic.php?p=4329011#p4329011"]Плюсы там только чтобы тип можно было посмотреть.[/uquote]что вы предлагали мне увидеть по вашей ссылке? или integer promotions уже отменили?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Таймеры/счётчики в AVR
[uquote="ARV",url="/forum/viewtopic.php?p=4329116#p4329116"]что вы предлагали мне увидеть по вашей ссылке?[/uquote]Что ваше "uint8 - uint8 это не uint8, а int!" это ложное утверждение.
[uquote="ARV",url="/forum/viewtopic.php?p=4329116#p4329116"]или integer promotions уже отменили?[/uquote]Зачем вы употребляете термины, значение которых не знаете? Есть же стандарт. Читаем 6.3.1.1 и обнаруживаем, что может быть как int, так и unsigned int. Что примеры по моей ссылке и подтверждают.
[uquote="ARV",url="/forum/viewtopic.php?p=4329116#p4329116"]или integer promotions уже отменили?[/uquote]Зачем вы употребляете термины, значение которых не знаете? Есть же стандарт. Читаем 6.3.1.1 и обнаруживаем, что может быть как int, так и unsigned int. Что примеры по моей ссылке и подтверждают.


