Как я могу сдвинуть сигнал на 90 градусов, используя круговой буфер

Я пытаюсь запрограммировать DSP (TMSF28335), используя код C в Control Studio V6.02.

В этом проекте мне нужно сделать сдвиг фазы на 90 градусов для сигнала переменного тока, который я измеряю датчиками. Мне посоветовали использовать кольцевой буфер, чтобы сделать такой фазовый сдвиг. Но, к сожалению, я не очень хорошо знаком с тем, как написать циклический буфер на языке Си. Согласно концепции, я знаю, что "голова" буфера должна быть входным сигналом (измеренный сигнал переменного тока), а "хвост" - это сдвинутый входной сигнал, который используется в качестве выходного сигнала кольцевого буфера.

Время выборки системы установлено на 3,84599989e-5 (с), а один период равен 0,02 (с) (50 Гц). Таким образом, 1/4 периода составляет (0,02/4)/3,84599989e-5=130 выборок. Другими словами, мне нужно сделать задержку на 130 сэмплов.

Буду признателен, если подскажете, как написать циклический буфер на C для моего контроллера и соответственно сделать фазовую задержку.


person Foad    schedule 11.08.2017    source источник
comment
Найдите учебник по круговым буферам. Научитесь реализовывать и использовать их на простых примерах. Затем узнайте точный период вашего сигнала. Затем сохраните четверть этого расстояния между входом и выходом. В качестве альтернативы (в случае непостоянного периода) вам придется динамически определять, что означает 90 градусов для вашего сигнала в любой момент времени.   -  person Yunnosch    schedule 11.08.2017
comment
Вам нужен цифровой фильтр (либо FIR, либо IIR), и для его реализации следует использовать кольцо буфер, это правильно до сих пор. Я бы использовал фильтр Гильберта, так как это преобразовало бы cos(ωt) в sin(ωt), что является сдвигом на 90°. См.: en.wikipedia.org/wiki/Hilbert_transform для математического объяснения, вам нужны знания о комплексные числа для этого. Этот вопрос должен быть лучше здесь: dsp.stackexchange.com. В дальнейшем я бы рекомендовал обучать такие вещи, как цифровая обработка сигналов в Matlab. Он отлично подходит для этой цели!   -  person Andre Kampling    schedule 11.08.2017
comment
Но чтобы ответить на ваш вопрос о круговых буферах, это очень общий вопрос: stackoverflow.com/a/827749/8051589. Здесь в одном для реализации КИХ-фильтра: фильтр в c">stackoverflow.com/questions/22749058/. В интернете много чего можно найти.   -  person Andre Kampling    schedule 11.08.2017


Ответы (1)


Что вам нужно, так это специальная реализация циклического буфера, называемого линией задержки. Вот простая (быстрая, грязная и несколько наивная) реализация.

Обратите внимание, что это может дать вам фиксированный фазовый сдвиг, только если входная частота постоянна.

typedef short Sample;  //  change to whatever your sample data is...

#define DELAY (130)

struct DelayLine               // <- make sure you initialize the entire struct
{                              // with zeroes before use !
    Sample buffer[DELAY + 1];
    int next;                  
};

Sample tick(DelayLine* effect, Sample sampleIn)
{
    // call for each sample received, returns the signal after delay

    int nextOut = effect->next + DELAY;  // note that this delay could be anything
                                         // shorter than the buffer size.
    if (nextOut >= DELAY + 1)   // <-- but not this one!!!
        nextOut -= DELAY + 1;

    effect->buffer[effect->next] = sampleIn;

    if (++(effect->next) >= DELAY + 1)
        effect->next = 0;

    return effect->buffer[nextOut];
}
person Michaël Roy    schedule 11.08.2017
comment
Спасибо за ответ. Пробовал коды в CC6. Мои образцы данных являются плавающими. Поэтому я изменил тип int на float. Ошибка, которую я получил, была в строках effect-›buffer[effect-›next] = sampleIn; и return effect-›buffer[nextOut] с сообщением, что выражение должно иметь тип integer или enum. Не могли бы вы помочь мне, как мне переставить коды, чтобы входной сигнал буфера (sampleIn) принимался как файл типа float? - person Foad; 12.08.2017
comment
индексы next``nextOut и nextIn являются типами int несмотря ни на что. для образцов с плавающей запятой вам нужно только изменить typedef Sample int на typedef Sample float в приведенном выше примере. - person Michaël Roy; 12.08.2017
comment
Извините, я заметил ошибку в коде. Я исправил это. - person Michaël Roy; 13.08.2017