AM中波放送用SDR.CICフィルタのみを使用.CQ出版社「トランジスタ技術」誌,2021年4月号に掲載

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //-------------------------------------------------------------
00002 //  中波 AM 放送用 SDR,CIC フィルタを使用
00003 //
00004 //      ダウンサンプリング(1/90)で使う LPF として CIC フィルタを使用
00005 //
00006 //      入力ピン: A1
00007 //      出力ピン: A2
00008 //
00009 //  2021/12/01, Copyright (c) 2021 MIKAMI, Naoki
00010 //-------------------------------------------------------------
00011 
00012 #include "F446_ADC_Intr.hpp"    // ADC
00013 #include "F446_DAC.hpp"         // DAC
00014 #include "QuadOscIir.hpp"       // 直交信号発生器
00015 #include "Cic3Stage.hpp"        // 3段 CIC フィルタ
00016 #include "Iir1st.hpp"           // 一次の IIR フィルタ
00017 #include "InitialMessage.hpp"   // 最初のメーッセージ
00018 using namespace Mikami;
00019 #pragma diag_suppress 870   // マルチバイト文字使用の警告抑制のため
00020 
00021 const float FS_ = 900.0f;       // 標本化周波数,単位: kHz
00022 const float T0_ = 1000/FS_;     // 標本化間隔,単位:μs
00023 const float A0_ = 8192;         // 直交信号発生器の出力の振幅
00024 
00025 // 各放送局の搬送波の周波数,単位: Hz
00026 const float F_C_[] = {  594.0e3f,   // NHK 第1
00027                         693.0e3f,   // NHK 第2
00028                         810.0e3f,   // AFN Tokyo
00029                         954.0e3f,   // TBS ラジオ
00030                        1134.0e3f,   // 文化放送
00031                        1242.0e3f,   // ニッポン放送
00032                        1422.0e3f};  // ラジオ日本
00033 
00034 AdcF446_Intr adc_(FS_, A1);         // ADC オブジェクトの宣言
00035 DacF446 dac_;                       // DAC オブジェクトの宣言
00036 Serial pc_(USBTX, USBRX);           // ターミナルに対する受信割込み用
00037 
00038 QuadOscIir nco_(F_C_[0], T0_, A0_); // NCO (numerically controlled oscillator)
00039 
00040 Iir1st comp_(-0.525f);              // CIC フィルタの補償用フィルタ
00041 Iir1st averaging_(0.9995f);         // 直流分を求めるためのフィルタ
00042 
00043 const int DS_RATE_ = 90;            // 1/90 にダウンサンプリング
00044 Cic3Stage cic3I_(DS_RATE_, A0_);    // CIC フィルタ,I 信号用
00045 Cic3Stage cic3Q_(DS_RATE_, A0_);    // CIC フィルタ,Q 信号用
00046 
00047 // AD 変換終了割り込みに対する割り込みサービス・ルーチン
00048 void AdcIsr()
00049 {
00050     static int count = 0;
00051 
00052     float xn = adc_.Read();     // ADC の読込み
00053     float sinX, cosX;
00054     nco_.Generate(sinX, cosX);  // sin, cos 発生
00055 
00056     // cos/sin を乗算したデータに対する CIC フィルタの積分処理
00057     cic3I_.Integrate((int16_t)(xn*cosX));   // I 信号用
00058     cic3Q_.Integrate((int16_t)(xn*sinX));   // Q 信号用
00059 
00060     if (++count >= DS_RATE_)
00061     {
00062         count = 0;
00063         NVIC->STIR = EXTI4_IRQn;    // ソフトウェア割り込み発生
00064     }
00065 }
00066 
00067 // ダウンサンプラより後の処理に対する割り込みサービス・ルーチン
00068 void SwiIsr()
00069 {
00070     // CIC フィルタのくし形フィルタの部分による処理
00071     float yI_n = cic3I_.CombFilter();   // くし形フィルタ処理で I 信号を生成
00072     float yQ_n = cic3Q_.CombFilter();   // くし形フィルタ処理で Q 信号を生成
00073 
00074     float yn = sqrtf(yI_n*yI_n + yQ_n*yQ_n);    // 包絡線成分を求める
00075     yn = comp_.Execute(yn);             // 補償フィルタ
00076     float dc = averaging_.Execute(yn);  // 直流分を求める
00077     yn = yn - dc;   // 直流分除去
00078 
00079     float gain = 0.8f/dc;               // AGC 処理の準備
00080     if (gain > 200.0f) gain = 200.0f;
00081 
00082     dac_.Write(gain*yn);
00083 }
00084 
00085 // シリアル・ポートの受信割込みに対する割り込みサービス・ルーチン
00086 void RxIsr()
00087 {
00088     unsigned char chr = pc_.getc();
00089     // 受信した文字が '0' ~ '6' の場合のみ NCO の周波数を変える
00090     if (('0' <= chr) && (chr <= '6'))
00091     {
00092         nco_.Set(F_C_[chr & 0x07]);
00093         pc_.putc(chr);   // エコーバック
00094     }
00095     if (chr == '\r') pc_.printf("\r\n");
00096 }
00097 
00098 int main()
00099 {
00100     InitialMessage("ダウンサンプリングに CIC フィルタを使用.", AM, pc_);
00101 
00102     NVIC_SetPriority(ADC_IRQn,    0);   // 最優先
00103     NVIC_SetPriority(EXTI4_IRQn,  1);   // 2番目に優先
00104     NVIC_SetPriority(USART2_IRQn, 2);   // 3番目に優先
00105 
00106     // ADC に対する割り込みサービス・ルーチンの設定
00107     adc_.SetIntrVec(&AdcIsr);
00108 
00109     // EXTI4 によるソフトウェア割り込みに対応する設定
00110     NVIC_SetVector(EXTI4_IRQn, (uint32_t)SwiIsr);
00111     NVIC_EnableIRQ(EXTI4_IRQn);
00112 
00113     // シリアル・ポートの受信割込みの設定
00114     pc_.format();    // default: 8 bits, nonparity, 1 stop bit
00115     pc_.attach(&RxIsr);
00116 
00117     while (true) {}
00118 }