Страница 1 из 3
обработка импульсов микроконтроллером
Добавлено: Вт окт 27, 2009 21:21:52
DOCKtor_vatson
Здравствуйте. Не могу решить одну проблему с обработкой импульсов микроконтроллером.
1. Есть необходимость обрабатывать импульс с приёмника радиоаппаратуры. С приёмника, в зависимости от положения ручек управления на передатчике, на один канал приходит импульс от 0.8 мс до 2.2 мс. Можно ли с помощью кода программы как то преобразоваться это изменение импульсов до логического 0 или 1, т.е. при подаче импульса от 0.8 до 1мс считать 0, а при 1.8 до 2.2 мс -1?
2. Если этого сделать нельзя программно, как реализовать с помощью постоянной логики?
Добавлено: Вт окт 27, 2009 22:22:06
Meteor
Можно решить на контроллере например AVR используя два внешних прерывания. Одно запускает старт счетчика по переднему фронту, а второе обрабатывает задний фронт и ищет разницу во времени. Для логики, если импульс идет с периодом, то можно настроить интегрирующую цепочку, с постоянной времени такой чтоб при одной длительности она не заряжалась, а при другой зараяжалась (проходила порог срабатывания). какой путь ыбирать Вам решать
Добавлено: Ср окт 28, 2009 00:41:46
DOCKtor_vatson
А нельзя ли сделать проще?
например:
сигнал пустить на один из портов d.
в прошивке назначить опрос порта с задержкой в эти самые 0.8 мс и повторить опрос, если сигнала повторно нет, то засчитать как 0, если сигнал повторно есть то считать как 1, а дальше не сложно.
Добавлено: Ср окт 28, 2009 02:36:46
BCluster
Можно - не эффективно, но можно (:
Re: обработка импульсов микроконтроллером
Добавлено: Ср окт 28, 2009 06:08:24
akl
DOCKtor_vatson писал(а):... приходит импульс от 0.8 мс до 2.2 мс. Можно ли с помощью кода программы как то преобразоваться это изменение импульсов до логического 0 или 1, т.е. при подаче импульса от 0.8 до 1мс считать 0, а при 1.8 до 2.2 мс -1?...
Здравствуйте. Какой логический уровень будет соответствовать сигналу длительностью 1.4мс?
Re: обработка импульсов микроконтроллером
Добавлено: Ср окт 28, 2009 08:28:01
Neekeetos
DOCKtor_vatson писал(а):Здравствуйте. Не могу решить одну проблему с обработкой импульсов микроконтроллером.
1. Есть необходимость обрабатывать импульс с приёмника радиоаппаратуры. С приёмника, в зависимости от положения ручек управления на передатчике, на один канал приходит импульс от 0.8 мс до 2.2 мс. Можно ли с помощью кода программы как то преобразоваться это изменение импульсов до логического 0 или 1, т.е. при подаче импульса от 0.8 до 1мс считать 0, а при 1.8 до 2.2 мс -1?
2. Если этого сделать нельзя программно, как реализовать с помощью постоянной логики?
Это элементарно, ватсон. Надо организовать в МК прерывание с частотой 5000Гц и в нем считывать состояние входа. Тогда в силу того что период опроса равен 0,2мс будет следующее - при получении 4 и 5 единиц подряд считаем 0, если от 9 до 11 единиц подряд то считаем 1, если вне диапазонов то считаем не подходит.
Re: обработка импульсов микроконтроллером
Добавлено: Ср окт 28, 2009 13:10:30
DOCKtor_vatson
akl писал(а):DOCKtor_vatson писал(а):... приходит импульс от 0.8 мс до 2.2 мс. Можно ли с помощью кода программы как то преобразоваться это изменение импульсов до логического 0 или 1, т.е. при подаче импульса от 0.8 до 1мс считать 0, а при 1.8 до 2.2 мс -1?...
Здравствуйте. Какой логический уровень будет соответствовать сигналу длительностью 1.4мс?
я разделил например.. можно разделить как угодно хоть от 0.8 до 1.4 =0, а от 1.5 до 2.2 =1
Re: обработка импульсов микроконтроллером
Добавлено: Ср окт 28, 2009 13:19:45
DOCKtor_vatson
Neekeetos писал(а):Это элементарно, ватсон. Надо организовать в МК прерывание с частотой 5000Гц и в нем считывать состояние входа. Тогда в силу того что период опроса равен 0,2мс будет следующее - при получении 4 и 5 единиц подряд считаем 0, если от 9 до 11 единиц подряд то считаем 1, если вне диапазонов то считаем не подходит.
я так думаю этот вариант не подходит, почему, будет видно на осциллограммах. Постараюсь выложить вечером.
Добавлено: Ср окт 28, 2009 20:50:44
AndryG
Meteor писал(а):Можно решить на контроллере например AVR используя два внешних прерывания...
Можно обойтись одним внешним прерыванием и таймером.
Внешнее прерывание настраиваем на любой фронт.
Внутри прерывания:
если начало импульса - стартуем таймер.
если конец - останавливаем таймер и смотрим, что он там насчитал.
Добавлено: Ср окт 28, 2009 21:46:45
Meteor
AndryG писал(а):Можно обойтись одним внешним прерыванием и таймером.
Внешнее прерывание настраиваем на любой фронт.
Внутри прерывания:
если начало импульса - стартуем таймер.
если конец - останавливаем таймер и смотрим, что он там насчитал.
Можно, но мне такие решения не нравятся, прежде всего тем что надо пересраивать режимы работы. Причем изменять внутри самого прерывания. Кстати тут подобная тема бродила, и не одна. Вот например:
http://radiokot.ru/forum/viewtopic.php?t=19002
Выводы:
1) Фсйо уже изобретено до нас;
2) Иногда надо пользоватьсйа поиском...

