Страница 53 из 72
Re: Таймеры/счётчики в AVR
Добавлено: Пн янв 06, 2020 09:35:16
Starichok51
да, два таймера имеют один общий предделитель.
но никто не мешает брать для каждого таймера свои (разные) коэффициенты деления.
Re: Таймеры/счётчики в AVR
Добавлено: Пн янв 06, 2020 09:56:17
akl
[uquote="Эйлер Леонард",url="/forum/viewtopic.php?p=3767986#p3767986"]Прошу прощенья. Речь пока идет об одном конкретном МК - грызу Attiny85. Конечно каждый МК имеет свои особенности.[/uquote]У этого камня таймеры имеют свои предделители, причем крепко разные.
Re: Таймеры/счётчики в AVR
Добавлено: Пт янв 10, 2020 17:36:46
Эйлер Леонард
Это как раз я и выяснил! Да вот только компарировать Т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 нагенерировал всякого, оно вроде бы и работает - разбирайся потом надо-не надо это всё. Это как препод у нас, написал - объясни. Не смог - иди учи, не сдал.

Re: Таймеры/счётчики в AVR
Добавлено: Сб янв 11, 2020 08:13:50
Starichok51
что-то я сомневаюсь, что тебе всего для двух дел нужно разрешать 6 (шесть) прерываний...
Re: Таймеры/счётчики в AVR
Добавлено: Сб янв 18, 2020 10:23:51
c2n
>>>использовать сторожевой таймер
Не очень то хорошая идея.
Ватчдог по идее должен перезагружать устройство, т.к. специально тактируется от других источников, в отличие от срандартных таймеров.
Re: Таймеры/счётчики в AVR
Добавлено: Вс янв 19, 2020 08:27:06
Эйлер Леонард
Действительно.
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( ®, num.g, 5 );
average=0;
}
};
Полученое числовое значение за 1 сек. расшплинтовываю на разряды и отправляю на индикатор. Хотя всё это можно реализовать на Timer0/Timer1 (Проверял в протеусе - фурыкает

)
Re: Таймеры/счётчики в AVR
Добавлено: Вс янв 19, 2020 09:44:59
Starichok51
у"собаки" генератор не калиброванный.
Re: Таймеры/счётчики в AVR
Добавлено: Вс янв 19, 2020 14:16:40
Эйлер Леонард
Время устанавливается в секундах, через которое он(таймер) вздрагивает.
Re: Таймеры/счётчики в AVR
Добавлено: Вс янв 19, 2020 22:35:33
Demiurg
У тини85 два таймера. На хера вам сторожевой? Озвучьте тз и соображения, по которым вы используете сторожевой таймер для временных интервалов.
Re: Таймеры/счётчики в AVR
Добавлено: Пн янв 20, 2020 20:18:15
Эйлер Леонард
Забегая наперед, скажу - для тарировки/калибровки при подключении внешнего генератора. Задал напр. 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.

Re: Таймеры/счётчики в AVR
Добавлено: Пн янв 20, 2020 21:32:25
Demiurg
Ага, разбирать двигатель через выхлопную трубу и секасом заниматься в гамаке и стоя...
Re: Таймеры/счётчики в AVR
Добавлено: Сб июл 25, 2020 23:33:34
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");
}
}

Re: Таймеры/счётчики в AVR
Добавлено: Вс июл 26, 2020 00:31:28
Demiurg
Я иногда думаю, что сначала всех принудительно заставлять начинать с ассемблера. Прогонять все программы в симуляторе. В дизассемблера. И только потом изучать си.
Но самое главное, пошаговое изучение ядра AVR. В книжках. А не на форумах.
Re: Таймеры/счётчики в AVR
Добавлено: Вс июл 26, 2020 07:31:57
Самсусамыч
[uquote="ChipCard",url="/forum/viewtopic.php?p=3871319#p3871319"]Подскажите, в чём может быть проблема?[/uquote]
Чтобы наступало прерывание по переполнению счётчика, его необходимо разрешить. Для этого устанавливается соответствующий бит в регистре TIMSK, а так же разрешаем все прерывания установкой бит I = 1 в регистре SREG. После установки данных битов прерывание начнёт выполнятся.
Re: Таймеры/счётчики в AVR
Добавлено: Вс июл 26, 2020 08:46:21
ChipCard
[uquote="Самсусамыч",url="/forum/viewtopic.php?p=3871344#p3871344"]Для этого устанавливается соответствующий бит в регистре
TIMSK, а так же разрешаем все прерывания установкой бит
I = 1 в регистре
SREG. После установки данных битов прерывание начнёт выполнятся.[/uquote]
Ткните, пожалуйста, меня носом, где я
НЕ установил соответствующие биты в правильное значение? Буду благодарен.
SREG я даже пытался (как это видно из черновика ) устанавливать разными способами. И нулевой бит
TIMSK в коде тоже установлен.

Re: Таймеры/счётчики в AVR
Добавлено: Вс июл 26, 2020 09:53:15
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);
}
Re: Таймеры/счётчики в AVR
Добавлено: Вс июл 26, 2020 10:14:04
ARV
NStorm писал(а):может оптимизатор выкидывает?
вполне может быть. ибо ассемблерную вставку nop-a надо делать так:
Re: Таймеры/счётчики в AVR
Добавлено: Вс июл 26, 2020 11:02:54
NStorm
Или так:
Что в общем-то равносильно пока.
Но я бы вопрошающему всё-равно посоветовал бы счетчика переменную добавить, чтобы наглядно видеть. Бряка там внутри ISR нет, может отладчик симулятора криво что кажет, может он что не так делает, не шагает внутрь просто.
Re: Таймеры/счётчики в AVR
Добавлено: Вс июл 26, 2020 12:03:53
Самсусамыч
[uquote="ChipCard",url="/forum/viewtopic.php?p=3871355#p3871355"]Ткните, пожалуйста, меня носом, где я НЕ установил соответствующие биты в правильное значение?[/uquote]
Я не пишу на Си, потому мне Ваш код не понятен. Я Вам пояснил как это работает не зависимо от языков программирования. Помигайте светиком с помощью таймера… обычно на первом этапе так делает большинство… так будет проще и понятней. Какой МК используете?
Re: Таймеры/счётчики в AVR
Добавлено: Вс июл 26, 2020 12:28:43
NStorm
Самсусамыч, да он же в симулятор смотрит, какой там светик. Я уже написал что сделать, так будет работать.