Jump to content
-=FISHER=-

Измерение длительности импульса на AtTiny13

Recommended Posts

Всем здравствуйте!

Может глупый вопрос, но решил с вами посоветоваться всё же. Каким образом можно измерить длительность импульса средствами AtTiny13, поделитесь мыслями пожалуйста?

Режима захвата у таймера этого МК нет (брать МК по мощнее у которого есть такой режим - не вариант).

Мне приходит на ум следующий алгоритм: завести прерывание таймера по переполнению, чтобы оно срабатывало допустим 100000 раз в 1 секунду. И в нём отслеживать сколько прерываний подряд будет держаться высокий уровень на определенной ноге МК. При том что, особенная точность вычислений мне не нужна.


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

Как вариант. Чтоб точнее, по прерыванию ноги зап./ост. таймер, переполнение умножаешь на разрядность и прибавляешь последнее значение таймера. 

Edited by Yuriy.pv

Share this post


Link to post
Share on other sites
10 часов назад, Yuriy.pv сказал:

Как вариант.

А может тогда ещё проще сделать, что-то типа приходят прерывания - значит есть какой-то то сигнал, 120 мкс например. Ну а если не приходят совсем, значит 0 мкс. Логично же? У меня ведь задачи измерить какой именно продолжительности сигнал, мне нужно определить есть ли он там вообще или нету.

 

Только осталось определить временной интервал, в течении которого если нет прерываний, значит и нет сигнала.

Edited by -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

Вебинар «Новинки и решения Traco для промышленных и отраслевых приложений» (28.10.2021)

Компэл 28 октября приглашает всех желающих принять участие в вебинаре, где будет рассмотрена новая и перспективная продукция компании Traco. Мы подробно рассмотрим сильные стороны и преимущества продукции Traco, а также коснемся практических вопросов, связанных с измерением уровня шумов, промывкой изделий после пайки и отдельно разберем, как отличить поддельный ИП Traco от оригинала.
Подробнее

таймер запускаешь на максимальной скорости (без предделителя) и считаешь переполнения.

организуешь внешнее прерывание по INT0 и подаешь на него свои импульсы.

сначала это прерывание делаешь по фронту.

когда на фронте сработает прерывание, считываешь счетчик таймера и счетчик переполнений в ячейки памяти.

в обработчике изменяешь это прерывание на прерывание по спаду.

когда в следующий раз прерывание сработает по спаду импульса, опять считываешь счетчик таймера и счетчик переполнений уже в другие в ячейки памяти.

затем сбрасываешь счетчик переполнений и счетчик таймера для подготовки к следующему измерению.

и потом в обработчике изменяешь это прерывание на прерывание по фронту, чтобы потом опять измерять длительность следующего импульса.

потом находишь разницу запомненных результатов (результатов по спаду и результатов по фронту) и получаешь длительность импульса.


Мудрость приходит вместе с импотенцией...

Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.

Share this post


Link to post
Share on other sites

Особенности вывода ключей PROFET+2 12V из состояния блокировки

Интеллектуальные ключи PROFET производства Infineon блокируют электрическую цепь в случае превышения допустимых параметров. Как ускорить их возврат в нормальное состояние в ответственных применениях, где это критически важно?

Подробнее

Таймер в прерывании с нужной частотой инкрементирует  SysTime.

В главном цикле опрашивается нога. Если её состояние изменилось, поднимается флаг и записывается время произошедшего. 

Пои возвращении в исходное состояние, вычисляется итоговая длительность.

Полученная длительность события при отличии от нуля анализируется, если значение длительности попадает в доверительный диапазон, то запускается сигнал, если меньше - помеха, если больше - авария.

Учесть фронта.

Share this post


Link to post
Share on other sites

Беспроводные интерфейсы умного проSTранства - преимущества и ограничения

При автоматизации больших территорий используются протоколы беспроводной связи ZigBee, BLE/Bluetooth, LoRaWAN, Sigfox, Thread, проприетарные протоколы 433/868 МГц и NFC. Компания STMicroelectronics предлагает для них приемопередающие модули и системы на кристалле, специализированные контроллеры, ИС для создания RFID-меток, а также экосистему из аппаратных и программных продуктов для разработки, отладки и поддержания работоспособности. Разберем подробно решения STMicroelectronics для передачи данных по этим протоколам.
Подробнее

