Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Счетчик на Mega128
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Ojo
Счетчик на Mega128

Пожалуйста, подскажите, как сделать следующую вещь? Есть линия для анализа. На ней могут быть логический ноль (почти всегда) или логическая 1 (редко, небольшими импульсами различной длины от 1 мсек до 10 мсек). Задача состоит в том, чтобы подсчитывать какова длительность всех импульсов логической 1 за текущую прошедшую секунду. Частота Меги 16MHz. Точность измерений:10% устроит.

Самое очевидное решение. Повесить исследуемую линию на любую ножку прерывания Мегию. При возникновении на ней логической 1 (и как следствия прерывания) засекать время (организовав внутренний таймер), При возникновении логического 0 на ней подсчитывать время импульса и прибавлять к переменной ВСЕГО.

Данное решение не подходит. Т.к. в силу специфики прошивки устройства Мега может запретить прерывания на длительное время (до 10 мсек).

Наверняка есть возможность решить эту задачу через таймеры/счетчки.
MrYuran
вешаете свой сигнал на вход захвата Timer1 (по-моему), по нужному фронту значение таймера защёлкнется в регистре захвата, а потом в прерывании можно его проанализировать и настроить таймер на захват другого фронта. Если есть опасность, что прерывание не возникнет (будет запрещено), то тогда надо завести сигнал на 2 входа захвата (не помню кстати, сколько их в меге), и один настроить на передний фронт, а другой - на задний. Разница значений в защёлках и будет равна длительности импульса (в тактах таймера)
Палыч
На ум приходит такая вещь:

1. Необходим генератор импульсов (на таймере МК с выходом наружу или внешний)
2. Логическая единица замеряемого сигнала через вентиль пропускается на счетный вход таймера (счетчика) импульсы генератора из п.1.
3. Сам сигнал заведен также на ногу внешнего прерывания, которое (прерывание) настроено на срабатывание по перепаду из 1 в 0.
4. При возникновении внешнего прерывания считываем значение счетного регистра счетчика из п.2, число в нем - пророрционально длительности замеряемого сигнала. После считывания (и вначале программы) - не забыть бы обнулить счетчик.



Цитата(MrYuran @ Jun 26 2008, 19:27) *
Разница значений в защёлках и будет равна длительности импульса (в тактах таймера)
При таком подходе возникает задача синхронизации значений счетных регистров двух таймеров. Правда, большая точность автору вопроса не нужна, поэтому, наверное, это - тоже решение.
Ojo
Спасибо за ответы. Жалко что у меги нет возможности в таймере по одному фронту записать значение счетчика в один регист, а по второму во второй. Т.к. оба предложенных решения требуют задействования 2-х ножек Мега.
zhevak
Это только идея:

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

По истечении секунды, с помощью меги-ной АЦП оценивается уровениь напряжения на конденсаторе. Затем конденсатор разряжается (с помощью внешнего полевого транзистора, например), и процесс накопления начинается заново.

Такой подход позволит меге безболезненно отвлекаться на любые прерывания и в любом количестве на протяжение всего процесса накопления. Минус: потребуется несколько дополнительных элементов в схеме.
GDI
А может чем мудрить лучше переписать программу так чтобы она не запрещала прерывания на 10мсек? Или рассмотреть возможность разрешения вложенных прерываний, можно разрешить , например, вложенные только от таймера.
Ojo
Цитата(zhevak @ Jun 26 2008, 22:23) *
Это только идея:

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

По истечении секунды, с помощью меги-ной АЦП оценивается уровениь напряжения на конденсаторе. Затем конденсатор разряжается (с помощью внешнего полевого транзистора, например), и процесс накопления начинается заново.

Такой подход позволит меге безболезненно отвлекаться на любые прерывания и в любом количестве на протяжение всего процесса накопления. Минус: потребуется несколько дополнительных элементов в схеме.


Красиво и работать будет! Но для наших целей слишком мудрено. Думаю, данный метод незаменим, если скачек на измеряемой линии превышает или сопоставим со временем одного такта процессора. Все равно, спасибо.
Maik-vs
Паноптикум... Мега 128 на 16 мегагерцах, внешний вентиль и ещё конденсатор!... lol.gif

