不韋 呂
/
SDR_AM_Rx_CIC
AM中波放送用SDR.CICフィルタのみを使用.CQ出版社「トランジスタ技術」誌,2021年4月号に掲載
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Fri Jul 22 2022 13:23:29 by 1.7.2