Jump to content

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


-=FISHER=-
 Share

Recommended Posts

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

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

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

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

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

Link to comment
Share on other sites

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

Edited by Yuriy.pv
Link to comment
Share on other sites

10 часов назад, Yuriy.pv сказал:

Как вариант.

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

 

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

Edited by -=FISHER=-

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

Link to comment
Share on other sites

Вебинар «Особенности применения литиевых батареек Fanso (EVE) в популярных решениях»(30.11.2021)

Приглашаем 30 ноября всех желающих посетить вебинар о литиевых источниках тока Fanso (EVE). Вы узнаете об особенностях использования литиевых источников питания и о том, как на них влияют режим работы и условия эксплуатации. Мы расскажем, какие параметры важно учитывать при выборе литиевого ХИТ, рассмотрим «подводные камни», с которыми можно столкнуться при неправильном выборе, разберем, как правильно проводить тесты, чтобы убедиться в надежности конечного решения. Вы сможете задать вопросы представителям производителя, которые будут участвовать в вебинаре.

Подробнее

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

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

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

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

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

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

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

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

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

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

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

Link to comment
Share on other sites

Вебинар «Антенны Molex: выбор и применение» (25.11.2021)

Приглашаем всех желающих 25/11/2021 г. принять участие в вебинаре, посвященном антеннам Molex. Готовые к использованию антенны Molex являются компактными, высокопроизводительными и доступны в различных форм-факторах для всех стандартных антенных протоколов и частот. На вебинаре будет проведен обзор готовых решений и перспектив развития продуктовой линейки. Разработчики смогут получить рекомендации по выбору антенны, работе с документацией и поддержкой, заказу образцов.

Подробнее

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

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

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

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

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

Link to comment
Share on other sites

Вебинар «Новые тенденции сетевых технологий: Ethernet по одной витой паре» (09.12.2021)

Приглашаем всех желающих посетить вебинар, посвященный технологии Ethernet и её новому стандарту 10BASE-T1S/L. Стандарт 802.3cg описывает передачу данных на скорости до 10 Мбит в секунду по одной витой паре. На вебинаре будут рассмотрены и другие новшества, которые недавно вошли в семейство технологий Ethernet: SyncE, PTP, TSN. Не останется в стороне и высокоскоростной 25G+ Ethernet от Microchip.

Подробнее

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

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

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

 

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

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

Link to comment
Share on other sites

Бюджетный и надежный источник питания для маломощного устройства? – Mornsun!

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

Подробнее

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

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

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

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

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

Link to comment
Share on other sites

10 часов назад, dasZebra сказал:

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

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

 

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

Edited by -=FISHER=-

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

Link to comment
Share on other sites

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

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

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

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

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

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

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

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

Link to comment
Share on other sites

15 минут назад, Starichok сказал:

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

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

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

Link to comment
Share on other sites

а мой пост

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

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

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

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

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

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

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

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

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

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

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

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

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

Link to comment
Share on other sites

40 минут назад, Starichok сказал:

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

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

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

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

 

Edited by -=FISHER=-

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

Link to comment
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 включаем сирену. 

Link to comment
Share on other sites

13 минут назад, dasZebra сказал:

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

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

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

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

Link to comment
Share on other sites

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

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

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

Link to comment
Share on other sites

45 минут назад, dasZebra сказал:

SysTime

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

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

Link to comment
Share on other sites

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

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

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

12 часов назад, -=FISHER=- сказал:

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

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

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

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

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

Link to comment
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

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

 

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

Link to comment
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=-

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

Link to comment
Share on other sites

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

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

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

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

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

Link to comment
Share on other sites

7 часов назад, -=FISHER=- сказал:

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

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

Link to comment
Share on other sites

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

все уловили

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

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

Link to comment
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...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...