Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Практическое использование схемы/блока захвата в 16ти разрядных таймерах AVR Mega
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Страницы: 1, 2
Буратино
Прочел в документации на процессор о возможности использования выхода аналогового компаратора, для управления блоком захвата счетчика Т1 в Меге. Хочу спросить, зачем вообще используется подобный режим работы счетчика? Ведь существует возможность внутри обработчика внешнего прерывания считать значения в счетных регистрах таймеров. Какой в этом смысл?
Я не просто так любопытствую. Необходимо обрабатывать (определять частоту сигнала 50-100кHz.) аналоговый сигнал. И я планирую использовать для формирования фронтов сигнала компаратор встроенный в Меге. Возможно, будет целесообразно использовать режим захвата для расчетов частоты?
Rst7
Для избавления от дрожания по времени момента считывания регистров относительно времени возникновения события. Джиттер, если знакомы с таким словцом.
Буратино
Цитата(Rst7 @ May 26 2009, 16:11) *
Для избавления от дрожания по времени момента считывания регистров относительно времени возникновения события. Джиттер, если знакомы с таким словцом.


Понятно. Словцо мелькало пару раз мимо сознанияsmile.gif
Ну тогда слушайте, как я сделаю:
Сконфигурирую ан. компаратор на внутренний источник опорного напряжения, и на работу с схемой захвата Т1. Сконфигурирую Т1 на нужную мне скорость счета и на захват по событию от компаратора. По фронту входного сигнала буду "выпадать" в прерывание "счетный регистр в регистре захвата" ну и дальше уже обрабатывать значения счетчиков, при этом сэкономлю на "теле" внешнего компаратора и избавлюсь от джиттера?
Rst7
Ну если Вас качество внутреннего компаратора устраивает и будете успевать все делать между двумя событиями - то все хорошо. Только Вы таким образом избавитесь только от программного джиттера.
_Pasha
Цитата(Буратино @ May 26 2009, 15:26) *
Сконфигурирую Т1 на нужную мне скорость счета


Если Вы сказали про 50-100кГц и "определять частоту", скажите и верхний лимит времени измерения - может Вам проще счетчик событий сделать а не интервалы мерять?


Цитата
при этом сэкономлю на "теле" внешнего компаратора и избавлюсь от джиттера?
И надо уточнить, устроит ли Вас стабильность внутренней опоры компаратора. А то вместо джиттера получим другую напасть... Упс, опередили smile.gif
Rst7
Цитата
может Вам проще счетчик событий сделать а не интервалы мерять?


Зато, если накопить пару десятков тысяч измерений периода, глядишь - и лишние десятичные знаки в разрешении образуются, дрожание в аппаратной части отфильтруется smile.gif
Буратино
Время измерения частоты должно быть минимальным, но достаточным для точного расчета. Считать события наверное не получится, так как за определенный промежуток времени может пройти столько же импульсов помехи (а помехи есть, и много) сколько прошло бы и фронтов у полезного сигнала.
Качество внутренней опоры вполне подходит, ведь мне необходимо формировать с ее помощью фронт для схемы захвата, которая будет сохранять зн. счетчика всегда с одной и фиксированной погрешностью. Пральна?
Rst7
Цитата
Время измерения частоты должно быть минимальным, но достаточным для точного расчета.


Цифры желаемой точности в студию.

Цитата
Пральна?


Не совсем. Шум еще есть. Как опоры, так и компаратора.
Буратино
Цитата(Rst7 @ May 26 2009, 16:49) *
Цифры желаемой точности в студию.
Не совсем. Шум еще есть. Как опоры, так и компаратора.


Было бы замечательно ,если бы я смог отделить 50kHz от 51kHz на протяжении пяти периодов сигнала.
_Pasha
Цитата(Буратино @ May 26 2009, 15:48) *
Время измерения частоты должно быть минимальным, но достаточным для точного расчета.


Это словоблудие smile.gif Знаете, как его расчитать, с учетом того, что будете усреднять измеренные интервалы? Я лично - не знаю, т.к. исходной информации маловато.

Цитата
Считать события наверное не получится, так как за определенный промежуток времени может пройти столько же импульсов помехи


Как все запущено (с сигналом, не у Вас smile.gif  ) Вам там корреляционный прием случайно не нужен?

Цитата
Качество внутренней опоры ... Пральна?



До тех пор пока Вас не припечет долговременная стабильность опоры (флуктуации в течение времени порядка времени измерения). Это ж тоже надо конкретизировать в  Вашем ТЗ.
Rst7
Цитата
Было бы замечательно ,если бы я смог отделить 50kHz от 51kHz на протяжении пяти периодов сигнала.


