Захват импульсного сигнала с определением времени следования

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Re: Захват импульсного сигнала с определением времени следов

Сообщение ВитГо »

а я вот смотрю на ETIMSK и думаю а почему там не ноль?

сейчас проверю свою догадку !
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Re: Захват импульсного сигнала с определением времени следов

Сообщение ВитГо »

все вопрос по зависанию снят !!!

ETIMSK должен быть равен нулю ! а там было 0х10 - то есть прерывание по переполнению timer3 - вот и был вис !
Елисей
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт мар 05, 2009 23:21:53

Re: Захват импульсного сигнала с определением времени следов

Сообщение Елисей »

Ура))) теперь ждем результата по отсчитыванию длинны импульса.
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Re: Захват импульсного сигнала с определением времени следов

Сообщение ВитГо »

а как задается приоритет прерываний?

что более приоритетно timer1 или внешнее прерывание int7 ?
Елисей
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт мар 05, 2009 23:21:53

Re: Захват импульсного сигнала с определением времени следов

Сообщение Елисей »

никак не задается. что первое сработает то и будет выполняться. во время обработки одного прерывания, все остальные на это время запрещаются. так чтоб оба сразу - какая то невероятная ситуация, хотя самому интересно что будет.
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Re: Захват импульсного сигнала с определением времени следов

Сообщение ВитГо »

запрещаются автоматом или я вначале обработчика прерывания должен cli поставить ?
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Re: Захват импульсного сигнала с определением времени следов

Сообщение ВитГо »

докладываю о своих экспериментах

реализовываю следующий алгоритм:

запустил таймер3 на счет со скоростью 2 мгц...

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

// Timer/Counter 3 initialization   - генератор для отсчета микросекунд для захвата PPM
// Clock source: System Clock
// Clock value: 2000,000 kHz
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Timer 3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR3A=0x00;
TCCR3B=0x02;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;


далее сконфигурировал вход на генерацию прерывания по любому изменению на нем

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

    PORTG=0b00010000; // включаем прерывание на захват
    EICRA=0x00; // любое изменение сигнала
    EICRB=0x40;
    EIMSK=0x80;
    EIFR=0x80;


после этого вся работа идет в обработчике прерывания

// External Interrupt 7 service routine
// Прерывание в котором осуществляется захват PPM с тренерского разъема
unsigned char cap_step; // фаза захвата
unsigned int f1,f2; // длительности захваченных импульсов
unsigned char cap_ch; // номер захватываемого канала
unsigned int TCAP_PPM[8]; // временные значения захваченных каналов - не проверенные

interrupt [EXT_INT7] void ext_int7_isr(void) {

#asm("cli")

f1=(TCNT3H*256+TCNT3L)/2; // отсчитаем длительность импульса

// вариант 1

if ( (f1>30) && (f1<500)) { // изменение уровня произошло от 50 до 300 мкс от предыдущего

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

мы не обнуляем счетчик TCNT3 - так как нам понадобиться длительность и импульса и паузы

}

else

// если изменение уровня произошло в большее время от 700 до 2400 - то мы получили
// значение канала равно длина импульса + длина паузы "=____"

if ( (f1>700) && (f1<2400) ) { // это канальный импульс ?

TCNT3H=0; TCNT3L=0; // сбрасываем счетчик - для подсчета длительности следующего канала

// каналов не может быть больше 8 - поэтому сохраняем только 8 и потом не сохраняем потому что пакет ошибочен если каналов больше 8

if (cap_ch<8) {
f2=f2+f1; // считаем общую длительность пачки импульсов
TCAP_PPM[cap_ch]=f1; // сохраняем длительность канала во временном массиве
}
cap_ch++; // увеличиваем счетчик каналов
}

else

// если импульс + пауза длятся более 3000 мкс - то это уже не канал а пауза между пачками каналов "=_____________"

if (f1>3000) { // это пауза между пачками ?

TCNT3H=0; TCNT3L=0; // сбрасываем счетчик - теперь идет канал-1 следующей пачки

сумма длительностей импульсов + длительность паузы не должны быть более 23 мс (23000 мкс)
if ((f2+f1)<23000) { // если пачка правильная по длительности то выводим ее

for (cap_ch=0;cap_ch<8;cap_ch++) CAP_PPM[cap_ch]=TCAP_PPM[cap_ch];
массив CAP_PPM - это как раз выход захваченных импульсов
}
else // иначе обнуляем временный массив длительностей каналов
for (cap_ch=0;cap_ch<8;cap_ch++) TCAP_PPM[cap_ch]=0;

f2=0; // обнуляем сумму длительностей всех каналов

cap_ch=0; // считываем каналы с начала
}

#asm("sei")
}