23 часа назад, dasZebra сказал:

Таймер в прерывании с нужной частотой инкрементирует  SysTime.

В главном цикле опрашивается нога. Если её состояние изменилось, поднимается флаг и записывается время произошедшего. 

 

А как в таком случае отследить момент когда продолжительность импульса до 0 упадёт?


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

Реле TE Connectivity – надежная коммутация, доступная со склада Компэл

Компэл предлагает огромный выбор реле от ведущего производителя электромеханических коммутирующих устройств – компании TE Connectivity. На складе представлен широкий ассортимент реле в миниатюрных и стандартных корпусах для сигнальных, высокочастотных и силовых применений.
Подробнее

2 часа назад, -=FISHER=- сказал:

А как в таком случае отследить момент когда продолжительность импульса до 0 упадёт?

Вопрос непонятен. 

В любом случае запускается два процесса (две задачи): один измеряет продолжительность импульса. Другой процесс (задача) смотрит намерянную продолжительность  и "выносит вердикт". В нем можно хоть самый длинный импульс отслеживать, хоть самый короткий, хоть последовательности в биты склеивать...  

Главное - правильно выбрать "частоту квантования", что бы у мк оставалось на это время.

Share this post


Link to post
Share on other sites
10 часов назад, dasZebra сказал:

Вопрос непонятен

Я просто вижу алгоритм так: завожу таймер на 1 мкс, затем в прерывании отслеживаю появление на ножке высокого уровнях, поднимаю флаг. Затем ждём низкого уровня - флаг опускаем и ждём опять появление высокого. А уже по количеству переполнения таймера с поднятым флагом - вычисляем длительность импульса.

 

Но что будет в случае, если высокий уровень так и не появится?

Edited by -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites
44 минуты назад, -=FISHER=- сказал:

А уже по количеству переполнения таймера с поднятым флагом

а что находится "внутри" таймера между переполнениями тебя не интересует?

46 минут назад, -=FISHER=- сказал:

завожу таймер на 1 мкс

а сколько МГц будет у тебя тактовая частота, чтобы завести таймер на 1мкс?


Мудрость приходит вместе с импотенцией...

Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.

Share this post


Link to post
Share on other sites
15 минут назад, Starichok сказал:

а сколько МГц будет у тебя тактовая частота, чтобы завести таймер на 1мкс

Согласен на attiny13 не получится на 1 мкс. Я проверял на Atmega8 на 16 МГц и счётный регистр заносил число 240.


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

а мой пост

24.09.2021 в 21:36, Starichok сказал:

таймер запускаешь на максимальной скорости (без предделителя) и считаешь переполнения.

организуешь внешнее прерывание по INT0 и подаешь на него свои импульсы.

сначала это прерывание делаешь по фронту.

когда на фронте сработает прерывание, считываешь счетчик таймера и счетчик переполнений в ячейки памяти.

в обработчике изменяешь это прерывание на прерывание по спаду.

когда в следующий раз прерывание сработает по спаду импульса, опять считываешь счетчик таймера и счетчик переполнений уже в другие в ячейки памяти.

затем сбрасываешь счетчик переполнений и счетчик таймера для подготовки к следующему измерению.

и потом в обработчике изменяешь это прерывание на прерывание по фронту, чтобы потом опять измерять длительность следующего импульса.

потом находишь разницу запомненных результатов (результатов по спаду и результатов по фронту) и получаешь длительность импульса.

прошел мимо тебя?


Мудрость приходит вместе с импотенцией...

Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.

Share this post


Link to post
Share on other sites
40 минут назад, Starichok сказал:

прошел мимо тебя?

У меня же два сигнала. А внешнее прерывание одно.

Я ещё раз напомню, что у меня нет задачи точно измерить время импульса. Мне всего лишь нужно отследить момент, когда время от примерно 112 мкс упадёт до 0 и потом момент когда восстановится до 112 мкс.

Грубо говоря, есть хоть какой-то цифровой сигнал на входе или там 0.

 

Edited by -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites
2 часа назад, -=FISHER=- сказал:

Я просто вижу алгоритм так: завожу таймер на 1 мкс, затем в прерывании отслеживаю появление на ножке высокого уровнях, поднимаю флаг. Затем ждём низкого уровня - флаг опускаем и ждём опять появление высокого. А уже по количеству переполнения таймера с поднятым флагом - вычисляем длительность импульса.

 

