реклама на сайте
подробности

 
 
> Практическое использование схемы/блока захвата в 16ти разрядных таймерах AVR Mega
Буратино
сообщение May 26 2009, 12:09
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215



Прочел в документации на процессор о возможности использования выхода аналогового компаратора, для управления блоком захвата счетчика Т1 в Меге. Хочу спросить, зачем вообще используется подобный режим работы счетчика? Ведь существует возможность внутри обработчика внешнего прерывания считать значения в счетных регистрах таймеров. Какой в этом смысл?
Я не просто так любопытствую. Необходимо обрабатывать (определять частоту сигнала 50-100кHz.) аналоговый сигнал. И я планирую использовать для формирования фронтов сигнала компаратор встроенный в Меге. Возможно, будет целесообразно использовать режим захвата для расчетов частоты?

Сообщение отредактировал Буратино - May 26 2009, 12:13


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Rst7
сообщение May 27 2009, 07:13
Сообщение #2


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Давайте попробуем.

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

Если бы мы точно знали фазу начального сигнала, то интеграл , где 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


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
BORIV
сообщение Jun 22 2009, 15:14
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 131
Регистрация: 5-05-06
Пользователь №: 16 820



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

и
А теперь - ваши вопросы smile.gif
[/quote]
Спасибо, давно так не смеялся. Люблю математические анекдоты.
Значит оцифровываем А с погрешностью 50%,
Затем грубим В до 50% погрешности,
Перемножаем А на В , поличаем 100% погрешности
и... дальше можем заниматься, чем угодно. biggrin.gif
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jun 22 2009, 17:09
Сообщение #4


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(BORIV @ Jun 22 2009, 18:14) *
Значит оцифровываем А с погрешностью 50%,
Затем грубим В до 50% погрешности,
Перемножаем А на В , поличаем 100% погрешности
Измеряем полярность А с довольно приличной точностью.
Заносим в табличку полярность В с идеальной точностью.

Цитата(BORIV @ Jun 22 2009, 18:14) *
и... дальше можем заниматься, чем угодно. biggrin.gif
Продолжайте...


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
BORIV
сообщение Jun 22 2009, 17:36
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 131
Регистрация: 5-05-06
Пользователь №: 16 820



Цитата(ReAl @ Jun 22 2009, 21:09) *
Измеряем полярность А с довольно приличной точностью.
Заносим в табличку полярность В с идеальной точностью.

Продолжайте...

Вы согласны, что получив результат с погрешностью 100% я могу потом делать с ним всё, что захочу?
Или вообще нечего не делать. Это уже без разницы, так как результата у меня уже нет.
Я вёл речь о ЦОС ? Покажите где.

