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

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

ただいまの
回答率

91.35%

  • C

    2525questions

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

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

受付中

回答 0

投稿 2017/12/05 16:52 ・編集 2017/12/08 15:46

flag 質問者が5日前に「まだ回答を求めています」と言っています。

  • 評価
  • クリップ 0
  • VIEW 52

sotooki

score 1

前提・実現したいこと

dspic、波形発生器(AD5932)を用いて計測をノイズなく行おうとしてます。

発生している問題・エラーメッセージ

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

イメージ説明
![イメージ説明](b1a58698a46b5221ce9ef40a7b5193db.jpeg)

該当のソースコード

#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通信

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • sotooki

    2017/12/11 15:36 編集

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

    キャンセル

  • sotooki

    2017/12/11 15: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 16:16

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

    キャンセル

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

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

ただいまの回答率

91.35%

関連した質問

  • 解決済

    linux 処理時間の表示

    C言語でLinuxを使っています。メモリを確保したりするプログラムなのですが、以下のプログラムを修正して 、5秒間で何回の入れ替えを行えるかを計測できるようにしてもらいたいです。初

  • 解決済

    Arduinoの関数を呼び出し

    実行したいこと 下記の関数をループ処理の時に実行する これは、Arduinoのスピーカーを使用して音階(ド~高いドまで)を鳴らすプログラムです。 ド~高いドまでを出力したら、

  • 受付中

    C:大きな数の計算方法,オーバーフロー回避

    C言語で3^80の計算をしたいのですが、数が大きすぎてオーバーフローしてしまいます。各桁ごとに配列を置けばいいのかとも思いましたが、いまいちよくわかりません。 解決方法が分かる方

  • 解決済

    配列の要素間の和を全パターン求めるプログラムを作成したい。

    皆様ありがとうございました。 前提・実現したいこと <CもしくはC++> 配列の要素間の和を全パターン求めるプログラムを作成したい。 【例】 /*-------------

  • 受付中

    【C言語】冗長だと思う数字入力プログラムを改善したい

    以下のプログラムは3つの数字をスペース区切りで入力して、入力した数字を改行区切りで出力するというコードです。 C言語はあまり慣れていないので、以下のコードに冗長さを感じますが何か改

  • 解決済

    char型の配列変数にchar型の変数を代入したい

    使用言語 C 環境 Visual Studio 2017 初めての質問です。 独学でプログラミングを始めたのですがわからないところがあり困っています。 char型の配列変数の使い方

  • 解決済

    無限ループしてしまうようになった

    解決したいこと 一度はうまくいったのですが、作り直したらなぜか無限ループしてしまうようになってしまいましたのですが、わかる方いますか。コンパイルも通っているのですが。 追記 #

  • 受付中

    プログラムを見やすく改良したい

    正常に動くプルグラムを見やすく改良したい。 具体的に教えていただければありがたいです。セグメンテーションフォルトでベスト7まで表示して停止します。173行あたりだと思うのですが、よ

同じタグがついた質問を見る

  • C

    2525questions

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