質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

0回答

1858閲覧

dspicを用いた計測を行う際にノイズが乗る問題

sotooki

総合スコア15

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2017/12/05 07:52

編集2022/01/12 10:55

###前提・実現したいこと
dspic、波形発生器(AD5932)を用いて計測をノイズなく行おうとしてます。

###発生している問題・エラーメッセージ
単にオシロスコープを用いて信号波形を確認してもノイズなくきれいに信号が送れています。
しかし、USBを介してSPI通信をPCと開始するとpicからAD5932のCTRLに送る信号に乱れが生じ、AD5932の生成波形にも影響(波形がひずむ)がおよび、PCに正しい計測結果が得られず困っています。

イメージ説明
イメージ説明
###該当のソースコード

#include<p30f3013.h> #include<dsp.h> #include<uart.h> #include<timer.h> #include<stdio.h> #include<stdlib.h> #include<math.h> #include<spi.h> #include<adc12.h> #define UART_RX_TX 0xFBE7 #define UART_ALTRX_ALTTX 0xFFE7 #define CLOCK 117964800 //clock=(7.3728*16)=118MHz #define Fcy CLOCK/4 //system clock=118/4=30MHz #define BAUD 115200 /*** dsPIC_config ***/ _FOSC(CSW_FSCM_OFF & XT_PLL16 ) _FWDT(WDT_OFF) _FBORPOR(MCLR_EN & PBOR_OFF & PWRT_OFF) _FGS(CODE_PROT_OFF) /*** ハードウェアピン設定 ***/ #define Green LATBbits.LATB5 #define Red LATBbits.LATB4 #define SPI_CS LATFbits.LATF5 #define dds_CTRL LATDbits.LATD8 #define dds_Int LATDbits.LATD9 #define Triger LATBbits.LATB6 /*** 定数定義 ***/ #define PI 3.141593 /*** Grobal変数定義 ***/ unsigned long SetTime1; unsigned long SetTime2; unsigned long Fs1; unsigned long Fs2; unsigned int cmnd; unsigned int Data[5]; unsigned int Data_new; unsigned int Data_old; unsigned int TopDataV; unsigned int TopDataf; unsigned int i=0; unsigned int n=0; unsigned int fmin[100]; unsigned int Vmin[100]; unsigned int TX; unsigned int RX; unsigned int ch=1; unsigned int h; unsigned int count=0; unsigned int flag=0; unsigned int ftx=0; unsigned int frx=0; /*** ADコンバータ初期設定パラメータ(符号付固定少数で扱う) ***/ unsigned int Config1 = ADC_MODULE_ON & ADC_IDLE_CONTINUE & ADC_FORMAT_SIGN_FRACT &ADC_CLK_AUTO & ADC_AUTO_SAMPLING_ON & ADC_SAMP_OFF; unsigned int Config2 = ADC_VREF_EXT_AVSS & ADC_SCAN_OFF & ADC_SAMPLES_PER_INT_1 & ADC_ALT_BUF_OFF & ADC_ALT_INPUT_OFF; unsigned int Config3 = ADC_SAMPLE_TIME_5 & ADC_CONV_CLK_SYSTEM &ADC_CONV_CLK_32Tcy; unsigned int ConfigPort = ENABLE_AN2_ANA; unsigned int ConfigScan = 0x000; unsigned int Channel0 = ADC_CH0_POS_SAMPLEA_AN2 & ADC_CH0_NEG_SAMPLEA_NVREF; /*** UARTの初期設定パラメータ ***/ unsigned int UMODEValue = UART_EN & UART_IDLE_CON & UART_ALTRX_ALTTX &UART_DIS_WAKE & UART_DIS_LOOPBACK &UART_DIS_ABAUD & UART_NO_PAR_8BIT & UART_1STOPBIT; unsigned int USTAValue = UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL &UART_TX_ENABLE & UART_INT_RX_CHAR &UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; unsigned int ubrg=(Fcy/(16*BAUD))-1; /*** SPI設定パラメータ クロック15MHz(Max20MHz) ***/ unsigned int SPICONValue = FRAME_ENABLE_OFF & FRAME_SYNC_INPUT &ENABLE_SDO_PIN & SPI_MODE16_ON & SPI_SMP_ON & SPI_CKE_ON& CLK_POL_ACTIVE_HIGH & MASTER_ENABLE_ON & SEC_PRESCAL_1_1 & PRI_PRESCAL_1_1; unsigned int SPISTATValue = SPI_ENABLE & SPI_IDLE_CON & SPI_RX_OVFLOW_CLR; /*** delay_ms,delay_usの作成 ***/ void delay_ms(unsigned int N) { __delay32((Fcy/1000)*N); } void delay_us(unsigned int N) { __delay32((Fcy/1000000)*N); } void delay_ns(unsigned int N) { __delay32((Fcy/1000000000)*N); } /** DDSの初期設定 **/ void DDSset(void) { /* コントロールレジスタ書き込み */ SPI_CS=0; WriteSPI1(0x6F7); delay_ns(500); SPI_CS=1; delay_ns(1000); /* 開始周波数設定 */ SPI_CS=0; WriteSPI1(0xCD1B);//LSB delay_ns(500); SPI_CS=1; delay_ns(1000); SPI_CS=0; WriteSPI1(0xD000);//MSB delay_ns(500); SPI_CS=1; delay_ns(1000); /* 周波数インクリメント設定 */ SPI_CS=0; WriteSPI1(0x20FB);//LSB delay_ns(500); SPI_CS=1; delay_ns(1000); SPI_CS=0; WriteSPI1(0x3000);//MSB delay_ns(500); SPI_CS=1; delay_ns(1000); /* インクリメント数設定 */ SPI_CS=0; WriteSPI1(0x1FA0); delay_ns(500); SPI_CS=1; delay_ns(1000); /* インクリメント・インターバル設定 */ SPI_CS=0; WriteSPI1(0x4000); delay_ns(500); SPI_CS=1; delay_ns(1000); } /***OnePoint***/ void OnePoint(void) { Red=0; WriteUART1((unsigned int)(0x02)); while(BusyUART1()); for(h=1; h<=2; h++) { WriteUART1((unsigned int)(0x41+((Vmin[h]>>12) & 0x000F))); while(BusyUART1()); WriteUART1((unsigned int)(0x41+((Vmin[h]>>8) & 0x000F))); while(BusyUART1()); WriteUART1((unsigned int)(0x41+((Vmin[h]>>4) & 0x000F))); while(BusyUART1()); WriteUART1((unsigned int)(0x41+((fmin[h]>>8) & 0x000F))); while(BusyUART1()); WriteUART1((unsigned int)(0x41+((fmin[h]>>4) & 0x000F))); while(BusyUART1()); WriteUART1((unsigned int)(0x41+((fmin[h]>>0) & 0x000F))); while(BusyUART1()); } WriteUART1((unsigned int)(0x03)); while(BusyUART1()); CRLF(); Red=1; } /***復帰改行関数***/ void CRLF(void) { WriteUART1((unsigned int)(0x0a)); while(BusyUART1()); WriteUART1((unsigned int)(0x0d)); while(BusyUART1()); } /*** タイマ2 割り込み処理関数 ***/ void __attribute__((__interrupt__, __shadow__))_T2Interrupt(void) { IFS0bits.T2IF=0;//割込みフラグクリア dds_CTRL=1; delay_ns(200); dds_CTRL=0; SigIn[0] = ReadADC12(0);// Input to A/D converter () Data_new = SigIn[0]+0x8000;//0~FFFFで与える n=n+1; // 最大値検出(トーナメント) // if(Data_new > TopDataV) { TopDataV = Data_new; TopDataf = n; } /*** 掃引終了判定* **/ if(n>=4000) { Green=1; count=count+1; Vmin[count]=TopDataV; fmin[count]=TopDataf; TopDataV=0; TopDataf=0; // swiching // if(TX==1 && RX==1){TX4();TX=4;RX2();RX=2;delay_ms(5);} else if(TX==4 && RX==2){TX1();TX=1;RX1();RX=1;delay_ms(5);ftx=1;} if(ftx==1){ftx=0;count=0;} dds_Int=1; delay_ns(200); n=0; dds_Int=0; } } /*** メイン関数 ***/ void main(void) { /// UART初期設定 OpenUART1(UMODEValue,USTAValue,ubrg); IPC2bits.U1TXIP=5; IPC2bits.U1RXIP=6; /// PORT初期設定 ADPCFG=0xFFFF;//アナログなし TRISB=0x0007;//0,1,2入力用,他出力用 TRISF=0x0000;//RF(2,3,6)SPI出力用 TRISD=0x0000;//RD8-SPI出力,RD9-INT0入力用 TRISC=0x1000;//UARTRX用(RC13=High) PORTB=0xFFFF;//all LED off PORTF=0xFFFF;//RF3=High PORTD=0xFFFF;//RD8=High /// Open SPI クロック 30MHz/1=30MHz(33ns) OpenSPI1(SPICONValue,SPISTATValue); INTCON1bits.NSTDIS=1;//多重割り込み禁止 SPI_CS=1; dds_CTRL=1; /** DDSの初期設定 **/ DDSset(); dds_Int=0; CloseSPI1(); /// ADC初期設定 OpenADC12(Config1,Config2,Config3,ConfigPort,ConfigScan); SetChanADC12(Channel0); ///DDS start //タイマ2設定,OPEN Fs2=240000; SetTime2 = ((Fcy/Fs2)+1);//((30MHz/240000) + 1) OpenTimer2(T2_ON & T2_GATE_OFF & T2_PS_1_1 & T2_SOURCE_INT , SetTime2); ConfigIntTimer2(T2_INT_PRIOR_4& T2_INT_ON); ///OnePoint();動作(0.05秒間隔) OpenTimer1(T1_ON & T1_GATE_OFF & T1_PS_1_256 & T1_SOURCE_INT , 5769);//50ms毎 ConfigIntTimer1(T1_INT_PRIOR_3 & T1_INT_ON); while(1) { if(DataRdyUART1()){ cmnd = ReadUART1(); } } } /*** タイマ1 割り込み処理関数 ***/ void __attribute__((__interrupt__, __shadow__))_T1Interrupt(void) { IFS0bits.T1IF=0;//割込みフラグクリア if(cmnd =='1') {OnePoint();}//1point送信 }

