Frequency shifter using Weaver modulator for ST Nucleo F401RE.

Dependencies:   UITDSP_ADDA mbed

main.cpp

Committer:
MikamiUitOpen
Date:
2015-07-25
Revision:
1:013f4e5762b1
Parent:
0:c17cb8371b55

File content as of revision 1:013f4e5762b1:

//------------------------------------------------------------------------------
//  Weaver 変調器を使う周波数シフタ
//
//  200 Hz ~ 4.2 kHz の範囲の成分の周波数を 100 Hz 低い方へシフトする
//
//  SW:0 No shift, SW:1 Shift to lower
//
//  2015/07/25, Copyright (c) 2015 MIKAMI, Naoki
//------------------------------------------------------------------------------

#include "ADC_BuiltIn.hpp"      // かならず必要 
#include "DAC_MCP4922.hpp"

#include "IIR_Cascade.hpp"
#include "Coefficients.hpp"  // Coeffisients of LPF and DC-cut filter

using namespace Mikami;         // かならず必要 

const int FS_ = 10000;          // 標本化周波数: 10 kHz
ADC_BuiltIn adc_(A0, FS_);      // A5 からの入力を使うように設定
DAC_MCP4922 myDac_;             // DAC を使うための設定
DigitalIn sw_(D2, PullDown);    // ロータリ・ディップ・スイッチ用

// 入力帯域制限用帯域通過フィルタ
IIR_Cascade<ORDER_BPF_> bpf_(ckBP_, g0Bpf_);

// Weaver 変調器で使う低域通過フィルタ 
IIR_Cascade<ORDER_LPF_> lpfC_(ckLP_, g0Lpf_);
IIR_Cascade<ORDER_LPF_> lpfS_(ckLP_, g0Lpf_);

int main()
{
    myDac_.ScfClockTim3(420000);    // 出力の LPF の遮断周波数を 4.2 kHz に設定

    bpf_.Clear();
    lpfC_.Clear();
    lpfS_.Clear();

    const float PI2 = 3.1415926536f*2;
    const float FL_ = 200.0f;
    const float FH_ = 4200.0f;
    const float FC_ = (FL_ + FH_)/2.0f;             // 中心周波数
    const float DPHI1 = FC_*PI2/FS_;                // 中心周波数に対応
    const float DPHI2 = (-100.0f + FC_)*PI2/FS_;    // 中心周波数 - 100 Hz

    float phi1 = 0;
    float phi2 = 0;
    
    while (true)
    {
        float xn = adc_.Read();     // A5 からの入力信号を読み込む
        //-----------------------------------------------

        xn = bpf_.Execute(xn);    // 帯域制限
        
        float mpyC = xn*cosf(phi1);
        float mpyS = xn*sinf(phi1);
        
        // LPF
        mpyC = lpfC_.Execute(mpyC);
        mpyS = lpfS_.Execute(mpyS);
        
        mpyC = mpyC*cosf(phi2);
        mpyS = mpyS*sinf(phi2);
        
        float yn = 2.0f*(mpyC + mpyS);
        
        //-----------------------------------------------
        if (sw_ == 0) myDac_.Write(xn);    // 入力をそのまま DAC へ出力する
        else          myDac_.Write(yn);    // 処理した結果を DAC へ出力する
        
        phi1 = phi1 + DPHI1;
        if (phi1 > PI2) phi1 = phi1 - PI2;
        phi2 = phi2 + DPHI2;
        if (phi2 > PI2) phi2 = phi2 - PI2;
    }
}