Нужен один таймер, четыре байта памяти и одна нога порта.
Таймер даёт прерывания через, например 1 миллисекунду. Процедура его прерывания смотрит на порт и наращивает счётчик длительности (2-байтовый), если единица. Потом наращивает счётчик времени. Если счётчик времени равен 1000, то переписывает счётчик длительности в другое место памяти, поднимает флаг "измерено" и сбрасывает счётчики времени и длительности. ВСЁ. Точность 0.1%, всё синхронно, где-то в основном цикле - программа обработки счётчика длительности по флагу. Блин, на ассемблере будет короче всё это написать.

Цитата(Ojo @ Jun 26 2008, 20:56) *
Спасибо за ответы. Жалко что у меги нет возможности в таймере по одному фронту записать значение счетчика в один регист, а по второму во второй. Т.к. оба предложенных решения требуют задействования 2-х ножек Мега.

Есть такая возможность! Подаёте свой сигнал на вход прерывания, настраиваете реакцию на оба фронта. В обработчике первым делом ветвитесь по уровню сигнала - какой фронт. И вперёд.
interrupt:
in reg,port
sbrc port,bit
rjmp falling
mov reg_raising,timer
ret
falling: mov reg_falling,timer
ret

Регистр флагов запоминать не нужно - ни одна команда его не меняет. 14 циклов процессора - 625 нс.
MrYuran
Цитата(Ojo @ Jun 26 2008, 19:56) *
Спасибо за ответы. Жалко что у меги нет возможности в таймере по одному фронту записать значение счетчика в один регист, а по второму во второй. Т.к. оба предложенных решения требуют задействования 2-х ножек Мега.

Можно выбрать, по какому фронту захват делать. А после первого захвата перенастроить на другой фронт.


Цитата(Maik-vs @ Jun 27 2008, 12:23) *
Таймер даёт прерывания через, например 1 миллисекунду. Точность 0.1%, всё синхронно

читаем задание:
Цитата
редко, небольшими импульсами различной длины от 1 мсек до 10 мсек

ну и где, спрашивается, "Точность 0.1%, всё синхронно"?
в лучшем случае 10%, а то и вообще импульс мимо пролетит.
не забываем ещё, что
Цитата
в силу специфики прошивки устройства Мега может запретить прерывания на длительное время (до 10 мсек)
Палыч
Цитата(Maik-vs @ Jun 27 2008, 12:23) *
Есть такая возможность! Подаёте свой сигнал на вход прерывания, настраиваете реакцию на оба фронта. В обработчике первым делом ветвитесь по уровню сигнала - какой фронт. И вперёд.


Цитата(MrYuran @ Jun 27 2008, 12:43) *
Можно выбрать, по какому фронту захват делать. А после первого захвата перенастроить на другой фронт.
Отвечающие, по-моему, забывают, что проблема в том, что прерывания могут быть запрещены на время бОльшее, чем длительность импульса...

Цитата(Ojo @ Jun 26 2008, 19:56) *
оба предложенных решения требуют задействования 2-х ножек Мега.
Наверное, на МК много чего подключено, раз двух ножек жалко. Тогда, может быть, поручить эту задачу отдельному МК (tiny) и подцепить его к m128 каким-нибудь уже используемым интерфейсом, позволяющим работать с несколькими устройствами (например, SPI)?
MrYuran
<offtop>
Да вообще эти меги такое убожество... просто зло берёт. Один TimerB с 7-ю защёлками в МСП стоит всех таймеров любой меги
</offtop>
Maik-vs
Цитата(Палыч @ Jun 27 2008, 13:57) *
Отвечающие, по-моему, забывают, что проблема в том, что прерывания могут быть запрещены на время бОльшее, чем длительность импульса...

Да, пардон, невнимательно прочитал. Просто не могу себе представить, зачем при такой частоте процессора запрещать прерывания на целых 10 мсек. Тут затык - переделывать надо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.