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

Обсуждаем контроллеры компании Atmel.
Ответить
Модератор
Аватара пользователя
Сообщения: 19077
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

да, два таймера имеют один общий предделитель.
но никто не мешает брать для каждого таймера свои (разные) коэффициенты деления.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Реклама
akl
Друг Кота
Сообщения: 4462
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

[uquote="Эйлер Леонард",url="/forum/viewtopic.php?p=3767986#p3767986"]Прошу прощенья. Речь пока идет об одном конкретном МК - грызу Attiny85. Конечно каждый МК имеет свои особенности.[/uquote]У этого камня таймеры имеют свои предделители, причем крепко разные.
Вложения
ATtiny85_T0.PNG
(33.73 КБ) 438 скачиваний
ATtiny85_T1.PNG
(36.26 КБ) 414 скачиваний
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 104
Зарегистрирован: Пн ноя 04, 2019 09:58:29
Откуда: г. Нижний Тагил Свердл. обл.

Сообщение Эйлер Леонард »

Это как раз я и выяснил! Да вот только компарировать Т1 никак не заставлю. Чудной какой то Т1. Использовал среду разработки CodeVisionAVR. Там галочек наставил каких надо - и всё показало в коде. Хотя я не любю генераторщиков кода - много лишнего, однако весьма полезны для начинающих. (...блокнот и ANT :))?! ). В своем проекте мне достаточно двух таймеров. Один для получения данных. Второй для динамической индикации. Для получения данных оказывается достаточно использовать сторожевой таймер - на нем пока я и остановился. Хотя с собаками я как то не очень. Но тут надо отметить - подружились сразу. :))
Спойлер

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

void WDT_init( void ){
// --- Attiny85---
// Watchdog timeout action: Interrupt
WDTCR|= (1<<WDCE)|(1<<WDE);
WDTCR = (1<<WDIF)|(1<<WDIE)|(0<<WDE)|(0<<WDCE)|(0<<WDP3)|(1<<WDP2)|(1<<WDP1)|(0<<WDP0);
/*
Watchdog Timer Prescale Select
WDP3 WDP2 WDP1 WDP0
0 0 0 0 2K       (2048) cycles 16 ms
0 0 0 1 4K       (4096) cycles 32 ms
0 0 1 0 8K       (8192) cycles 64 ms
0 0 1 1 16K     (16384) cycles 0.125 s
0 1 0 0 32K     (32764) cycles 0.25 s
0 1 0 1 64K     (65536) cycles 0.5 s
0 1 1 0 128K   (131072) cycles 1.0 s
0 1 1 1 256K   (262144) cycles 2.0 s
1 0 0 0 512K   (524288) cycles 4.0 s
1 0 0 1 1024K (1048576) cycles 8.0 s
*/
};
И обязательно в main.cpp
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK = (1<<OCIE1A) | (1<<OCIE1B) | (1<<OCIE0A) | (1<<OCIE0B) | (0<<TOIE1) | (0<<TOIE0);
----
Что я и думаю - а не много ли здесь лишнего. CodeVisionAVR нагенерировал всякого, оно вроде бы и работает - разбирайся потом надо-не надо это всё. Это как препод у нас, написал - объясни. Не смог - иди учи, не сдал. :))
Последний раз редактировалось Эйлер Леонард Сб янв 11, 2020 09:38:30, всего редактировалось 1 раз.
Модератор
Аватара пользователя
Сообщения: 19077
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

что-то я сомневаюсь, что тебе всего для двух дел нужно разрешать 6 (шесть) прерываний...
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Реклама
Эиком - электронные компоненты и радиодетали
c2n
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1193
Зарегистрирован: Ср июл 25, 2012 21:40:09
Откуда: Самара

Сообщение c2n »

>>>использовать сторожевой таймер

Не очень то хорошая идея.
Ватчдог по идее должен перезагружать устройство, т.к. специально тактируется от других источников, в отличие от срандартных таймеров.
Контактная информация:
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 104
Зарегистрирован: Пн ноя 04, 2019 09:58:29
Откуда: г. Нижний Тагил Свердл. обл.

Сообщение Эйлер Леонард »

Действительно. Watchdog Timer - тактируется от своего собственного источника. И задача у него несколько иная. Это аппаратно-реализованная схема контроля над зависанием системы. Но ничего не стоит и не мешает использовать его (в моем случае) просто как счетчик, установив биты в WDTCR соответствующим образом. Тем более что по условиям своей задачи мне необходимо получать с внешнего прерывания некое усредненное значение за определенный период времени. Среднее арифметическое по 4-5 значениям. В этом случае WDT установлен с прескалером на 0.25 сек. Взяв четыре значения, которые могут быть разными, я их складываю и получаю среднее за 1 сек. (бензин в баке плещется)

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