Но что будет в случае, если высокий уровень так и не появится?

в прерывании таймера только инкрементируется переменная системного времени SysTime. больше там ничего делать не нужно.

в главном цикле уже все "вычисления":

Изменилось состояние ноги с 0 на 1 пишем myPinHigh = SysTime

Изменилось состояние ноги с 1 до 0 пишем myPinLow= SysTime

HighLevelDuration =  myPinHigh - myPinLow

LowLevelDuration =  myPinLow - myPinHigh

Теперь имеется все что нужно, что бы "принять решение" и затем обнулить переменные для последующего:

если промежуток между импульсами больше 20 (LowLevelDuration > 20) то делается что нужно и все обнуляется

 

Если ног несколько, то все тоже только переменных больше.

 

NB

50 минут назад, -=FISHER=- сказал:

Грубо говоря, есть хоть какой-то цифровой сигнал на входе или там 0.

вобще то это не для мк задача, достаточно "LC-интегратора" с детектором  и усилителем.

мк нужен когда цифровые сигналы на входе нужно как то различить\сравнить\декодировать 

например если пауза между импульсами от 20 до 50 сидим ничего не делаем, от 51 до 65 - открываем кран, от 66 до 100 - открываем два крана, выше 101 включаем сирену. 

Share this post


Link to post
Share on other sites
13 минут назад, dasZebra сказал:

в прерывании таймера только инкрементируется переменная системного времени SysTime. больше там ничего делать не нужно.

в главном цикле уже все "вычисления":

Последний наверное вопрос: дребезг нужно как-то отслеживать или приемлемый для моей задачи результат можно достигнуть без фильтрации?


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites
12 минут назад, -=FISHER=- сказал:

дребезг нужно как-то отслеживать или приемлемый для моей задачи результат можно достигнуть без фильтрации?

Воот,  как раз дребезг и прочие помехи легко отфильтровать введя проверку на длительности. Если все подозрительно короткое, то идет мимо и присваиваний делать не надо.

Share this post


Link to post
Share on other sites
45 минут назад, dasZebra сказал:

SysTime

Простите за глупый вопрос, время же по кругу гоняем? Например в переменной uint16_t? 


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites
9 минут назад, -=FISHER=- сказал:

Простите за глупый вопрос, время же по кругу гоняем? Например в переменной uint16_t? 

 Да, но в беззнаковой. Очень часто беззнаковой переменной более чем достаточно для того, что бы все крутилось "автоматически".

Share this post


Link to post
Share on other sites

Но кстати "метод Старичка"  вполне вероятно может оказаться удобне, особенно для поиска "пауз". Ибо переключить регист для реагирования на фронты быстрее чем операции  сравнения. Единственное, что нужно "посмотреть", что бы два прерывания не вызывали гонку (race condition), ибо точностб повысится, но снизится помехоустойчивость....

Share this post


Link to post
Share on other sites
12 часов назад, -=FISHER=- сказал:

У меня же два сигнала.

а где было сказано про 2 сигнала? я этого в теме не видел.

и этого МК есть 6 внешних прерываний.


Мудрость приходит вместе с импотенцией...

Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.

Share this post


Link to post
Share on other sites
26.09.2021 в 13:20, dasZebra сказал:

Изменилось состояние ноги с 0 на 1 пишем myPinHigh = SysTime

Изменилось состояние ноги с 1 до 0 пишем myPinLow= SysTime

HighLevelDuration =  myPinHigh - myPinLow

LowLevelDuration =  myPinLow - myPinHigh

Только наверное вот так:

HighLevelDuration =  myPinLow - myPinHigh

LowLevelDuration =  myPinHigh -myPinLow

Иначе будут отрицательные значение.

 


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites
26.09.2021 в 14:17, dasZebra сказал:

Да, но в беззнаковой.

Взгляните пожалуйста, я хотя бы примерно правильно записал Ваш алгоритм в коде?

Скрытый текст

 


#include "main.h"

uint32_t SysTime, myPinHigh, myPinLow, HighLevelDuration, LowLevelDuration;

