Transistor Gijutsu, October 2014, Special Features Chapter 9, Software of the Function Generator トランジスタ技術2014年10月号 特集第9章のソフトウェア わがまま波形発生器のソフトウェア
DDS.cpp
00001 #include "mbed.h" 00002 #include "USBSerial.h" 00003 #include "DDS.h" 00004 #include "DigitalOut.h" 00005 #include "math.h" 00006 00007 DigitalOut out1(P0_2); // osc1のトリガ出力ピン 00008 DigitalOut out2(P0_23); // osc2のトリガ出力ピン 00009 00010 // 最適化指定。DDS基準周波数100kHzに必要。 00011 #pragma O3 00012 00013 // スタティック変数の領域確保 00014 int16_t DDS::waveForm1[DDS::TBLSIZE]; 00015 unsigned int DDS::phaseAcc1 = 0; 00016 unsigned int DDS::phaseInc1 = 0; 00017 unsigned int DDS::phaseShift1 = 0; 00018 int DDS::bstBgn1; 00019 int DDS::bstEnd1; 00020 int DDS::bstLen1; 00021 int DDS::bstDcL1; 00022 int DDS::trigger1; 00023 int DDS::wc1; 00024 int DDS::lp1; 00025 00026 int16_t DDS::waveForm2[DDS::TBLSIZE]; 00027 unsigned int DDS::phaseAcc2 = 0; 00028 unsigned int DDS::phaseInc2 = 0; 00029 unsigned int DDS::phaseShift2 = 0; 00030 int DDS::bstBgn2; 00031 int DDS::bstEnd2; 00032 int DDS::bstLen2; 00033 int DDS::bstDcL2; 00034 int DDS::trigger2; 00035 int DDS::wc2; 00036 int DDS::lp2; 00037 00038 00039 // 割り込みハンドラ 00040 void PWM1_IRQHandler (void) 00041 { 00042 static int pw1 = 1; 00043 static int pw2 = 1; 00044 LPC_CT32B1->IR |= 0x01; // 割り込み要因のリセット 00045 LPC_CT32B1->MR1 = pw1; // PWM1パルス幅変更 00046 LPC_CT32B1->MR2 = pw2; // PWM2パルス幅変更 00047 out1 = DDS::trigger1; // トリガパルス出力 00048 out2 = DDS::trigger2; 00049 DDS::trigger1 = 0; // トリガ要因リセット 00050 DDS::trigger2 = 0; 00051 00052 // 次のPWM幅とトリガ要因を計算 00053 pw1 = DDS::getNextPw1(); 00054 pw2 = DDS::getNextPw2(); 00055 // トリガパルス終了。パルス幅はPWM計算時間。 00056 out1 = 0; 00057 out2 = 0; 00058 } 00059 00060 // osc1次のパルス幅を得る 00061 inline int DDS::getNextPw1(void) 00062 { 00063 static int ret = 0; 00064 00065 // 位相の更新 00066 phaseAcc1 += phaseInc1; 00067 // バースト信号処理 00068 if(bstBgn1 <= wc1 && wc1 <= bstEnd1){ 00069 ret = waveForm1[(phaseAcc1 + phaseShift1)>> WFRES]; 00070 }else{ 00071 ret = bstDcL1; 00072 } 00073 if(lp1 > phaseAcc1){ 00074 // バースト出力の先頭でトリガパルスを発生する 00075 wc1++; 00076 if(wc1 > bstLen1){ 00077 wc1 = 1; 00078 trigger1 = 1; 00079 } 00080 } 00081 lp1 = phaseAcc1; 00082 00083 return ret; 00084 }; 00085 00086 // osc2次のパルス幅を得る 00087 inline int DDS::getNextPw2(void) 00088 { 00089 static int ret = 0; 00090 00091 phaseAcc2 += phaseInc2; 00092 if(bstBgn2 <= wc2 && wc2 <= bstEnd2){ 00093 ret = waveForm2[(phaseAcc2 + phaseShift2) >> WFRES]; 00094 }else{ 00095 ret = bstDcL2; 00096 } 00097 if(lp2 > phaseAcc2){ 00098 wc2++; 00099 if(wc2 > bstLen2){ 00100 wc2 = 1; 00101 trigger2 = 1; 00102 } 00103 } 00104 lp2 = phaseAcc2; 00105 return ret; 00106 }; 00107 00108 void DDS::reset(void) 00109 { 00110 // 割り込みを停止してから変数を初期化 00111 NVIC_DisableIRQ(TIMER_32_1_IRQn); 00112 phaseAcc1 = phaseAcc2 = 0; 00113 wc1 = wc2 = 1; 00114 lp1 = lp2 = 0xffffffff; 00115 NVIC_EnableIRQ(TIMER_32_1_IRQn); 00116 } 00117 00118 // osc1バースト波形の設定 00119 void DDS::burst1(int begin, int end, int length, float dcLevel) 00120 { 00121 bstBgn1 = begin; 00122 bstEnd1 = end; 00123 bstLen1 = length; 00124 bstDcL1 = WFVSPN - WFMAG * dcLevel * WFVSPN; 00125 } 00126 00127 // osc1バースト波形の設定 00128 void DDS::burst2(int begin, int end, int length, float dcLevel) 00129 { 00130 bstBgn2 = begin; 00131 bstEnd2 = end; 00132 bstLen2 = length; 00133 bstDcL2 = WFVSPN - WFMAG * dcLevel * WFVSPN; 00134 } 00135 00136 void DDS::fillTable(int16_t wftbl[], float level, float ofst, float (*wf)(float x)) 00137 { 00138 level = (level < -2.0) ? -2.0 : level; 00139 level = (level > 2.0) ? 2.0 : level; 00140 00141 for(int a = 0; a < TBLSIZE; a++){ 00142 // ラジアンを引数として関数値を計算 00143 float val = wf(2.0 * PI * a / TBLSIZE); 00144 val = (val < -1.0) ? -1.0 : val; 00145 val = (val > 1.0) ? 1.0 : val; 00146 // PWMの極性に合わせるためvalの符号を反転し、PWM値に変換 00147 //val = (level * val + ofst) * WFMAG * WFVSPN; 00148 val = (level * val + ofst) * WFMAG * WFVSPN; 00149 wftbl[a] = WFVSPN - val; 00150 } 00151 } 00152 00153 /// OSC1の波形定義 00154 void DDS::osc1(float f, float p, float level, float ofst, float (*wf)(float x)) 00155 { 00156 phaseInc1 = (PACCLEN / DDSCLK) * f; 00157 if(p < 0){ 00158 p = 360 - p; 00159 } 00160 phaseShift1 = PACCLEN * p / 360.0; 00161 fillTable(waveForm1, level, ofst, wf); 00162 } 00163 00164 /// OSC2の波形定義 00165 void DDS::osc2(float f, float p, float level, float ofst, float (*wf)(float x)) 00166 { 00167 // 位相増分 00168 phaseInc2 = (PACCLEN / DDSCLK) * f; 00169 if(p < 0){ 00170 p = 360 - p; 00171 } 00172 phaseShift2 = PACCLEN * p / 360.0; 00173 fillTable(waveForm2, level, ofst, wf); 00174 } 00175 00176 void DDS::osc1(float freq, float phase) 00177 { 00178 phaseInc1 = (PACCLEN / DDSCLK) * freq; 00179 phaseShift1 = PACCLEN * phase / 360.0; 00180 } 00181 00182 void DDS::osc2(float freq, float phase) 00183 { 00184 phaseInc2 = (PACCLEN / DDSCLK) * freq; 00185 phaseShift2 = PACCLEN * phase / 360.0; 00186 } 00187 00188 // 三角波 00189 float triangle(float x) 00190 { 00191 if(x < PI){ 00192 return 2.0 * x / PI - 1.0; 00193 }else{ 00194 return 2.0 * (2 * PI - x) / PI - 1.0; 00195 } 00196 } 00197 00198 // 三角関数の合成による三角波 00199 float triangleSin(float x) 00200 { 00201 x -= PI / 2.0; 00202 return 8.0 / PI / PI * (sin(x) - sin(3.0 * x) / 9.0 + sin(5.0 * x) / 25.0); 00203 //return 8.0 / PI / PI * (sin(x) - sin(3.0 * x) / 9.0 + sin(5.0 * x) / 25.0 - sin(7.0 * x) / 49.0 + sin(9.0 * x)/81.0); 00204 } 00205 00206 // 方形波 00207 float square(float x) 00208 { 00209 if(x < PI){ 00210 return 1.0; 00211 }else{ 00212 return -1.0; 00213 } 00214 } 00215 00216 // コンソトラクタ、ハードウエアの初期化 00217 DDS::DDS(void) 00218 { 00219 LPC_IOCON->TRST_PIO0_14 = 0x83; // P0_14 -> CT32B1_MAT1 00220 LPC_IOCON->SWDIO_PIO0_15 = 0x83; // P0_15 -> CT32B1_MAT2 00221 LPC_SYSCON->SYSAHBCLKCTRL |= 0x1 << 10; // Enable clock CT32B1 00222 LPC_CT32B1->PWMC = 0xf; // Enable MAT0..3 00223 LPC_CT32B1->MCR = 0x03; // MR0 reset & interrupt 00224 00225 LPC_CT32B1->PR = 0; 00226 LPC_CT32B1->MR0 = WFVSPN - 1; // PWM周期 00227 LPC_CT32B1->MR1 = WFVSPN / 2; // duty 50% 00228 LPC_CT32B1->MR2 = WFVSPN / 2; 00229 LPC_CT32B1->TCR = 0x02; // counter reset 00230 00231 // デフォルトのDDS波形は1kHz連続正弦波 00232 trigger1 = 0; 00233 burst1(1, 1, 1, 1.0); 00234 osc1(1000.0, 0.0, 0.5, 1.0, sin); 00235 trigger2 = 0; 00236 burst2(1, 1, 1, 1.0); 00237 osc2(2000.0, 0.0, 0.5, 1.0, sin); 00238 reset(); 00239 00240 // USB割り込みの優先順位を下げる。 00241 NVIC_SetPriority(USB_IRQn, 3); 00242 NVIC_SetPriority(USB_FIQn, 3); 00243 NVIC_SetPriority(TIMER_32_1_IRQn, 0); 00244 00245 // 割り込み処理の登録と許可 00246 NVIC_SetVector(TIMER_32_1_IRQn, (unsigned int)&PWM1_IRQHandler); 00247 NVIC_EnableIRQ(TIMER_32_1_IRQn); 00248 } 00249 00250 00251 void DDS::start(void) 00252 { 00253 LPC_CT32B1->TCR = 0x01; // counter enable 00254 } 00255 00256 void DDS::stop(void) 00257 { 00258 LPC_CT32B1->TCR = 0x02; // counter reset 00259 }
Generated on Wed Jul 13 2022 01:52:22 by 1.7.2