ISR(WDT_vect){// j = 0,1,2,3
j=(j>2)?(j=0):(j+1);
average = average+impulses;
impulses=0;
if(j==3){
num = SplitNumber(average);
SHIFTREG_OutputValue( &reg, num.g, 5 );
average=0;
}
};
Полученое числовое значение за 1 сек. расшплинтовываю на разряды и отправляю на индикатор. Хотя всё это можно реализовать на Timer0/Timer1 (Проверял в протеусе - фурыкает :)) )
Реклама
Модератор
Аватара пользователя
Сообщения: 19077
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

у"собаки" генератор не калиброванный.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Встал на лапы
Аватара пользователя
Сообщения: 104
Зарегистрирован: Пн ноя 04, 2019 09:58:29
Откуда: г. Нижний Тагил Свердл. обл.

Сообщение Эйлер Леонард »

Время устанавливается в секундах, через которое он(таймер) вздрагивает.
Watchdog_Timer_Attiny85.png
Watchdog_Timer_Attiny85
(77.24 КБ) 372 скачивания
Это не хвост, это антенна
Сообщения: 1492
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

У тини85 два таймера. На хера вам сторожевой? Озвучьте тз и соображения, по которым вы используете сторожевой таймер для временных интервалов.
Контактная информация:
Встал на лапы
Аватара пользователя
Сообщения: 104
Зарегистрирован: Пн ноя 04, 2019 09:58:29
Откуда: г. Нижний Тагил Свердл. обл.

Сообщение Эйлер Леонард »

Забегая наперед, скажу - для тарировки/калибровки при подключении внешнего генератора. Задал напр. 0,25/0,5/1 сек. В T0,T1 там тики по формулам считать надо - а тут всё готово. Хотя это и не сложно - формулы простые. Мне необходимо получить сначала зависимость частоты от количества бензина в баке. Заливаеш в бак по пол литра или 0,8 - записал на листочек частоту. И так до полного бака. Эту таблицу и запишу потом в коде в какой нибудь двухмерный массив, структуру. Фрагмент кода С++
Спойлер

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

struct FreqRange {
	 uint16_t freq; 
	 uint16_t ltrs; // литры
	 uint16_t ltrsInterpol;
 } freqRange[] = { 
	{20005,   0}, //  0   
	{21338,   8}, //  1   
	{22671,  16}, //  2 
	{24004,  24}, //  3 
	{25337,  32}, //  4 
	{26670,  40}, //  5  
	{28003,  48}, //  6  
	{29336,  56}, //  7  
	{30669,  64}, //  8  
	{32002,  72}, //  9 
	{33335,  80}, // 10  
	{34668,  88}, // 11  
	{36001,  96}, // 12  
	{37334, 104}, // 13  
	{38667, 112}, // 14  
	{40000, 120}  // 15  
	 }, ddd;
	 
FreqRange Interpolation( uint16_t f ){
FreqRange FR;
uint8_t level;
uint16_t temp_1, temp_2;

for( level=0; level<=15; ++level ){
if( f > 0                     && f<=       freqRange[1].freq ){ break; }// level = 0;	
if( f > freqRange[level].freq && f<= freqRange[level+1].freq ){ break; }// level = 1...14;
if( f > freqRange[level].freq && f<= 41000                   ){ break; }// level = 15;	
}

temp_1 = (freqRange[level+1].ltrs-freqRange[level].ltrs);
temp_2 = (freqRange[level+1].freq-freqRange[level].freq);
 
FR.ltrsInterpol = round(
(float)f/(float)(temp_2/temp_1)-(float)((freqRange[level].freq/temp_2)*temp_1-freqRange[level].ltrs)
);
return FR;
}
Линейную интерполяцию реализовал по промежуточным значениям. (Функция добавлена к структуре). "Уплотнение таблиц" - для точности. Значения пока произвольные. Отдельный блок кода по тарировке с записью в EEPROM пока не планирую т.к. ещё не изучил это дело. Ув. Demiurg, - на счет использования сторожевого таймера, пусть будет в порядке эксперимента. Как говорил один старый фортранщик - программист должен быть извращенцем и экспериментатором. :)))
----
P.S. :)
Последний раз редактировалось Эйлер Леонард Вт янв 21, 2020 15:43:05, всего редактировалось 1 раз.
Это не хвост, это антенна
Сообщения: 1492
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

