前提・実現したいこと
オシロスコープに出力された波形をdsPICでA/D変換したのち、波形の最大値を求めシリアル通信でPCに送りたいと考えています。
発生している問題・エラーメッセージ
図や動画のように計測を開始するとオシロスコープ上の波形が乱れてしまいます。
また、シリアル通信後の値も不定期に別の値に飛んでしまいます。
マイコンの割り込みによる問題が考えられますが、このような現象はあり得ますでしょうか。
###ソースコード
C言語
1#include<p30f3013.h> 2#include<dsp.h> 3#include<uart.h> 4#include<timer.h> 5#include<stdio.h> 6#include<stdlib.h> 7#include<math.h> 8#include<spi.h> 9#include<adc12.h> 10#define UART_RX_TX 0xFBE7 11#define UART_ALTRX_ALTTX 0xFFE7 12#define CLOCK 117964800 //clock=(7.3728*16)=118MHz 13#define Fcy CLOCK/4 //system clock=118/4=30MHz 14#define BAUD 115200 //最大で57600bps 15 16/*** dsPIC_config ***/ 17_FOSC(CSW_FSCM_OFF & XT_PLL16 )//XT_PLL16 or FRC_PLL8 18_FWDT(WDT_OFF) 19_FBORPOR(MCLR_EN & PBOR_OFF & PWRT_OFF) 20_FGS(CODE_PROT_OFF) 21 22/*** ハードウェアピン設定 ***/ 23#define Green LATBbits.LATB5 24#define Red LATBbits.LATB4 25#define SPI_CS LATFbits.LATF5 26#define dds_CTRL LATDbits.LATD8 27#define dds_Int LATDbits.LATD9 28#define A2 LATBbits.LATB8 29#define A1 LATBbits.LATB9 30#define A0 LATBbits.LATB7 31#define Triger LATBbits.LATB6 32 33/*** 定数定義 ***/ 34#define PI 3.141593 35 36/*** Grobal変数定義 ***/ 37unsigned long SetTime1; 38unsigned long SetTime2; 39unsigned long Fs1; 40unsigned long Fs2; 41unsigned int cmnd; 42unsigned int Data[5]; 43unsigned int Data_new; 44unsigned int Data_old; 45unsigned int TopDataV; 46unsigned int TopDataf; 47unsigned int i=0; 48unsigned int n=0; 49unsigned int fmin[100]; 50unsigned int Vmin[100]; 51unsigned int TX; 52unsigned int RX; 53unsigned int ch=1; 54unsigned int h; 55unsigned int count=0; 56unsigned int flag=0; 57unsigned int ftx=0; 58unsigned int frx=0; 59 60 61/*** ADコンバータ初期設定パラメータ(符号付固定少数で扱う) ***/ 62unsigned int Config1 = ADC_MODULE_ON & ADC_IDLE_CONTINUE & ADC_FORMAT_SIGN_FRACT & 63 ADC_CLK_AUTO & ADC_AUTO_SAMPLING_ON & ADC_SAMP_OFF; 64unsigned int Config2 = ADC_VREF_EXT_AVSS & ADC_SCAN_OFF & ADC_SAMPLES_PER_INT_1 & 65 ADC_ALT_BUF_OFF & ADC_ALT_INPUT_OFF; 66unsigned int Config3 = ADC_SAMPLE_TIME_5 & ADC_CONV_CLK_SYSTEM & 67 ADC_CONV_CLK_32Tcy; 68unsigned int ConfigPort = ENABLE_AN2_ANA; 69unsigned int ConfigScan = 0x000; 70unsigned int Channel0 = ADC_CH0_POS_SAMPLEA_AN2 & ADC_CH0_NEG_SAMPLEA_NVREF; 71 72/*** UARTの初期設定パラメータ ***/ 73unsigned int UMODEValue = UART_EN & UART_IDLE_CON & UART_ALTRX_ALTTX & 74 UART_DIS_WAKE & UART_DIS_LOOPBACK & 75 UART_DIS_ABAUD & UART_NO_PAR_8BIT & UART_1STOPBIT; 76unsigned int USTAValue = UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL & 77 UART_TX_ENABLE & UART_INT_RX_CHAR & 78 UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; 79unsigned int ubrg=(Fcy/(16*BAUD))-1; 80 81/*** SPI設定パラメータ クロック15MHz(Max20MHz) ***/ 82unsigned int SPICONValue = FRAME_ENABLE_OFF & FRAME_SYNC_INPUT & 83 ENABLE_SDO_PIN & SPI_MODE16_ON & SPI_SMP_ON & SPI_CKE_ON& 84 CLK_POL_ACTIVE_HIGH & MASTER_ENABLE_ON & 85 SEC_PRESCAL_1_1 & PRI_PRESCAL_1_1; 86unsigned int SPISTATValue = SPI_ENABLE & SPI_IDLE_CON & 87 SPI_RX_OVFLOW_CLR; 88 89 90/*** delay_ms,delay_usの作成 ***/ 91void delay_ms(unsigned int N) 92{ 93 __delay32((Fcy/1000)*N); 94} 95 96void delay_us(unsigned int N) 97{ 98 __delay32((Fcy/1000000)*N); 99} 100 101void delay_ns(unsigned int N) 102{ 103 __delay32((Fcy/1000000000)*N); 104} 105 106 107/** DDSの初期設定 **/ 108void DDSset(void) 109{ 110/* コントロールレジスタ書き込み */ 111 SPI_CS=0; 112 WriteSPI1(0x6F7); 113 delay_ns(500); 114 SPI_CS=1; 115 delay_ns(1000); 116/* 開始周波数設定 */ 117 SPI_CS=0; 118 WriteSPI1(0xC312);//LSB 119 delay_ns(500); 120 SPI_CS=1; 121 delay_ns(1000); 122 SPI_CS=0; 123 WriteSPI1(0xD008);//MSB 124 delay_ns(500); 125 SPI_CS=1; 126 delay_ns(1000); 127/* 周波数インクリメント設定 */ 128 SPI_CS=0; 129 WriteSPI1(0x20F3);//LSB 130 delay_ns(500); 131 SPI_CS=1; 132 delay_ns(1000); 133 SPI_CS=0; 134 WriteSPI1(0x3000);//MSB 135 delay_ns(500); 136 SPI_CS=1; 137 delay_ns(1000); 138/* インクリメント数設定 */ 139 SPI_CS=0; 140 WriteSPI1(0x1FA0); 141 delay_ns(500); 142 SPI_CS=1; 143 delay_ns(1000); 144/* インクリメント・インターバル設定 */ 145 SPI_CS=0; 146 WriteSPI1(0x4000); 147 delay_ns(500); 148 SPI_CS=1; 149 delay_ns(1000); 150} 151 152/***1point measure***/ 153void OnePoint(void) 154{ 155 Red=0; 156 WriteUART1((unsigned int)(0x02)); 157 while(BusyUART1()); 158for(h=1; h<=2; h++) 159 { 160 WriteUART1((unsigned int)(0x41+((Vmin[h]>>12) & 0x000F))); 161 while(BusyUART1()); 162 WriteUART1((unsigned int)(0x41+((Vmin[h]>>8) & 0x000F))); 163 while(BusyUART1()); 164 WriteUART1((unsigned int)(0x41+((Vmin[h]>>4) & 0x000F))); 165 while(BusyUART1()); 166 WriteUART1((unsigned int)(0x41+((fmin[h]>>8) & 0x000F))); 167 while(BusyUART1()); 168 WriteUART1((unsigned int)(0x41+((fmin[h]>>4) & 0x000F))); 169 while(BusyUART1()); 170 WriteUART1((unsigned int)(0x41+((fmin[h]>>0) & 0x000F))); 171 while(BusyUART1()); 172 } 173 WriteUART1((unsigned int)(0x03)); 174 while(BusyUART1()); 175 CRLF(); 176 Red=1; 177} 178 179/***復帰改行関数***/ 180void CRLF(void) 181{ 182 WriteUART1((unsigned int)(0x0a)); 183 while(BusyUART1()); 184 WriteUART1((unsigned int)(0x0d)); 185 while(BusyUART1()); 186} 187 188void dtime (void){delay_ns(1000);} 189 190/*** タイマ1 割り込み処理関数 ***/ 191void __attribute__((__interrupt__, __shadow__))_T1Interrupt(void) 192{ 193 IFS0bits.T1IF=0;//割込みフラグクリア 194 OnePoint();//1point送信 195} 196 197/*** タイマ2 割り込み処理関数 ***/ 198void __attribute__((__interrupt__, __shadow__))_T2Interrupt(void) 199{ 200 201 IFS0bits.T2IF=0;//割込みフラグクリア 202 dds_CTRL=1; 203 delay_ns(200); 204 dds_CTRL=0; 205 SigIn[0] = ReadADC12(0);// Input to A/D converter () 206 Data_new = SigIn[0]+0x8000;//0~FFFFで与える 207 n=n+1; 208 209 // 最大値検出(トーナメント) // 210 if(Data_new > TopDataV) 211 { 212 TopDataV = Data_new; 213 TopDataf = n; 214 } 215 216/*** 掃引終了判定* **/ 217 if(n>=4000) 218 { 219 Green=1; 220 count=count+1; 221 Vmin[count]=TopDataV; 222 fmin[count]=TopDataf; 223 TopDataV=0; 224 TopDataf=0; 225 226 dds_Int=1; 227 delay_ns(200); 228 n=0; 229 dds_Int=0; 230 231 } 232} 233 234/*** メイン関数 ***/ 235void main(void) 236{ 237 /// UART初期設定 238 OpenUART1(UMODEValue,USTAValue,ubrg); 239 IPC2bits.U1TXIP=5; 240 IPC2bits.U1RXIP=6; 241 242 /// PORT初期設定 243 ADPCFG=0xFFFF;//アナログなし 244 TRISB=0x0007;//0,1,2入力用,他出力用 245 TRISF=0x0000;//RF(2,3,6)SPI出力用 246 TRISD=0x0000;//RD8-SPI出力,RD9-INT0入力用 247 TRISC=0x1000;//UARTRX用(RC13=High) 248 PORTB=0xFFFF;//all LED off 249 PORTF=0xFFFF;//RF3=High 250 PORTD=0xFFFF;//RD8=High 251 252 /// Open SPI クロック 30MHz/1=30MHz(33ns) 253 OpenSPI1(SPICONValue,SPISTATValue); 254 INTCON1bits.NSTDIS=1;//多重割り込み禁止 255 SPI_CS=1; 256 dds_CTRL=1; 257 258 /** DDSの初期設定 **/ 259 DDSset(); 260 dds_Int=0; 261 CloseSPI1(); 262 263 /// ADC初期設定 264 OpenADC12(Config1,Config2,Config3,ConfigPort,ConfigScan); 265 SetChanADC12(Channel0); 266 267 ///DDS tart 268 //タイマ2設定,OPEN 269 Fs2=240000;//Tscan=0.2s_20000,Tscan=0.05s_80000 270 SetTime2 = ((Fcy/Fs2)+1); 271 OpenTimer2(T2_ON & T2_GATE_OFF & T2_PS_1_1 & T2_SOURCE_INT , SetTime2); 272 ConfigIntTimer2(T2_INT_PRIOR_3 & T2_INT_ON); 273 274 while(1) 275 { 276 while(!DataRdyUART1()); 277 cmnd = ReadUART1(); 278 ///受信コマンドの処理 279 switch(cmnd) 280 { 281 case'1': 282 283 ///1point measure 284 OnePoint(); 285 break; 286 287 case'2': 288 289 break; 290 291 default : break; 292 } 293 294 } 295 296}
試したこと
最大値を求めるアルゴリズムを変更してみました。
しかし、根本を解決しないことには問題であると考えます。
補足情報(FW/ツールのバージョンなど)
4ピンへの入力回路:TIAによる電流電圧変換、包絡線検波回路による搬送波除去
STコネクタより波形発生器で生成された交流電圧の周波数を掃引
###回路動作
①波形発生器から一定範囲(1M~3MHz)の交流電圧の周波数を掃引、STより出力する
②モノがその電流を受け取った際、アナログ素子として回路上に設置したコイルとモノの抵抗、静電容量によって共振回路が生成され、STから出力された周波数を用いて共振点(オシロスコープの波形の最大値)が検出される。
③RX部分から共振点が決まった波形が入力され、12bitのA/D変換を行った後、A/D変換の最大値を求め、Bluetooth通信でPCに送信する。
回答3件
あなたの回答
tips
プレビュー