Огласите соотношение сигнал/шум на входе.
_Pasha
Походу, тут без корреляционного приема не обойтись. Вспомнил еще такое чудо: http://www.jaycar.com.au/images_uploaded/LM567.PDF  , но там чтобы 50 от 51 отличить надо 100 периодов. Оно и понятно - вчерашний день smile.gif
Rst7
Цитата
Оно и понятно - вчерашний день


Да хоть позавчерашний и послезавтрашний. Все зависит от соотношения сигнал-шум.
Буратино
Цитата(Rst7 @ May 26 2009, 17:00) *
Огласите соотношение сигнал/шум на входе.

07.gif , ну как вам сказать..я не знаю laughing.gif

В идеале никакого шума нет вообще, но в реале, всякие там мобильники, техника работающая - создают помеху, которую усиливает мой усилок (Именно он готовит сигнал для последующей обработки. Я обсуждал в разделе схемотехники его устройство)
Сначала я хотел фильтровать все , что не 50kHz, но потом понял, что помеха, если она есть, "задавит" полезный сигнал на входе усилка все равно! И нет никакого смысла пытаться аппаратно от нее избавиться до процессора. Лучше сделать проще схемотехнику девайса, тем самым ув. ее надежность.
Другими словами представьте себе что шума нетsmile.gif
Rst7
Вы бы более глобально задачу обрисовали. А то что-то непонятное... В той теме усилитель с детектором, в этой уже без детектора, а сразу 50кГц... Нифига не понятно...
_Pasha
Цитата(Буратино @ May 26 2009, 16:12) *
Другими словами представьте себе что шума нет smile.gif

Не, Вы не поняли. Имеется ввиду динамический диапазон сигнала на входе. В децибубелах. smile.gif
Буратино
Цитата(_Pasha @ May 26 2009, 17:16) *
Не, Вы не поняли. Имеется ввиду динамический диапазон сигнала на входе. В децибубелах. smile.gif


На входе чего? Если на входе компаратора, то это совсем другая песня. Это не имеет отношения к вопросу! Будем считать, что сигнал уже сформирован по уровню, и вообще зачем так усложнять? 1111493779.gif

Модератор. Вам еще не надоело повторять этот анекдот с периодичностью в две недели? Фиксирую повторное нарушение п.2.1в Правил форума.
Rst7
Цитата
и вообще зачем так усложнять?


Если Вы хотите просчитать поведение схемы перед тем, как ее создавать - то надо. Ну а так, можете конечно попробовать замерить 4 интервала и по сумме значений определить частоту...
Goodefine
Случайно, не об этой ли проблеме идет речь?
_Pasha
Цитата(Буратино @ May 26 2009, 16:28) *
 и вообще зачем так усложнять? 1111493779.gif

Тогда меряйте 5 периодов - и в медиану Ходжеса-Лемана. Т.е. образуете ряд из полусумм 5-ти измерений (это будет 15 значений), упорядочиваете его и берете 7-й элемент (считая от 0)
Буратино
Цитата(Rst7 @ May 26 2009, 17:34) *
Если Вы хотите просчитать поведение схемы перед тем, как ее создавать - то надо. Ну а так, можете конечно попробовать замерить 4 интервала и по сумме значений определить частоту...


Да, спасибо, буду значит разводить плату. НЕобходим был беглый взгляд профи на "идею". Слово идея я специально взял в кавычички, ибо ровно как и термин "джиттер", оно лишь только пролетаем изредка мимо моего сознания.
Rst7
Цитата
Случайно, не об этой ли проблеме идет речь?


Если о ней - то там же цифры более вменяемые. 0.05-0.1 секунды - это уже что-то, 5-10 периодов разности частот. Корреляционный прием спасет отца русской демократии smile.gif

Устроит ли топикстартера принятие решения о наличии частоты в 50кГц или 51кГц за 1мс? Если да, то можно достаточно вменяемый код корреляционного приемника сделать. Правда, придется занять SPI, один таймер и сделать внешний компаратор.

PS и где-то ~512 байт флеша на таблички.
_Pasha
Цитата(Rst7 @ May 26 2009, 16:45) *
Корреляционный прием спасет отца русской демократии smile.gif