typedef enum //список возможных состояний
{
	LOW_LEVEL, //ОЖИДАНИЕ ВЫСОКОГО УРОВНЯ
	HIGH_LEVEL //ОЖИДАНИЕ НИЗКОГО УРОВНЯ
} state_t;

state_t state = LOW_LEVEL; //НАЧИНАЕМ С ОЖИДАНИЯ ВЫСОКОГО УРОВНЯ

void port_ini(void)
{
	PORTB=0x23; //0b00100011 - включаем подтягивающие резисторы внутри МК на PB0, PB1, PB5
	DDRB=0xC; //0b00001100 - настраиваем PB2 и PB3 на выход
}

void timer0_ini(void) //инициализация основного таймера
{
	TIMSK0|=(1<<TOIE0); //включаем прерывание по переполнению
	TCCR0B|=(1<<CS00); //предделитель 1
	TCNT0=160;
}

ISR (TIM0_OVF_vect) //прерывание по переполнению, вызывается 9600000/96 = 100000 раз в секунду или каждые 10 мкс
{
	TCNT0=160;
	SysTime++;
}

int main(void)
{
	port_ini();
	timer0_ini();
	sei();
		
    while (1) 
   {	
	switch(state) //АВТОМАТ СОСТОЯНИЙ
	{
		case LOW_LEVEL: //НА НОЖКЕ НИЗКИЙ УРОВЕНЬ, ЖДЁМ ВЫСОГО УРОВНЯ
		{
			if(PINB&LEFT_IN) //ПОЯВИЛСЯ ВЫСОКИЙ УРОВЕНЬ
            {
              	myPinHigh = SysTime; //ЗАПОМИНАЕМ ТЕКУЩЕЕ "ВРЕМЯ"
              	state = HIGH_LEVEL; //ПЕРЕКЛЮЧАЕМСЯ В РЕЖИМ ОЖИДАНИЯ ВЫСОКОГО УРОВНЯ
            }
			break;
		}
		
		case HIGH_LEVEL: //НА НОЖКЕ ВЫСОКИЙ УРОВЕНЬ, ЖДЁМ НИЗКОГО УРОВНЯ
		{
			if(!(PINB&LEFT_IN)) //ПОЯВИЛСЯ НИЗКИЙ УРОВЕНЬ
			{
				myPinLow = SysTime; //ЗАПОМИНАЕМ ТЕКУЩЕЕ "ВРЕМЯ"
				HighLevelDuration = myPinLow - myPinHigh; //ВЫЧИСЛЯЕМ ПРОДОЛЖИТЕЛЬНОСТЬ ВЫСОКОГО УРОВНЯ
				if(HighLevelDuration>112){/*ДЕЛАЕМ ЧТО-ТО*/} //ЕСЛИ ДЛИНА ИМПУЛЬСА БОЛЬШЕ 112
				state = LOW_LEVEL; //ПЕРЕКЛЮЧАЕМСЯ В РЕЖИМ ОЖИДАНИЯ НИЗКОГО УРОВНЯ
			}
			break;
		}
		break;
	}	
   }
}

 

 

Edited by -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

Ещё, если не сложно, объясните пожалуйста, как ардуиновская функция pulsein может отслеживать появление высокого уровня на ножке, без внешней подтяжки этой ножки к земле?

Ведь если я повешу кнопку на любую ножку и буду замыкать её на плюс, то без внешней подтяжки к земле я не смогу отследить на ней высокий уровень типа:

if(PINB&(1<< 0b00000001)){какой-то код}

Извините, если туплю, не кидайте камнями.


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites
7 часов назад, -=FISHER=- сказал:

Взгляните пожалуйста, я хотя бы примерно правильно записал Ваш алгоритм в коде?

Мне кажется Вы отлично все уловили.

Share this post


Link to post
Share on other sites
1 час назад, dasZebra сказал:

все уловили