все вроде правильно.. но вот незадача- это прерывание должно работать параллельно с другим прерыванием... причем более тяжеловесным и занимающим больше процессорного времени..
мне нужно обеспечить приоритетность этого прерывания, чтобы захват импульсов происходил даже из процедуры другого прерывания...
это возможно?
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Re: Захват импульсного сигнала с определением времени следов

Сообщение ВитГо »

выше был первый вариант процедуры захвата

второй вроде умнее.. но почему то не работает

// External Interrupt 7 service routine
// Прерывание в котором осуществляется захват PPM с тренерского разъема

unsigned char cap_step; // фаза захвата
unsigned int f1,f2; // длительности захваченных импульсов
unsigned char cap_ch; // захватываемый канал
unsigned int TCAP_PPM[8]; // временные переменные захвата

interrupt [EXT_INT7] void ext_int7_isr(void) {
#asm("cli")

f1=(TCNT3H*256+TCNT3L)/2; // отсчитаем длительность импульса

switch (cap_step) {

case 0 : { // начало импульса (нарастающий фронт)
TCNT3H=0; TCNT3L=0; // сброс счетчика
cap_step=1; // ищем спадающий фронт
break;
}

case 1 : { // получаем падающий фронт

if ( (f1>30) && (f1<400) ) { // проверяем длительность импульса от 30 до 400 мкс

cap_step=2; // ждем начала следующего импульса отсчета
}
else { // если длительность импульса не правильная - то ждем следующее
изменение уровня сигнала на входе пока не получим правильную длину импульса

TCNT3H=0; TCNT3L=0; // сброс счетчика

cap_step=1; // ищем второй фронт импульса

}
break;
}

case 2 : { // получаем фронт второго импульса - между первым фронтом первого импульса и первым фронтом второго импульса - промежуток времени показывает нам значение канала или указывает на паузу

TCNT3H=0; TCNT3L=0; // сброс счетчика для подсчета следующего канала

// если длительность от 750 до 2400 мкс - значит это канал !

if ( (f1>750) && (f1<2400) ) { // у нас считан канал

if (cap_ch<8) { // если каналов не больше 8 - значит все ОК, сохраняем
f2=f2+f1;
TCAP_PPM[cap_ch]=f1; // сохраняем длительность канала
}
cap_ch++; // увеличиваем номер канала для ожидания
cap_step=1; // ждем второй фронт импульса
}
else {

if (f1>3000) { // у нас считана межканальная пауза

TCNT3H=0; TCNT3L=0; // сбрасываем счетчик

if ((f2+f1)<23000) { // если пачка правильная по длительности то выводим ее
for (cap_ch=0;cap_ch<8;cap_ch++) CAP_PPM[cap_ch]=TCAP_PPM[cap_ch];
} else for (cap_ch=0;cap_ch<8;cap_ch++) TCAP_PPM[cap_ch]=0;
f2=0;
cap_ch=0; // считываем каналы с начала
cap_step=1;
}
}
break;
}
default : { cap_step=0; }
}


этот код не работает. хотя вроде как правильный.. и должен синхронизироваться сам по сигналу (шаг 1) и потом работать....
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

Re: Захват импульсного сигнала с определением времени следов

Сообщение ВитГо »

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

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