обработка импульсов микроконтроллером

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Родился
Сообщения: 10
Зарегистрирован: Пн дек 10, 2007 01:42:52

Сообщение DOCKtor_vatson »

Здравствуйте. Не могу решить одну проблему с обработкой импульсов микроконтроллером.
1. Есть необходимость обрабатывать импульс с приёмника радиоаппаратуры. С приёмника, в зависимости от положения ручек управления на передатчике, на один канал приходит импульс от 0.8 мс до 2.2 мс. Можно ли с помощью кода программы как то преобразоваться это изменение импульсов до логического 0 или 1, т.е. при подаче импульса от 0.8 до 1мс считать 0, а при 1.8 до 2.2 мс -1?
2. Если этого сделать нельзя программно, как реализовать с помощью постоянной логики?
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....

Сообщение Meteor »

Можно решить на контроллере например AVR используя два внешних прерывания. Одно запускает старт счетчика по переднему фронту, а второе обрабатывает задний фронт и ищет разницу во времени. Для логики, если импульс идет с периодом, то можно настроить интегрирующую цепочку, с постоянной времени такой чтоб при одной длительности она не заряжалась, а при другой зараяжалась (проходила порог срабатывания). какой путь ыбирать Вам решать
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Контактная информация:
Реклама
Родился
Сообщения: 10
Зарегистрирован: Пн дек 10, 2007 01:42:52

Сообщение DOCKtor_vatson »

А нельзя ли сделать проще?
например:
сигнал пустить на один из портов d.
в прошивке назначить опрос порта с задержкой в эти самые 0.8 мс и повторить опрос, если сигнала повторно нет, то засчитать как 0, если сигнал повторно есть то считать как 1, а дальше не сложно.
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев

Сообщение BCluster »

Можно - не эффективно, но можно (:
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
akl
Друг Кота
Сообщения: 4450
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

DOCKtor_vatson писал(а):... приходит импульс от 0.8 мс до 2.2 мс. Можно ли с помощью кода программы как то преобразоваться это изменение импульсов до логического 0 или 1, т.е. при подаче импульса от 0.8 до 1мс считать 0, а при 1.8 до 2.2 мс -1?...
Здравствуйте. Какой логический уровень будет соответствовать сигналу длительностью 1.4мс?
Реклама
Держит паяльник хвостом
Аватара пользователя
Сообщения: 993
Зарегистрирован: Пн сен 18, 2006 11:16:05
Откуда: Тула

Сообщение 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, если вне диапазонов то считаем не подходит.
Контактная информация:
Реклама
Родился
Сообщения: 10
Зарегистрирован: Пн дек 10, 2007 01:42:52

Сообщение 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
Контактная информация:
Родился
Сообщения: 10
Зарегистрирован: Пн дек 10, 2007 01:42:52

Сообщение DOCKtor_vatson »

Neekeetos писал(а):Это элементарно, ватсон. Надо организовать в МК прерывание с частотой 5000Гц и в нем считывать состояние входа. Тогда в силу того что период опроса равен 0,2мс будет следующее - при получении 4 и 5 единиц подряд считаем 0, если от 9 до 11 единиц подряд то считаем 1, если вне диапазонов то считаем не подходит.
я так думаю этот вариант не подходит, почему, будет видно на осциллограммах. Постараюсь выложить вечером.
Контактная информация:
Открыл глаза
Сообщения: 76
Зарегистрирован: Сб ноя 10, 2007 14:28:04
Откуда: UA

Сообщение AndryG »

Meteor писал(а):Можно решить на контроллере например AVR используя два внешних прерывания...
Можно обойтись одним внешним прерыванием и таймером.
Внешнее прерывание настраиваем на любой фронт.

Внутри прерывания:
если начало импульса - стартуем таймер.
если конец - останавливаем таймер и смотрим, что он там насчитал.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....

Сообщение Meteor »

AndryG писал(а):Можно обойтись одним внешним прерыванием и таймером.
Внешнее прерывание настраиваем на любой фронт.
Внутри прерывания:
если начало импульса - стартуем таймер.
если конец - останавливаем таймер и смотрим, что он там насчитал.
Можно, но мне такие решения не нравятся, прежде всего тем что надо пересраивать режимы работы. Причем изменять внутри самого прерывания. Кстати тут подобная тема бродила, и не одна. Вот например: http://radiokot.ru/forum/viewtopic.php?t=19002
Выводы:
1) Фсйо уже изобретено до нас; :wink:
2) Иногда надо пользоватьсйа поиском... :tea:
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Контактная информация:
Встал на лапы
Аватара пользователя
Сообщения: 84
Зарегистрирован: Вт ноя 25, 2008 18:56:41

Сообщение OBIVAN »

