Захват импульсного сигнала с определением времени следования
Re: Захват импульсного сигнала с определением времени следов
а я вот смотрю на ETIMSK и думаю а почему там не ноль?
сейчас проверю свою догадку !
сейчас проверю свою догадку !
Re: Захват импульсного сигнала с определением времени следов
все вопрос по зависанию снят !!!
ETIMSK должен быть равен нулю ! а там было 0х10 - то есть прерывание по переполнению timer3 - вот и был вис !
ETIMSK должен быть равен нулю ! а там было 0х10 - то есть прерывание по переполнению timer3 - вот и был вис !
Re: Захват импульсного сигнала с определением времени следов
Ура))) теперь ждем результата по отсчитыванию длинны импульса.
Re: Захват импульсного сигнала с определением времени следов
а как задается приоритет прерываний?
что более приоритетно timer1 или внешнее прерывание int7 ?
что более приоритетно timer1 или внешнее прерывание int7 ?
Re: Захват импульсного сигнала с определением времени следов
никак не задается. что первое сработает то и будет выполняться. во время обработки одного прерывания, все остальные на это время запрещаются. так чтоб оба сразу - какая то невероятная ситуация, хотя самому интересно что будет.
Re: Захват импульсного сигнала с определением времени следов
запрещаются автоматом или я вначале обработчика прерывания должен cli поставить ?
Re: Захват импульсного сигнала с определением времени следов
докладываю о своих экспериментах
реализовываю следующий алгоритм:
запустил таймер3 на счет со скоростью 2 мгц...
далее сконфигурировал вход на генерацию прерывания по любому изменению на нем
после этого вся работа идет в обработчике прерывания
все вроде правильно.. но вот незадача- это прерывание должно работать параллельно с другим прерыванием... причем более тяжеловесным и занимающим больше процессорного времени..
мне нужно обеспечить приоритетность этого прерывания, чтобы захват импульсов происходил даже из процедуры другого прерывания...
это возможно?
реализовываю следующий алгоритм:
запустил таймер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")
}
все вроде правильно.. но вот незадача- это прерывание должно работать параллельно с другим прерыванием... причем более тяжеловесным и занимающим больше процессорного времени..
мне нужно обеспечить приоритетность этого прерывания, чтобы захват импульсов происходил даже из процедуры другого прерывания...
это возможно?
Re: Захват импульсного сигнала с определением времени следов
выше был первый вариант процедуры захвата
второй вроде умнее.. но почему то не работает
этот код не работает. хотя вроде как правильный.. и должен синхронизироваться сам по сигналу (шаг 1) и потом работать....
второй вроде умнее.. но почему то не работает
// 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) и потом работать....
Re: Захват импульсного сигнала с определением времени следов
неужели никак нельзя находясь в одном прерывании разрешить другие ?