Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