Кстати, если пауза между измерениями допустима, то можно с частотой выборки 1,6 МГц аж бегом набить 2*20 байт и потом неспеша кодовое расстояние считать. Выгрузку образцового сигнала тоже в ОЗУ предварительно делать...
Буратино
Цитата(Rst7 @ May 26 2009, 17:50) *
Устроит ли топикстартера принятие решения о наличии частоты в 50кГц или 51кГц за 1мс? Если да, то можно достаточно вменяемый код корреляционного приемника сделать. Правда, придется занять SPI, один таймер и сделать внешний компаратор.
PS и где-то ~512 байт флеша на таблички.


Максимально допустимое время расчета частоты нужно считать, при этом учитывая массу факторов, которые при определенном стечении обсттоятельств, могут сложиться в одну большую... Сказал 5 периодов так как меньшее время уже совсем глупасть. SPI занят радиоканалом, с таймерами тоже не густо, зато флеши свободной больше чем у меня на диске С.
Но для общего развития намекните приблизительно, как эТО делают при помощи корреляционного метода ?
Спс.

Пауза между измерениями допустима.
Rst7
Цитата
SPI занят радиоканалом


В принципе SPI нужен только для разгрузки проца. Можно будет сразу по 8 бит обрабатывать. USART в режиме SPI есть?

Цитата
с таймерами тоже не густо


Таймер нужен для генерации тактового сигнала SPI в режиме Slave (потому что в мастере есть дырки). Если использовать USART в режиме SPI, то таймер не нужен.
Goodefine
Помехи в полезный сигнал (при его наличии) пролазят?
Буратино
Цитата(Rst7 @ May 26 2009, 18:03) *
В принципе SPI нужен только для разгрузки проца. Можно будет сразу по 8 бит обрабатывать. USART в режиме SPI есть?



Таймер нужен для генерации тактового сигнала SPI в режиме Slave (потому что в мастере есть дырки). Если использовать USART в режиме SPI, то таймер не нужен.


USART в режиме SPI есть. Но у меня тут кошка рядом сидела, так она ушла... cranky.gif

Goodefne, думаю, что пролазятsad.gif
Rst7
Цитата
Но для общего развития намекните приблизительно, как эТО делают при помощи корреляционного метода ?
Спс.


Общий метод таков - результат интегрирования произведения входного сигнала на искомый - суть оптимальный приемник. Правда, есть тонкость, связанная с неопределенностью фазы входного сигнала относительно искомого (опорного). Поэтому Вам нужно будет сделать 4 перемножителя - две пары на опорные меандры с частотами 50 и 51кГц. В каждой паре 2 опорных сигнала с одной частотой должны быть сдвинуты на 90 градусов относительно друг друга (обычное обозначение I и Q).

После интегрирования у Вас будет 4 значения, I и Q для 51кГц и I,Q для 50кГц. Затем P51=I51^2+Q51^2 - суть мощность сигнала на частоте 51 кГц с полосой, равной 1/t, где t - время интегрирования, аналогично P50=I50^2+Q50^2 - для 50кГц. Затем сравниваете P50 и P51 между собой - кто больше, та частота и есть. Только еще надо ввести минимальный порог по мощности.

В общем, звучит мрачно, но программно не сложно.

Цитата
USART в режиме SPI есть. Но у меня тут кошка рядом сидела, так она ушла...


Ээээ?
_Pasha
Цитата(Буратино @ May 26 2009, 16:58) *
Но для общего развития намекните приблизительно, как эТО делают при помощи корреляционного метода ?
Спс.
Пауза между измерениями допустима.


Формируете табличку образцового сигнала (50 кГц) и его же, сдвинутого на 90 градусов по фазе. Если частота выборки 1.6 Мгц не вызывает возражений, то это


Код
SG50_sin: .db 0x00,0x00,0xff,0xff // итд до тех самых 5 периодов (т.е. это будет 20 байт)

SG50_cos: .db 0x00,0xff,0xff,0x00 // итд тоже 20 байт


Далее, накапливаете отсчеты из компаратора в сдвиговый регистр (направление сдвига вправо), по заполнению буфера делаете XOR с SG50_sin и сохраняете(канал 1), и тоже самое с SG50_cos (канал 2). Прогоняете это все дальше - до конца таблиц образцовых сигналов. Потом считаете кол-во единиц в каждом канале, пусть они будут X и Y. Полученные числа - знаковые, со смещением для нашего случая 5*16 = 80

Выход фильтра AMP=(X^2 + Y^2)

Если Вам надо четко отличить 50 от 51 - это таки 1 мс, и добавление такой же таблицы образцового сигнала для 51 кгц. Решение - победит тот, у которого AMP поболе