Зря я Вам отвечаю. Вам ведь ПРОЦЕСС важен, а не результат.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Буратино   Практическое использование схемы/блока захвата в 16ти разрядных таймерах AVR Mega   May 26 2009, 12:09
- - Rst7   Для избавления от дрожания по времени момента счит...   May 26 2009, 12:11
|- - Буратино   Цитата(Rst7 @ May 26 2009, 16:11) Для изб...   May 26 2009, 12:26
|- - _Pasha   Цитата(Буратино @ May 26 2009, 15:26) Ско...   May 26 2009, 12:36
- - Rst7   Ну если Вас качество внутреннего компаратора устра...   May 26 2009, 12:33
- - Rst7   Цитатаможет Вам проще счетчик событий сделать а не...   May 26 2009, 12:44
- - Буратино   Время измерения частоты должно быть минимальным, н...   May 26 2009, 12:48
|- - _Pasha   Цитата(Буратино @ May 26 2009, 15:48) Вре...   May 26 2009, 12:56
- - Rst7   ЦитатаВремя измерения частоты должно быть минималь...   May 26 2009, 12:49
|- - Буратино   Цитата(Rst7 @ May 26 2009, 16:49) Цифры ж...   May 26 2009, 12:56
- - Rst7   ЦитатаБыло бы замечательно ,если бы я смог отделит...   May 26 2009, 13:00
- - _Pasha   Походу, тут без корреляционного приема не обойтись...   May 26 2009, 13:06
- - Rst7   ЦитатаОно и понятно - вчерашний день Да хоть поза...   May 26 2009, 13:10
- - Буратино   Цитата(Rst7 @ May 26 2009, 17:00) Огласит...   May 26 2009, 13:12
|- - _Pasha   Цитата(Буратино @ May 26 2009, 16:12) Дру...   May 26 2009, 13:16
|- - Буратино   Цитата(_Pasha @ May 26 2009, 17:16) Не, В...   May 26 2009, 13:28
|- - _Pasha   Цитата(Буратино @ May 26 2009, 16:28)  и ...   May 26 2009, 13:41
- - Rst7   Вы бы более глобально задачу обрисовали. А то что-...   May 26 2009, 13:14
- - Rst7   Цитатаи вообще зачем так усложнять? Если Вы хотит...   May 26 2009, 13:34
|- - Буратино   Цитата(Rst7 @ May 26 2009, 17:34) Если Вы...   May 26 2009, 13:43
- - Goodefine   Случайно, не об этой ли проблеме идет речь?   May 26 2009, 13:40
- - Rst7   ЦитатаСлучайно, не об этой ли проблеме идет речь? ...   May 26 2009, 13:50
|- - _Pasha   Цитата(Rst7 @ May 26 2009, 16:45) Корреля...   May 26 2009, 13:56
- - Буратино   Цитата(Rst7 @ May 26 2009, 17:50) Устроит...   May 26 2009, 13:58
|- - _Pasha   Цитата(Буратино @ May 26 2009, 16:58) Но ...   May 26 2009, 14:20
|- - singlskv   Цитата(Буратино @ May 26 2009, 17:58) Но ...   May 27 2009, 13:32
- - Rst7   ЦитатаSPI занят радиоканалом В принципе SPI нужен...   May 26 2009, 14:03
|- - Буратино   Цитата(Rst7 @ May 26 2009, 18:03) В принц...   May 26 2009, 14:06
- - Goodefine   Помехи в полезный сигнал (при его наличии) пролазя...   May 26 2009, 14:05
- - Rst7   ЦитатаНо для общего развития намекните приблизител...   May 26 2009, 14:11
|- - Буратино   Цитата(Rst7 @ May 26 2009, 18:11) Цит...   May 26 2009, 14:25
- - Rst7   ЦитатаЕсли частота выборки 1.6 Мгц не вызывает воз...   May 26 2009, 14:40
|- - _Pasha   Цитата(Rst7 @ May 26 2009, 17:40) Предлаг...   May 26 2009, 14:44
- - Rst7   Если эта тема коррелирует с той, в которой топикст...   May 27 2009, 13:50
|- - singlskv   Цитата(Rst7 @ May 27 2009, 17:50) Если эт...   May 27 2009, 13:56
- - Rst7   ЦитатаНу а вот теперь представьте себе высокочасто...   May 27 2009, 14:02
|- - singlskv   Цитата(Rst7 @ May 27 2009, 18:02) Что мне...   May 27 2009, 14:13
- - Буратино   Если получится с резонансным усилителем на входе, ...   May 27 2009, 14:28
|- - singlskv   Цитата(Буратино @ May 27 2009, 18:28) Есл...   May 27 2009, 14:36
- - Rst7   ЦитатаНе ожидал от Вас услышать такое... Да ладно...   May 27 2009, 15:47
|- - singlskv   Цитата(Rst7 @ May 27 2009, 19:47) Да ладн...   May 27 2009, 18:36
|- - SSerge   Цитата(Rst7 @ May 27 2009, 21:47) Хотя, л...   May 27 2009, 19:46
- - Буратино   Скажите, а вывод схемы захвата ICP1 (Timer/Counter...   Jun 4 2009, 19:00
|- - _Pasha   Цитата(Буратино @ Jun 4 2009, 22:00) Скаж...   Jun 5 2009, 08:43
- - Буратино   Сделал в итоге так: наполняю массив из 20ти значен...   Jun 22 2009, 05:54
- - Rst7   ЦитатаСпасибо, давно так не смеялся. Люблю математ...   Jun 22 2009, 15:40
|- - BORIV   Цитата(Rst7 @ Jun 22 2009, 19:40) Ну-ка н...   Jun 22 2009, 15:44
- - Rst7   ЦитатаПротив чего? Против описанного алгоритма пр...   Jun 22 2009, 15:58
- - Rst7   ЦитатаПродолжайте... Я не думаю, что нас удостоят...   Jun 22 2009, 17:18
- - Rst7   ЦитатаВы согласны, что получив результат с погрешн...   Jun 22 2009, 17:49
|- - BORIV   Цитата(Rst7 @ Jun 22 2009, 21:49) Очень с...   Jun 22 2009, 18:24
- - Rst7   ЦитатаЯ смеялся над неподходящим объяснением Прив...   Jun 22 2009, 19:09
|- - BORIV   Цитата(Rst7 @ Jun 22 2009, 23:09) Приведи...   Jun 22 2009, 21:38
- - Rst7   ЦитатаНе хочу я Вас развлекать. Сами развлекайтесь...   Jun 23 2009, 05:17
|- - BORIV   Цитата(Rst7 @ Jun 23 2009, 09:17) Вы нас ...   Jun 23 2009, 05:49
- - Rst7   ЦитатаИ всё это прекрасно видно из приведённых Вам...   Jun 23 2009, 06:57
|- - BORIV   Цитата(Rst7 @ Jun 23 2009, 10:57) Любезны...   Jun 23 2009, 10:40
- - Rst7   Последний раз спрашиваю, у Вас есть возражения к м...   Jun 23 2009, 10:49


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 02:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01565 секунд с 7
ELECTRONIX ©2004-2016