Добавлено: Ср окт 28, 2009 22:37:50
OBIVAN
Я так понимаю речь идет о пропорциональном управлении, исходя из слов передатчик точно выдает пропорциональные сигналы, самое простое решение на мой взгляд: 1- делаем предсенхронизацию по любому выводу МК. то-есть ищем фронт сигнала, 2-запускаем таймер от внутреннего источника тактовых импульсов, 3- ждем изменения фронта и останавливаем таймер, 4-зная какой частотой мы заполняли таймер подсчитываем длительность и принимаем решение 1 или ноль или что там еще понадобится,в принципе туда команд можно будет всунуть поболее чем 2.
Добавлено: Чт окт 29, 2009 07:39:16
Meteor
OBIVAN писал(а):Я так понимаю ...самое простое решение на мой взгляд: 1- делаем предсенхронизацию по любому выводу МК. то-есть ищем фронт сигнала, 2-запускаем таймер от внутреннего источника тактовых импульсов, 3- ждем изменения фронта и останавливаем таймер, 4-зная какой частотой мы заполняли таймер подсчитываем длительность и принимаем решение
Если других функций нет у МК то да. А если есть то проще освоить прерывания. По ссылкам найдете решения. Зачем изобретать лисапед, когда достаточно поднапрячься и сделать как надо..