Но можно оценивать поведение AMP от измерения к измерению - его дисперсию. Тогда Вам нужен порог чувствительности и критерий оценки этой самой дисперсии. В общем случае это мрачно, но в Вашем - помочь может

 
Буратино
Цитата(Rst7 @ May 26 2009, 18:11) *

maniac.gif
Цитата(_Pasha @ May 26 2009, 18:20) *

smile3046.gif

Пять раз перечитал. Кошка ушла не зря.
Еще раз большое спасибо за советы и помощь, обязательно разберусь с вашимИ постамИ, даже если мне на это понадобится целая жизнь.smile.gif
Rst7
Цитата
Если частота выборки 1.6 Мгц не вызывает возражений


Многовато. 256 килогерц вполне хватит. Предлагаю тут завтра мастеркласс устроить по этому делу (сегодня уже врядли буду за компом)
_Pasha
Цитата(Rst7 @ May 26 2009, 17:40) *
Предлагаю тут завтра мастеркласс устроить по этому делу

Гут. Поищу написанное тож.
Rst7
Давайте попробуем.

Сначала немного теории на пальцах.

Если бы мы точно знали фазу начального сигнала, то интеграл , где A - входной сигнал, - круговая частота, - фаза сигнала, был бы равен значению амплитуды полосы спектра во входном сигнале с центральной частотой и полосой, равной , где t - время интегрирования.

Но мы не знаем фазу сигнала. Поэтому делается два интегратора



Второй отличается от первого сдвигом фазы опорного сигнала на 90 градусов.

Если быть точным, то I и Q представляют из себя действительные и мнимые значения результата дискретного преобразования Фурье для выбранной полосы спектра.

Для того, чтобы получить реальную амплитуду необходимо вычислить длинну вектора с координатами I и Q


Для наших целей корень вполне можно опустить. Итого, для определения двух частот необходимо вычислить четыре интеграла




А затем, после интегрирования, получить значения мощностей



Далее, банально сравниваем
Код
if ((A50>THRESH)||(A51>THRESH))
{
  if (A50>A51)
  {
     //Есть сигнал с частотой 50кГц
  }
  else
  {
     //Есть сигнал с частотой 50кГц
   }
}
else
{
   //Сигнала нет
}

где THRESH - порог обнаружения.

Теперь, от математики надо перейти к реальной жизни.

Во-первых, определиться с параметрами.

Т.к. полоса обнаружения определяется временем интегрирования, то хорошим выбором будет 1мс. Это эквивалентно полосе в 1кГц. Для простоты реализации на восьмибитных процессорах имеет смысл выбрать частоту дискретизации, ну например, 256кГц (это примерно 5 отсчетов на период сигнала).

Далее, вместо полноценного АЦП будем использовать компаратор. Его можно рассматривать как однобитный АЦП. Так как сигнал имеет разрядность один бит, то разрядность опорного сигнала тоже нужно брать 1 бит (больше просто нет смысла). Причем, этот бит определяет просто знак. Т.е. если бит равен 0 - значение сигнала равно -1, если бит равен 1 - значение сигнала равно +1.

Теперь нарисуем таблицу умножения в наших терминах
Код
a,b,a*b:
-1,-1,+1
+1,-1,-1
-1,+1,-1
+1,+1,+1

и заменим значения уровня сигнала (+1/-1) на битовые значения(1/0)

Код
a,b,a*b:
0,0,1
1,0,0
0,1,0
1,1,1