###試したこと
ノイズ対策に配線をいろいろ工夫しましたが解決せず、プログラムの問題であると考えています。

###補足情報(言語/FW/ツール等のバージョンなど)
C言語
dspic
波形発生器(AD5932)
SPI通信

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2017/12/05 08:05

「CTRLに送る信号に乱れが生じ」電位が乱れるのか意図しないタイミングで信号送ってしまうのかどちらですか?
sotooki

2017/12/05 09:02

質問ありがとうございます!電位のトップを測定しSPI通信でPCに結果を送っているのですが、電位の乱れによりトップがひずんでしまい、結果計測値がおかしくなります。
ozwk

2017/12/07 08:13

通信はするが、CTRLは何もいじらないコードにするとどうなります?
ozwk

2017/12/07 08:17

PC<->PIC間の通信が問題なのかPIC<->AD5932間の通信が問題なのか切り分けられますか?
sotooki

2017/12/08 06:40 編集

回答ありがとうございます。波形発生を外部のファンクションジェネレーターを用いて計測を試みてみましたがノイズが見られたため、PC↔PIC間の通信に問題があるのではないかと考えております。
ozwk

2017/12/08 06:45

外部のジェネレータに対してPICは何もしておらず、PICとPC間の通信内容にかかわらず乱れるなら、ソフトの問題ではなく電気的な問題になるのですが、そのあたりどうですか?
ozwk