Ага, разбирать двигатель через выхлопную трубу и секасом заниматься в гамаке и стоя...
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 42
Зарегистрирован: Чт июл 23, 2020 20:59:01
Откуда: СевКавТВ

Сообщение ChipCard »

Подскажите, в чём может быть проблема? После переполнения таймер 0 и установки флага TOV0 микроконтроллер не уходит по вектору прерывания. счётчик сбрасывается и начинает отсчёт дальше, флаг TOV0 остается установленным (((

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

#include <avr/io.h>
//#include <util/delay.h>
#include <avr/interrupt.h>



ISR (TIMER0_OVF_vect)
{
	asm ("nop");
}

int main(void)
  
{    
	
	TCCR0 |= (1<<1); TCCR0 &= ~ ((1<<0)|(1<<2));// делитель 8
	//TCNT0 = 0b11111100; 
	TIMSK |= (1<<0);
	//SREG |= (1<<7);
	sei ();
	
	
    while(1)
    {
        asm ("nop");
		
		
    }
}
Изображение
Это не хвост, это антенна
Сообщения: 1492
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

Я иногда думаю, что сначала всех принудительно заставлять начинать с ассемблера. Прогонять все программы в симуляторе. В дизассемблера. И только потом изучать си.
Но самое главное, пошаговое изучение ядра AVR. В книжках. А не на форумах.
Контактная информация:
Самсусамыч

Сообщение Самсусамыч »

[uquote="ChipCard",url="/forum/viewtopic.php?p=3871319#p3871319"]Подскажите, в чём может быть проблема?[/uquote]
Чтобы наступало прерывание по переполнению счётчика, его необходимо разрешить. Для этого устанавливается соответствующий бит в регистре TIMSK, а так же разрешаем все прерывания установкой бит I = 1 в регистре SREG. После установки данных битов прерывание начнёт выполнятся.
Открыл глаза
Аватара пользователя
Сообщения: 42
Зарегистрирован: Чт июл 23, 2020 20:59:01
Откуда: СевКавТВ

Сообщение ChipCard »

[uquote="Самсусамыч",url="/forum/viewtopic.php?p=3871344#p3871344"]Для этого устанавливается соответствующий бит в регистре TIMSK, а так же разрешаем все прерывания установкой бит I = 1 в регистре SREG. После установки данных битов прерывание начнёт выполнятся.[/uquote]
Ткните, пожалуйста, меня носом, где я НЕ установил соответствующие биты в правильное значение? Буду благодарен.
SREG я даже пытался (как это видно из черновика ) устанавливать разными способами. И нулевой бит TIMSK в коде тоже установлен. :dont_know:
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

ChipCard, оптимизация какого уровня? Поставьте что-то более значимое, чем nop в ISR, может оптимизатор выкидывает? Ну и прерывания лучше включать ДО включения таймера. А еще лучше не пользоваться магическими числами и не писать нули туда, где они и так были.

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

...
volatile uint16_t cnt = 0;

ISR (TIMER0_OVF_vect)
{
   cnt++;
}

int main(void)
{   
   sei ();
   TIMSK = (1<<TOIE0);
   TCCR0 = (1<<CS01); // делитель 8

    while(1);
}
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

NStorm писал(а):может оптимизатор выкидывает?
вполне может быть. ибо ассемблерную вставку nop-a надо делать так:

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

volatile asm ("nop");
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Или так:

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

#include <avr/cpufunc.h>
...
_NOP();
Что в общем-то равносильно пока.
Но я бы вопрошающему всё-равно посоветовал бы счетчика переменную добавить, чтобы наглядно видеть. Бряка там внутри ISR нет, может отладчик симулятора криво что кажет, может он что не так делает, не шагает внутрь просто.
Самсусамыч

Сообщение Самсусамыч »

[uquote="ChipCard",url="/forum/viewtopic.php?p=3871355#p3871355"]Ткните, пожалуйста, меня носом, где я НЕ установил соответствующие биты в правильное значение?[/uquote]
Я не пишу на Си, потому мне Ваш код не понятен. Я Вам пояснил как это работает не зависимо от языков программирования. Помигайте светиком с помощью таймера… обычно на первом этапе так делает большинство… так будет проще и понятней. Какой МК используете?
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Самсусамыч, да он же в симулятор смотрит, какой там светик. Я уже написал что сделать, так будет работать.
Ответить

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