Если мы внимательно посмотрим на таблицу, то увидим, что a*b=not (a xor cool.gif. Т.к. входной сигнал мы можем безболезненно проинвертировать, то not можно убрать. Значит, все умножение входного сигнала на опорный сводится к выполнению операции xor между значениями.

Следовательно, каждый интегратор в коде будет представлять из себя
Код
I+=signal^reference;
, где I - интегратор, signal - выборка сигнала, reference - табличное значение опорного сигнала.

Тут надо обратить внимание на то, что после интегрирования необходимо вычесть из интегратора половину от количества выборок. Происходит это по простой причине - мы вместо прибавления +1 и -1 к интегратору прибавляем либо 1, либо 0, что дает сдвиг на полдиапазона. Либо можно начальное значение интегратора задавать не 0, а минус половина количества выборок.

Теперь про оптимизацию. Если делать интегрирование на каждой выборке - это будет большой перерасход ресурсов. Посему, надо обрабатывать сразу 8 бит.

Для начала - о получении 8ми бит. Надо просто выход компаратора подключить, например, ко входу MOSI, а на вход SCK подать нужную частоту выборок. В результате, в каждом байте, читаемом из SPDR будет получено 8 выборок подряд. Теперь о обработке.

Код
I+=bitcount_table[byte_signal^byte_reference]
, где byte_signal - 8 выборок сигнала в виде одного байта, byte_reference - 8 выборок опорного сигнала в виде одного байта, bitcount_table - таблица длинной 256 байт, каждый байт которой равен количеству единичных бит в индексе.

Теперь попробуем написать код интегратора более близкий к реальности. При этом для простоты разместим 2 таблицы непосредственно в конце флеша, причем, таблица опорных сигналов будет представлять из себя записи по 4 байта, каждый байт - восемь выборок для сигналов I50,Q50,I51,Q51 соответственно, общей длинной ((256 выборок всего)/(8 выборок в байте))*(4 сигнала)=128 байт
Код
typedef unsigned char UREG;
typedef signed char REG;
typedef signed char INT8;
typedef unsigned char UINT8;


volatile UINT8 I50;
volatile UINT8 Q50;
volatile UINT8 I51;
volatile UINT8 Q51;

__flash UINT8 bitcount_table[256] @ FLASHEND-0xFF;
__root __flash UINT8 reference_sig[128] @ FLASHEND-0xFF-0x80;

volatile UINT8 Int_Idx; //Начальное значение - 0x80

__interrupt void ProcessIntegrators(void)
{
  UINT8 __flash *r=(UINT8 __flash *)(FLASHEND-0xFF-0x100)+Int_Idx; //Текущее положение в таблице опорных сигналов
  UREG sig_i50;
  UREG sig_q50;
  UREG sig_i51;
  UREG sig_q51;
  sig_i50=sig_q50=sig_i51=sig_q51=SPDR;
  sig_i50^=*r++; //Операция умножения входного сигнала на опорные
  sig_q50^=*r++;
  sig_i51^=*r++;
  sig_q51^=*r++;
  Int_Idx=(int)r; //Сохранение указателя
  I50+=bitcount_table[sig_i50]; //Собственно интегрирование
  Q50+=bitcount_table[sig_q50];
  I51+=bitcount_table[sig_i51];
  Q51+=bitcount_table[sig_q51];
}


Некоторое колдовство имеется с указателем Int_Idx. Для уменьшения оверхеда его начальное значение должно быть 128, и когда он досчитает до 0, то результат интегрирования будет готов.

Вот результат компиляции EWAVR 5.11
CODE

RSEG NEAR_Z:DATA:NOROOT(0)
REQUIRE `?<Segment init: NEAR_Z>`
I50:
DS 1
Q50:
DS 1
I51:
DS 1
Q51:
DS 1
// 11
// 12 volatile UINT8 Int_Idx; //Начальное значение - 0x80
Int_Idx:
DS 1
// 13

RSEG CODE:CODE:NOROOT(1)
// 14 __interrupt void ProcessIntegrators(void)
ProcessIntegrators:
// 15 {
ST -Y, R31
ST -Y, R30
ST -Y, R22
ST -Y, R21
ST -Y, R20
ST -Y, R19
ST -Y, R18
ST -Y, R17
ST -Y, R16
IN R21, 0x3F
// 16 UINT8 __flash *r=(UINT8 __flash *)(FLASHEND-0xFF-0x100)+Int_Idx; //Текущее положение в таблице опорных сигналов
LDS R16, (I50 + 4)
LDI R31, 62
MOV R30, R16
// 17 UREG sig_i50;
// 18 UREG sig_q50;
// 19 UREG sig_i51;
// 20 UREG sig_q51;
// 21 sig_i50=sig_q50=sig_i51=sig_q51=SPDR;
IN R17, 0x2E
MOV R16, R17
MOV R18, R17
MOV R20, R17
MOV R22, R17
// 22 sig_i50^=*r++; //Операция умножения входного сигнала на опорные
LPM R17, Z+
EOR R22, R17
// 23 sig_q50^=*r++;
LPM R17, Z+
EOR R20, R17
// 24 sig_i51^=*r++;
LPM R17, Z+
EOR R18, R17
// 25 sig_q51^=*r++;
LPM R17, Z+
EOR R16, R17
// 26 Int_Idx=(int)r; //Сохранение указателя
STS (I50 + 4), R30
// 27 I50+=bitcount_table[sig_i50]; //Собственно интегрирование
MOV R30, R22
LDI R31, 63
LPM R17, Z
LDI R30, LOW(I50)
LDI R31, (I50) >> 8
LD R19, Z
ADD R19, R17
ST Z, R19
// 28 Q50+=bitcount_table[sig_q50];
MOV R30, R20
LDI R31, 63
LPM R17, Z
LDI R30, LOW(I50)
LDI R31, (I50) >> 8
LDD R19, Z+1
ADD R19, R17
STD Z+1, R19
// 29 I51+=bitcount_table[sig_i51];
MOV R30, R18
LDI R31, 63
LPM R17, Z
LDI R30, LOW(I50)
LDI R31, (I50) >> 8
LDD R18, Z+2
ADD R18, R17
STD Z+2, R18
// 30 Q51+=bitcount_table[sig_q51];
MOV R30, R16
LDI R31, 63
LPM R16, Z
LDI R30, LOW(I50)
LDI R31, (I50) >> 8
LDD R17, Z+3
ADD R17, R16
STD Z+3, R17
// 31 }
OUT 0x3F, R21
LD R16, Y+
LD R17, Y+
LD R18, Y+
LD R19, Y+
LD R20, Y+
LD R21, Y+
LD R22, Y+
LD R30, Y+
LD R31, Y+
RETI


Ну и финальное действие по достижению переменной Int_Idx значения 0 - оно банально:
Код
#define THRESH (20*0x100)

UREG TestIntegrators(void)
{
  __disable_interrupt();
  REG i50=I50;
  REG q50=Q50;
  REG i51=I51;
  REG q51=Q51;
  __enable_interrupt();
  unsigned int A50=__multiply_signed(i50,i50)+__multiply_signed(q50,q50);
  unsigned int A51=__multiply_signed(i51,i51)+__multiply_signed(q51,q51);
  if ((A50>THRESH)||(A51>THRESH))
  {
    if (A50>A51) return 1;
    else return 2;
  }
  return 0;
}


В качестве упражнения рекомендую сгенерировать самому необходимые таблицы, написать необходимую инициализацию измерения и проверку окончания.

А теперь - ваши вопросы smile.gif
singlskv
Цитата(Буратино @ May 26 2009, 17:58) *
Но для общего развития намекните приблизительно, как эТО делают при помощи корреляционного метода ?
корреляционный метод ловли частоты это конечно здорово, и Rst7 все грамотно описал,
тока мне почему-то кажеться что Вам это нафиг не нужно...(да и периодов нужно довольно много)
При наличии помех стабильно выделить наборы частот будет сложно(за короткий интервал без помех),
а вот определить что частота стала < определенной очень легко, может в этом
направлении подумать в смысле схемотехники ?
Т.е. срабатывание сигнализации == (частота < определенной),
тогда прога будет совсем простой а любые помехи просто чуть мешают "скорости" определения срабатывания сигнализации...
Rst7
Если эта тема коррелирует с той, в которой топикстартер делает приемник прямого усиления, то корреляционный прием в течении 1мс - как раз. У него добротность входного контура выходит порядка 50 smile.gif

Да, кстати. Небольшое улучшение кода коррелятора
Код
volatile struct
{
  UINT8 I50;
  UINT8 Q50;
  UINT8 I51;
  UINT8 Q51;
};

__flash UINT8 bitcount_table[256] @ FLASHEND-0xFF;
__root __flash UINT8 reference_sig[128] @ FLASHEND-0xFF-0x80;

volatile UINT8 Int_Idx; //Начальное значение - 0x80

__interrupt void ProcessIntegrators(void)
{
  UINT8 __flash *r=(UINT8 __flash *)(FLASHEND-0xFF-0x100)+Int_Idx; //Текущее положение в таблице опорных сигналов
  UREG sig_i50;
  UREG sig_q50;
  UREG sig_i51;
  UREG sig_q51;
  sig_i50=sig_q50=sig_i51=sig_q51=SPDR;
  sig_i50^=*r++; //Операция умножения входного сигнала на опорные
  sig_q50^=*r++;
  sig_i51^=*r++;
  sig_q51^=*r++;
  Int_Idx=(int)r; //Сохранение указателя
  sig_i50=bitcount_table[sig_i50]; //Подсчет единичных бит
  sig_q50=bitcount_table[sig_q50];
  sig_i51=bitcount_table[sig_i51];
  sig_q51=bitcount_table[sig_q51];
  I50+=sig_i50; //Собственно интегрирование
  Q50+=sig_q50;
  I51+=sig_i51;
  Q51+=sig_q51;
}


И результат
CODE

RSEG CODE:CODE:NOROOT(1)
// 15 __interrupt void ProcessIntegrators(void)
ProcessIntegrators:
// 16 {
ST -Y, R31
ST -Y, R30
ST -Y, R22
ST -Y, R21
ST -Y, R20
ST -Y, R19
ST -Y, R18
ST -Y, R17
ST -Y, R16
IN R21, 0x3F
// 17 UINT8 __flash *r=(UINT8 __flash *)(FLASHEND-0xFF-0x100)+Int_Idx; //Текущее положение в таблице опорных сигналов
LDS R16, (_A_I50 + 4)
LDI R31, 62
MOV R30, R16
// 18 UREG sig_i50;
// 19 UREG sig_q50;
// 20 UREG sig_i51;
// 21 UREG sig_q51;
// 22 sig_i50=sig_q50=sig_i51=sig_q51=SPDR;
IN R17, 0x2E
MOV R16, R17
MOV R18, R17
MOV R20, R17
MOV R22, R17
// 23 sig_i50^=*r++; //Операция умножения входного сигнала на опорные
LPM R17, Z+
EOR R22, R17
// 24 sig_q50^=*r++;
LPM R17, Z+
EOR R20, R17
// 25 sig_i51^=*r++;
LPM R17, Z+
EOR R18, R17
// 26 sig_q51^=*r++;
LPM R17, Z+
EOR R16, R17
// 27 Int_Idx=(int)r; //Сохранение указателя
STS (_A_I50 + 4), R30
// 28 sig_i50=bitcount_table[sig_i50]; //Подсчет единичных бит
// 29 sig_q50=bitcount_table[sig_q50];
MOV R30, R20
LDI R31, 63
LPM R20, Z
// 30 sig_i51=bitcount_table[sig_i51];
MOV R30, R18
LPM R18, Z
// 31 sig_q51=bitcount_table[sig_q51];
MOV R30, R16
LPM R16, Z
// 32 I50+=sig_i50; //Собственно интегрирование
MOV R30, R22
LPM R17, Z
LDI R30, LOW(_A_I50)
LDI R31, (_A_I50) >> 8
LD R19, Z
ADD R19, R17
ST Z, R19
// 33 Q50+=sig_q50;
LDD R17, Z+1
ADD R17, R20
STD Z+1, R17
// 34 I51+=sig_i51;
LDD R17, Z+2
ADD R17, R18
STD Z+2, R17
// 35 Q51+=sig_q51;
LDD R17, Z+3
ADD R17, R16
STD Z+3, R17
// 36 }
OUT 0x3F, R21
LD R16, Y+
LD R17, Y+
LD R18, Y+
LD R19, Y+
LD R20, Y+
LD R21, Y+
LD R22, Y+
LD R30, Y+
LD R31, Y+
RETI


Так быстрее немного smile.gif
singlskv
Цитата(Rst7 @ May 27 2009, 17:50) *
Если эта тема коррелирует с той, в которой топикстартер делает приемник прямого усиления, то корреляционный прием в течении 1мс - как раз. У него добротность входного контура выходит порядка 50 smile.gif

Ну а вот теперь представьте себе высокочастотную помеху которая наложилась на сигнал когда там 50KHz и не наложилась
когда там 51KHz, мощность двух сигналов после перемножения оказалась одинаковой...
Rst7
Цитата
Ну а вот теперь представьте себе высокочастотную помеху


Что мне представлять, за меня большие головы давно подумали, и определили, что описанный корреляцинный способ приема - оптимальный. А остальное - от лукавого.
singlskv
Цитата(Rst7 @ May 27 2009, 18:02) *
Что мне представлять, за меня большие головы давно подумали, и определили, что описанный корреляцинный способ приема - оптимальный. А остальное - от лукавого.
Не ожидал от Вас услышать такое... wassat.gif
Несомненно корреляцинный способ приема оптимальный - при определенных обстоятельствах...
Тока вот обстоятельства не факт что соответствуют smile.gif выбранному методу... (или наоборот...)

Автор топика сказал что у него помехи могут быть в любой момент, поэтому ИМХО,
будет работать только способ определения минимальной частоты...
Буратино
Если получится с резонансным усилителем на входе, то в совокупности с методом описанным ув. Rst7, я получу практически 100 процентное определение наличия полезного сигнала. Сегодня изучал детали процесса. Обязательно буду пробовать реализовать в железе.
Но если честно, то больно уж заковыристо, надеюсь затраты окупятся соответствующим качеством результата.
singlskv
Цитата(Буратино @ May 27 2009, 18:28) *
Если получится с резонансным усилителем на входе, то в совокупности с методом описанным ув. Rst7, я получу практически 100 процентное определение наличия полезного сигнала.
Вы бы уже четко описали что есть полезный сигнал...
И что у Вас с помехами...
Rst7
Цитата
Не ожидал от Вас услышать такое...


Да ладно, это мне мои телепатические способности подсказывают smile.gif Шучу. Вносите Ваше предложение о способе обнаружения сигналов, будем считать, где порог по с/ш лучше.

Хотя, лучше подождем, пока нам топикстартер расскажет о параметрах его сигнала. Иначе мы тут без исходных данных холивар как разведем - только поругаемся...
singlskv
Цитата(Rst7 @ May 27 2009, 19:47) *
Да ладно, это мне мои телепатические способности подсказывают smile.gif Шучу. Вносите Ваше предложение о способе обнаружения сигналов, будем считать, где порог по с/ш лучше.
дык все очень просто, прерывание EXTINT(или компаратор) на ноге и прерывание от таймера которое запускается в
прерывании от ножки...
прерывание от таймера настраиваем в прерываниии EXTIN(причем так чтоб прерывание возникло только если T > T реальное)
Таким образом окажемся в прерывании таймера толко если F(частота) > заданой
В принципе, есть возможность привязаться таймером к моменту перехода, тч джитера может не быть совсем...
Цитата
Хотя, лучше подождем, пока нам топикстартер расскажет о параметрах его сигнала. Иначе мы тут без исходных данных холивар как разведем - только поругаемся...
не..., ругацо не нада...
SSerge
Цитата(Rst7 @ May 27 2009, 21:47) *
Хотя, лучше подождем, пока нам топикстартер расскажет о параметрах его сигнала. Иначе мы тут без исходных данных холивар как разведем - только поругаемся...

Кстати, если топикстартер расскажет нам что полоса сигнала ограничена (или её можно ограничить неким полосовым фильтром) то частоту сэмплирования можно и понизить, вплоть до нескольких килогерц (undersampling). При этом, конечно, уменьшится и число отсчётов за миллисекунду и увеличится погрешность в вычисленных I и Q, ну да это вопрос выбора между сложностью и точностью.
Буратино
Скажите, а вывод схемы захвата ICP1 (Timer/Counter1 Input Capture Input) в меге, при подключении к нему компаратора не выводит сигнал сравнения ИЗ контроллера? То есть, на нем нет результата сравнения после соответствующей конфигурации внутренностей?
_Pasha
Цитата(Буратино @ Jun 4 2009, 22:00) *
Скажите, а вывод схемы захвата ICP1 (Timer/Counter1 Input Capture Input) в меге, при подключении к нему компаратора не выводит сигнал сравнения ИЗ контроллера? То есть, на нем нет результата сравнения после соответствующей конфигурации внутренностей?


Нету. К сожалению.
Буратино
Сделал в итоге так:
наполняю массив из 20ти значениями периода сигнала. В цикле анализирую массив. Если хоть одно значение выходит за пределы ограничения сверху или снизу - ошибка. Ни один из доступных мне источников помех ложных срабатываний не вызывает. Пока будет так.
BORIV
Теперь нарисуем таблицу умножения в наших терминах
Код
a,b,a*b:
-1,-1,+1
+1,-1,-1
-1,+1,-1
+1,+1,+1

и
А теперь - ваши вопросы smile.gif
[/quote]
Спасибо, давно так не смеялся. Люблю математические анекдоты.
Значит оцифровываем А с погрешностью 50%,
Затем грубим В до 50% погрешности,
Перемножаем А на В , поличаем 100% погрешности
и... дальше можем заниматься, чем угодно. biggrin.gif
Rst7
Цитата
Спасибо, давно так не смеялся. Люблю математические анекдоты.


Ну-ка ну-ка... Имеете что-то против? wink.gif
BORIV
Цитата(Rst7 @ Jun 22 2009, 19:40) *
Ну-ка ну-ка... Имеете что-то против? wink.gif

Против чего?
Rst7
Цитата
Против чего?


Против описанного алгоритма приема. Давайте, просим-просим, блесните знаниями в ЦОС. В другой теме обсудить другого плана вопросы Вы уже отказались, отписавшись фразой "не люблю хвастаться". Тут Вам предлагается поделиться исключительно Вашими познаниями в обсуждаемой области. Никакого "хвастовства" на этот раз от Вас не требуется.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.