2017/12/11 05:26

貼られた画像は何をどうやって測定したものですか?
sotooki

2017/12/11 06:36 編集

グラフの計測画像は包絡線検波回路を用いて計測値の包絡線を取り出し、包絡線のピーク値を計測値としてSPI通信を用いてVBのプログラムに取り込み、エクセルで出力した値です。
sotooki

2017/12/11 06:38 編集

以下のプログラムを用いて4000点比較しながらピーク値を求めています。/*** 掃引終了判定* **/ if(n>=4000) { Green=1; count=count+1; Vmin[count]=TopDataV; fmin[count]=TopDataf; TopDataV=0; TopDataf=0; // swiching // if(TX==1 && RX==1){TX4();TX=4;RX2();RX=2;delay_ms(5);} else if(TX==4 && RX==2){TX1();TX=1;RX1();RX=1;delay_ms(5);ftx=1;} if(ftx==1){ftx=0;count=0;} dds_Int=1; delay_ns(200); n=0; dds_Int=0; } }
sotooki

2017/12/11 07:16

ピークの値とその前後を併せて3点の平均で出力する方法が得策かと考えました。しかし、どのようにプログラムを書けばよいかわからず困っております。よろしければ教えていただけないでしょうか。データ処理に関するプログラムは/***タイマ2 割り込み処理関数のところです***/
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問