Добавлено: Чт окт 29, 2009 18:00:55
DOCKtor_vatson
выкладываю осциллограммы. огромное спасибо вам за советы, сегодня буду пробовать программить. Уважаемый Meteor, посмотрел то, что вы посоветовали, к сожалению не понимаю язык си, работаю, точнее изучаю, асамблер.
Добавлено: Чт окт 29, 2009 20:23:08
Meteor
DOCKtor_vatson писал(а):посмотрел то, что вы посоветовали, к сожалению не понимаю язык си, работаю, точнее изучаю, асамблер.
Я ссылался на идею, а не текст. Сам тоже пишу на ассемблере причем уже с 3 архитектурой. Доволен как кот у сметаны:)))
Добавлено: Пт ноя 06, 2009 02:01:13
DOCKtor_vatson
добрый вечер. уже несколько дней пишу программу. Первые пробы дали отрицательный результат, так как взялся сразу за сложное.
столкнулся с проблемой такого рода. когда проиходит обработка тела программы (на разные порты подаются импульсы), допустим срабатывает прерывание, происходит обработка прерывания при котором считывается порт D и передаётся на PB1. после этого на выход PB1 в зависимости от полученного результата с порта D подаётся 1 или 0. на как только прерывание заканчивается, основная программа сбрасывает это значение и сигнал перестаёт поступать до нового прерывания. как сделать так чтоб получаившейся в конце когда прерывания результат сохранялся и работал в теле программы.
Код: Выделить всё
.include "c:\avr\avrasm\appnotes\tn2313def.inc"
.def Temp=R16
.def Temp1=R17
.def Temp2=R18
.def Temp3=R19
.def Temp4=R20
.cseg
.org 0
rjmp Reset ;вектора прерываний
rjmp INT_0
rjmp INT_1
rjmp Timer1_capt1
rjmp Timer1_comp1
rjmp Timer1_OVF1
rjmp Timer0_OVF0
rjmp UART_RX
rjmp UART_UDRE
rjmp UART_TX
rjmp ANA_COMP
;Reset:
;INT_0:
INT_1:
Timer1_capt1:
Timer1_comp1:
Timer1_OVF1:
Timer0_OVF0:
UART_RX:
UART_UDRE:
UART_TX:
ANA_COMP:
.org 20 //размещение тела программы
Reset: //тело программы
ldi Temp,RamEnd //инициализация стека
out SPL,Temp
// настройка прерывания int0
ldi Temp,0b00000000
out DDRD,Temp //порт D настроен на вход
ldi Temp,0b11111111 //настройка портов
out DDRB,Temp
out PORTD,temp
ldi Temp,0b00000011 // по фронту
out MCUCR,Temp //установка триггера
ldi Temp,0b01000000
out GIMSK,Temp
ldi Temp,0b01100000
out GIFR,Temp //сброс флагов прерываний
sei //разрешение прерывания int0
// конец настройки прерывания int0
Begin: ldi Temp,0b11010000
rcall mig1
ldi Temp,0b11000000
rcall mig1
ldi Temp,0b11010000
rcall mig1
ldi Temp,0b11000000
rcall mig2
ldi Temp,0b11100000
rcall mig1
ldi Temp,0b11000000
rcall mig1
ldi Temp,0b11100000
rcall mig1
ldi Temp,0b11000000
rcall mig2
sei
rjmp Begin
;****************************************************
;Задержка
mig1: out PortB,Temp ;вывод на индикацию
ldi Temp1,0
ldi Temp2,70
ldi Temp3,1
Loop: dec Temp1
brne Loop
dec Temp2
brne Loop
dec Temp3
brne Loop
ret
mig2: out PortB,Temp ;вывод на индикацию
ldi Temp1,0
ldi Temp2,0
ldi Temp3,5
Loop2: dec Temp1
brne Loop2
dec Temp2
brne Loop2
dec Temp3
brne Loop2
ret
mig: ldi Temp1,0
ldi Temp2,70
wt1: dec Temp1
brne wt1
dec Temp2
brne wt1
ret
int_0:
;*****************************************
;размещение обработчика прерывания int0
in temp,PINB
sbrc temp,0
rjmp m1
sbi PORTB,0
rjmp m2
m1: cbi PORTB,0
m2: reti
Добавлено: Пт ноя 06, 2009 06:44:26
akl
Здравствуйте. Программа, после выполнения прерывания и окончания текущей задержки, командой
принудительно сбрасывает значение PORTB0.
Сделал так, вроде получилось.
Добавлено: Пт ноя 06, 2009 07:41:03
SeamaNCOS
Можно задействовать Timer1_comp1
настроить
Reset:
out TIMSK,Temp ;разрешить прерывание компаратора
out TCCR1B,Temp ;тактовый сигнал
;инициализация компаратора настраиваем на прерывание 1.79мс
out OCR1AH,Temp
out OCR1AL,Temp
out MCUCR,Temp ;НАСТРОИТЬ INT_0 ПО ВОЗРАСТАЮЩЕМУ ФРОНТУ
в прерывании
INT_0:
ldi Temp,0b01000000;разрешить прерывание компаратора
out TIMSK,Temp
ldi Temp,0 ;обнуление таймера
out TCNT1H,Temp
out TCNT1L,Temp
reti
в прерывании
Timer1_comp1:
ldi Temp,0b00000000 ;запретить прерывание компаратора
out TIMSK,Temp
in temp,PIND ;читаем PD2(int0)
ori temp,0b11111011 ;обрезка по маске
cpi temp,0b11111111 ;сравнение
breq taim18 ;если равно перейти
ldi temp1,0
reti
taim18:
ldi temp1,1
reti
Inf: ;бесконечный цикл
OUT PORTB,temp1
rjmp Inf
ВОТ КАК ТО ТАК
Добавлено: Пт ноя 06, 2009 17:36:04
Dock
akl писал(а):Здравствуйте. Программа, после выполнения прерывания и окончания текущей задержки, командой
принудительно сбрасывает значение PORTB0.
Сделал так, вроде получилось.
попробовал ваш код, у меня некорректно обрабатывает тело программы (сначало подаётся разовый сигнал на PB5 потом на PB6 и впоследствии горят 4 светика и ничего не происходит, прерывание работает). может фузы какие не включены. кристал tini 2313 20 su
а нельзя как то прибавить дорпустим значения temp к temp1.
после прерывания сохранить значения в temp а в начале каждого вывода в порт просто складывать значения??
и здесь решение найдено
команда add
получается после прерывания
in temp4, pinb ;сохраняем значение после прерывания
в теле программы
add temp,temp4 сложение значений
out portb,temp вывод на индикацию
Добавлено: Пт ноя 06, 2009 19:27:24
Dock
решение найдено
применив вместо этого:
Ldi temp, 0x0xxxxxxx
out portb,temp
вот это:
sbi port,x
и
cbi port,x
кому интересно могу выложить прошивку.
Добавлено: Пт ноя 06, 2009 19:48:37
akl
Пока писал решение было найдено.