Не могу понять, почему тогда не работает код :( может быть всё таки я упустил какой-то очень важный момент?...


Мы все учились по-немногу, чему-нибудь и как-нибудь...

Share this post


Link to post
Share on other sites

SysTime должно быть описано как volatile или нет?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • А я всёже добился своего,опять слетал правый канал,разобрал и перемычки на левый и правый каналы поставил,всё-равно не слушаю наушники,теперь красота.В сети читал многие не нашли причину,почему звук пропадает и повыбрасывали Свен -мс80. А  вообще Свен классная система,если доработать напильником. Вот так выглядит после доработки,для кухни хорошая система получилась,в громкоговорителях 70-х,1ГД-40 стоят между прочим,классный звук! 
    • Выздоравливайте, не забывайте лечить последствия и побочки, многие отмечают что они гораздо зловреднее чем сам ковид. Сам ещё как началось прошлой весной купил на Али пару оксиметров. Вот недавно только пригодились, семья большая + родственники. Редкий случай, когда покупка на Али реально полезная оказалась. Понятно что они +- километр меряют, но чисто как показометр, что имеет место быть тенденция ухудшения, вполне приемлемы. Да, парацетамол у меня в начале тоже сбивал температуру, а как стала подниматься выше 39 перестало сбивать, сильная потливость по ночам была. Прям просыпался от того, что весь и все вокруг мокрое. Потом сбивал уже анальгином температуру + когда на КТ поставили 15% и пневмония,  другой антибиотик стал пить (клацид, если кому интересно) и буквально в 3 дня уже почти здоров был. Ещё дней 10 кашель отходил. Антикоагулянт (эликвис) тоже прописывали на месяц, но я одну пачку на 10 дней пропил и забил. СтОит прилично, а поражение не большое было, ИМХО - перестраховываются врачи и всем по шаблону прописывают одно и тоже.  
    • Будем надеяться, что это единственная ошибка.  
    • Да, надо было написать pause, или хотя бы за неимением места  paus,  но я эту ошибку не заметил. Вот поэтому и нужна проверка программы другими радиолюбителями. 
    • Нет, нужно сначала попытаться решить проблему самостоятельно, и только потом спрашивать. Из чего складывается вывод АЦП на экран? Из измерения, усреднения по 40 точкам и преобразования в строку. В некоторых кривых библиотеках добавляется еще перевод в дробные числа, который, естественно, ухудшает точность и сильно ухудшает скорость. Вот по очереди эти шаги и проверяете. Правильно ли идет оцифровка одного измерения? Правильно ли срабатывает выбор канала (рекомендую проверить не только 0 и 1 каналы, но и остальные. Даже не только проверить, но и исправить чтобы работало)? Правильно ли идет усреднение? Правильно ли идет вывод? Я даже подскажу: проблема в функции readADC(). Ну и в Lcd_printf() - из-за дурацкой идеи преобразовывать целое число в дробное. Подобные вещи всегда считаются в фиксированной точке! Если бы ее заметили вы, сами бы и исправили. А то, что на нее случайно наткнулись, бездумно меняя константы - другой вопрос. Потом решить усреднять не по 40 точкам, а по 256 - "а-а-а, у вас ошибка". Не угадали, процессор 8-битный. Снова не угадали. Потому что деление на степень двойки не требует деления. А сформулировать по-человечески сложно? Количество шагов оцифровки в AVR фиксированное, 12.5 - эта цифра есть в даташите. Выходное значение АЦП физически не может принимать значения за пределами 0-1023. Либо 0-65536 при выравнивании влево. Э нет, это ведь у вас возникло непонимание. Все остальные прекрасно знают откуда и какие ограничения берутся. Вот разберитесь и изложите свое понимание здесь - чтобы мы могли проверить. А лучше на uin16_t из <inttypes.h>
    • Ну, раз нет других вариантов, будем полагаться на мою проверку программы. Итак:         МОДУЛЬ BLUETOOTH В РАДИОПРИЁМНИКЕ С ДИСПЛЕЕМ WH1602 Схема и программа приёмника являются дальнейшим развитием предыдущей программы. Электрическая схема радиоприёмника содержит цепи управления Bluetooth- модулем типа МН-М18, который имеет небольшие размеры. Модуль рассчитан на управление при помощи кнопок, роль которых в данной схеме выполняют ключи на транзисторах VT6…VT8. Можно применить любые маломощные n-p-n транзисторы. Питание модуля коммутируется при помощи ключа на полевом транзисторе VT5. Управлять модулем можно как от кнопок, так и при помощи пульта ДУ, который может быть любым, лишь бы он работал по протоколу NEC.    FM_M8A_1602_RDS_IR_BT.pdf FM_M8A_1602_RDS_IR_BT.hex

  • Карандаш-флюс 951 RMA. Объем 10мл

×
×
  • Create New...