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

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

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

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

Q&A

解決済

3回答

788閲覧

マイコンを用いたA/D変換後のシリアル通信時の波形の乱れ

sotooki

総合スコア15

C

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

0グッド

0クリップ

投稿2018/06/08 07:01

編集2018/06/08 08:21

前提・実現したいこと

オシロスコープに出力された波形を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による電流電圧変換、包絡線検波回路による搬送波除去

イメージ説明
dsPIC周辺

イメージ説明
STコネクタより波形発生器で生成された交流電圧の周波数を掃引

###回路動作
①波形発生器から一定範囲(1M~3MHz)の交流電圧の周波数を掃引、STより出力する
②モノがその電流を受け取った際、アナログ素子として回路上に設置したコイルとモノの抵抗、静電容量によって共振回路が生成され、STから出力された周波数を用いて共振点(オシロスコープの波形の最大値)が検出される。
③RX部分から共振点が決まった波形が入力され、12bitのA/D変換を行った後、A/D変換の最大値を求め、Bluetooth通信でPCに送信する。

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

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

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

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

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

yoorwm

2018/06/08 07:09

アナログ波形にノイズが乗るとか普通にある事だと思いますが。
sotooki

2018/06/08 07:16

シリアル通信動作時にオシロスコープ上で波形が不自然な形になるのはなぜでしょうか。
y_waiwai

2018/06/08 07:25

アナログ入力回路周りがなにか間違えてるように思いますが
sotooki

2018/06/08 07:29

PORT初期設定の部分ということでしょうか?
y_waiwai

2018/06/08 07:31

それはもちろんのこと、入力回路はどうなってる?
sotooki

2018/06/08 07:46

11,12ピンにUART用Bluetoothモジュール・14,15,16,17,21ピンにプログラマブル周波数スキャン波形発生器・23,24,25ピンにチャンネル変更マルチプレクサ・4ピンに入力波形が入ってきます
sotooki

2018/06/08 07:47

計測したい波形は4ピンから入ってきてフィルタ処理されたのち、A/D変換が行われます。
y_waiwai

2018/06/08 07:48

信号源からA/D入力ピンに至る回路図が見たいんだがw
sotooki

2018/06/08 07:57

失礼いたしました。入力信号の配線にはGNDシールディング等のノイズ対策は行っております。
coco_bauer

2018/06/08 07:57

オシロスコープ上の波形というのは、どこ(どのような機器)から出力された信号のもので、信号源、dsPIC、PC(シリアル通信でdsPICと接続されている)、オシロスコープなどの機器がどのように接続されているのか判らないので、状況が把握できません。 また、波形が乱れるという現象は、アースの取り方、配線の引き回しなどに影響を受けていますか?
ozwk

2018/06/08 08:07

プログラマブル周波数スキャン波形発生器とやらに何をどう使っていますか? picから一定周期でパルス与えないと動かなかったりするやつだったりしませんか?
sotooki

2018/06/08 08:23

補足させていただきました。オシロスコープは入力回路のENVタグで計測しています。
ozwk

2018/06/08 08:35

原理的に、波形発生機の周波数がインクリメントされない期間があると、観測波形に平坦な部分ができますか?
sotooki

2018/06/08 08:53

はい、メイン関数で周波数発生の割り込みタイミングを決めています。
guest

回答3

0

パッと絵を見た感じでは、A/Dからデータ取り込みに失敗しています。データを取りこぼしているように見えます。

1sec ぶんだけまとめてデータ処理する仕様として、1secのデータをCPUが処理している間もデータ取り込みを並行して行う必要があります。
その並行処理がうまくできていないために、取りこぼしがあり、結果が不連続になっています。
測定開始0.0secから1.0を取り込み、処理している途中、1.0後から1.2はデータを取りこぼし、再び1.2から2.2secの部分を取り込む..
みたいな。

対策としては、

  1. とにかく長い今のプログラムを1/10くらいの長さを目標に短くする。
  2. 実際に取り込めたデータの総サンプル数が、サンプル期間とあっているか考える。
  3. データ取り込みの割り込み処理がメインタスクの影響を受けていないかデバッグする。

投稿2018/06/08 23:03

編集2018/06/08 23:09
gm300

総合スコア580

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

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

0

ベストアンサー

波形が平らな部分が出るのをどうにかしたいという話だとして、
波形が平らになるには波形発生機の周波数インクリメントが止まっているはずで、
その波形発生機の周波数インクリメントはT2の割り込みでやっているので、
割り込みが何らかの理由で発生していないんでしょう。

で、UARTが動いていると波形が平らな部分がたまに出るということなので(ですよね?)
そのあたりをよく見直してください。
正直コード見てても結果をPCに送るタイミングが測定と全然同期していないように見えます。

投稿2018/06/08 09:13

ozwk

総合スコア13521

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

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

sotooki

2018/06/08 09:15

確かに、波形発生器をオシロスコープで観察すると高周波なので見にくいですが、挙動がおかしい部分が見受けられます。 確認させていただきます。
guest

0

まず、dsPICのデータシートを見ると、A/D入力ピンは、アナログSWを介した後、直接S/H回路に入っていることが見て取れます。
で、このおかげで信号源インピーダンスは最大2.5KΩと規定されているようです

ということで、この入力回路では、A/Dの動作状況によって、入力電圧が振られてしまうのは想像に難くありません

で、不定期に別の値に飛ぶというのも、なにか動作不良を匂わせるものなので、まずはソフト面から、この別の値に飛ぶバグを潰してしまいましょう
#もしかしたらこのバグで波形が乱れているということも考えられる

ここらへんをしっかりデバッグし、出力数値も入力電圧に追従している、という状況にした後、この波形が乱れるというのをどうにかすることにしましょう

投稿2018/06/08 08:24

y_waiwai

総合スコア87774

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

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

sotooki

2018/06/08 09:28

やはりデータシートを見ないといけないですね(笑) 正直、マイコンの動作が理解できていないのも問題かと思います。 身につくように取り組みたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問