Я так понимаю речь идет о пропорциональном управлении, исходя из слов передатчик точно выдает пропорциональные сигналы, самое простое решение на мой взгляд: 1- делаем предсенхронизацию по любому выводу МК. то-есть ищем фронт сигнала, 2-запускаем таймер от внутреннего источника тактовых импульсов, 3- ждем изменения фронта и останавливаем таймер, 4-зная какой частотой мы заполняли таймер подсчитываем длительность и принимаем решение 1 или ноль или что там еще понадобится,в принципе туда команд можно будет всунуть поболее чем 2.
Друг Кота
Аватара пользователя
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....

Сообщение Meteor »

OBIVAN писал(а):Я так понимаю ...самое простое решение на мой взгляд: 1- делаем предсенхронизацию по любому выводу МК. то-есть ищем фронт сигнала, 2-запускаем таймер от внутреннего источника тактовых импульсов, 3- ждем изменения фронта и останавливаем таймер, 4-зная какой частотой мы заполняли таймер подсчитываем длительность и принимаем решение
Если других функций нет у МК то да. А если есть то проще освоить прерывания. По ссылкам найдете решения. Зачем изобретать лисапед, когда достаточно поднапрячься и сделать как надо.. :tea:
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Контактная информация:
Родился
Сообщения: 10
Зарегистрирован: Пн дек 10, 2007 01:42:52

Сообщение DOCKtor_vatson »

выкладываю осциллограммы. огромное спасибо вам за советы, сегодня буду пробовать программить. Уважаемый Meteor, посмотрел то, что вы посоветовали, к сожалению не понимаю язык си, работаю, точнее изучаю, асамблер.
Вложения
143304.jpg
Развёртка 5 мс. получается, что частота повторений импульса 20-22мс
(64.65 КБ) 649 скачиваний
143420.jpg
развёртка 0.2, получается что при нижнем положении ручки управления длинна импульса составляет 0.8 мс
(61.76 КБ) 679 скачиваний
143343.jpg
развёртка 0.2, при верхнем положении ручки, длинна импульса составляет 1.8 (т.е. крайнее значение)
(62.54 КБ) 394 скачивания
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....

Сообщение Meteor »

DOCKtor_vatson писал(а):посмотрел то, что вы посоветовали, к сожалению не понимаю язык си, работаю, точнее изучаю, асамблер.
Я ссылался на идею, а не текст. Сам тоже пишу на ассемблере причем уже с 3 архитектурой. Доволен как кот у сметаны:)))
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Контактная информация:
Родился
Сообщения: 10
Зарегистрирован: Пн дек 10, 2007 01:42:52

Сообщение 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

Контактная информация:
akl
Друг Кота
Сообщения: 4450
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

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

Код: Выделить всё

ldi Temp,0bxxxxxxx0
принудительно сбрасывает значение PORTB0.
Сделал так, вроде получилось.
Встал на лапы
Аватара пользователя
Сообщения: 107
Зарегистрирован: Ср дек 10, 2008 15:10:59
Откуда: KPACHO9PCK

Сообщение 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

ВОТ КАК ТО ТАК
Чем больше думаеш, тем дольше уснуть не можеш...
Контактная информация:
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 37
Зарегистрирован: Сб дек 22, 2007 17:13:24

Сообщение Dock »

akl писал(а):Здравствуйте. Программа, после выполнения прерывания и окончания текущей задержки, командой

Код: Выделить всё

ldi Temp,0bxxxxxxx0
принудительно сбрасывает значение PORTB0.
Сделал так, вроде получилось.
попробовал ваш код, у меня некорректно обрабатывает тело программы (сначало подаётся разовый сигнал на PB5 потом на PB6 и впоследствии горят 4 светика и ничего не происходит, прерывание работает). может фузы какие не включены. кристал tini 2313 20 su

а нельзя как то прибавить дорпустим значения temp к temp1.
после прерывания сохранить значения в temp а в начале каждого вывода в порт просто складывать значения??

и здесь решение найдено
команда add
получается после прерывания
in temp4, pinb ;сохраняем значение после прерывания

в теле программы
add temp,temp4 сложение значений
out portb,temp вывод на индикацию
Последний раз редактировалось Dock Пт ноя 06, 2009 20:09:18, всего редактировалось 1 раз.
Контактная информация:
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 37
Зарегистрирован: Сб дек 22, 2007 17:13:24

Сообщение Dock »

решение найдено
применив вместо этого:
Ldi temp, 0x0xxxxxxx
out portb,temp

вот это:

sbi port,x
и
cbi port,x

кому интересно могу выложить прошивку.
Контактная информация:
akl
Друг Кота
Сообщения: 4450
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Пока писал решение было найдено.
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»