マイコン(PIC)とPC間での通信について

このQ&Aのポイント
  • マイコン(PIC)とPC間での通信についての質問です。プログラムの考え方について教えてください。
  • 行いたいことは、PICのある値をTera Termを用いてシリアル通信で変化させることです。具体的には、5ケタの数値を入力する際に、「00001」ではなく、「1+[Enter]」で入力したいです。
  • 現状としては、Tera Termでの通信はできていますが、数値の入力において「015」と入力する必要があります。これをスマートにするための考え方やアルゴリズムの参考書籍やサイトについて教えていただけると助かります。
回答を見る
  • ベストアンサー

マイコン(PIC)とPC間での通信について

プログラムの考え方についての質問です。 環境: Windows環境にて、Tera Termを用いています。 PICはdsPICです。 行いたいこと: PICのある値をTera Termを用いてシリアル通信で変化させたい。 その時、5ケタの数値を入れる時に「00001」では無く、「1+[Enter]」で入力をしたい。 質問: 上記を実現する考え方を教えて頂けると幸いです。 (プログラムはもちろん自分で考えます) または、アルゴリズムの参考書籍や、参考サイト等を教えて頂けると幸いです。 書店で「アルゴリズム」の本を見ても、マイコンや組込みシステムの本が見当たりませんでした。 (私の探し方が悪いとは思うのですが・・) 現状: 1.Tera Term での通信はできています。 3桁の数値を入力し、その値が反映され、PICは動作しています。 しかし、「15」と打つ時も「015」と打っており、スマートではありません。 以下のソースの通り、1文字ずつ受信した文字を、数値に変換し、 各桁に変換しています。 /*ソース抜粋*/ putsUART1(Set_para_Adj_num); while(BusyUART1()); for(i=0;i<3;i++){ while(!U1STAbits.URXDA); // データ受信すると、「1」になるので次の行へ行く adj[i] = ReadUART1(); } for(i=0;i<3;i++){ U1_Send(adj[i]); while(BusyUART1()); } CRLF(); adj[0]=(adj[0]-'0')*100; // -'0'でASCII⇒数値への変換 adj[1]=(adj[1]-'0')*10; adj[2]=adj[2]-'0'; Adj_num=adj[0]+adj[1]+adj[2]; 2.Tera TermでのEnterキーの受信は出来ています。 0X0D (CR)を受信すると、「ENETR」が表示されることは確認できています。 下名の考え: if文で「Enterが押された時」に、今までの入力された桁数を覚えておいて、上位の桁に「0」 を代入するしかないのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8522/19371)
回答No.1

以下のように変更しましょう。 Adj_num = 0; putsUART1(Set_para_Adj_num); while(BusyUART1()); for(;;){ while(!U1STAbits.URXDA); // データ受信すると、「1」になるので次の行へ行く adj[0] = ReadUART1(); U1_Send(adj[0]); //受け取った文字をそのままエコーバックする while(BusyUART1()); if (adj[0] == 0x0d) { U1_Send(0x0a); //CRをエコーバックした後はLFもエコーバックする while(BusyUART1()); break; //Enterを受け取ったのでループを抜ける } else if ((adj[0] >= '0') && (adj[0] <= '9')) { Adj_num *= 10; Adj_num += (adj[0] - '0'); } } //Enterを受信してループを抜けた段階で、Ajd_numの中に、希望する答えが入っているので、これ以上、何もする必要はない。

Snoodam
質問者

お礼

chie65535様: ソースコードも示して頂き、ありがとうございます。 また、私の抜粋した説明不足のプログラムに、コメントまでつけて頂きありがとうございます。 惚れ惚れする洗練された、プログラムですね。 私のベタ書きが恥ずかしい限りです。 少しでもchie65535様の様なソースを書けるように様々なプログラムを読んでいきます。 本日は、PICの前にいないので、明日に試してみます。 一応頭の中で検算(chie65535様を疑っている訳でなく、コピペで終わらせない為に) したところ、 例)一回目が'5' 、二回目が'3'と打つと、53になりました。(あくまでも私の頭の中だけですが・・) また、非常に厚かましい質問ですが、 もし3桁欲しい場合はどうお考えになられますか? 単純に Adj_num *= 10;の前に Adj_num *= 100; を加えても、十の位の入力の時に値が更新されてしまいました。(あくまでも私の頭の中で) もしお時間があれば、アドバイスを頂けると幸いです。

Snoodam
質問者

補足

申し訳ございません。 おかしなことを言っていました。 Adj_num *= 100; は不要ですね。 三桁以上の場合も、chie65535様のプログラムで大丈夫ですね。 例)'1', '5', '3'と入力が来た場合 *10なので、1桁ずつシフトしていきますね。 お恥ずかしい限りです。

関連するQ&A

  • Tera Termを使ったマイコンとの通信

    H8/3048Fと通信をしようと思い、「Tera Term」を使ってみたのですが、 下のプログラムを実行してもTera Termに何も表示されません(COMの番号はしっかり確認しました) while( 1 ){ ITU0.TCNT = 0; while( ITU0.TCNT < 40000 ); counter++; if( counter > 100 ){ if( P4DR == 0x00 ){ //LEDを点滅させる(確認用) P4DR = 0x10; } else{ P4DR = 0x00; } while( ( SCI0.SSR.BYTE & 0x80 ) == 0 ); SCI0.TDR = 'A'; //Aを送信する SCI0.SSR.BYTE &= ~0x80; counter = 0; } } SCI0の設定は int i; SCI0.SCR.BYTE = 0x00; SCI0.SMR.BYTE = 0x00; SCI0.BRR = 51; for( i = 0 ; i < 1000 ; i++); i = SCI0.SSR.BYTE; SCI0.SSR.BYTE = 0x80; SCI0.SCR.BYTE = 0x30; となっております。 このプログラムを実行すると確認用のLEDは点滅しますが、Tera Termには何も表示されません。 どこか間違っているところなどがあれば教えていただけないでしょうか? ちなみに、使用しているOSはWindows7です。 よろしくお願いします。

  • PICのシリアル通信について

    現在PICで電子工作を勉強中です。 PIC16f628Aを使ってパソコンとのシリアル通信をしようと思っています。 しかし、PICから"Hit some key for test"という文字列をおくったところ、 文字化けして"ソ3!・ソ)5"といった感じで出力されてしまいました。 文字化けが起きる原因としては何が考えられるのでしょうか? なお、パソコン側の端末にはTera Termを使用しています。 どなたかご教授お願いします。 以下にソースコードを示します。 #include <pic.h> __CONFIG(MCLRDIS & PWRTEN & BORDIS & UNPROTECT & WDTDIS & LVPDIS & HS); __IDLOC(628A); unsigned char getchr(void) { while(RCIF == 0); return (RCREG); } void putchr(unsigned char c) { while(TXIF == 0); TXREG = c; } void puts(const unsigned char *s) { while(*s) putchr(*s++); } void main(void) { PORTB = 0; TRISB = 0b00000010; SPBRG = 129; TXSTA = 0b00100100; RCSTA = 0b10010000; puts("Hit some key for test\n"); puts("\n"); while(1) putchr(getchr()); }

  • PIC間通信

    http://kuri6005.sakura.ne.jp/pic/pukiwiki.php?PIC-PIC%A4%CE%C4%CC%BF%AE%28USART%29 現在上記のサイトを利用してPICの勉強中です。 上記サイトでは、'A'という文字を転送していますが、数字や'AA'など複数文字ではうまく動作しません。 なにか良い方法があるのでしょうか? 下記 Usart_Write(1); の1の部分を'A'にするとうまく動作します。 (もちろん、送信・受信両方のPICは書き換えています。) できれば、変数にして受信側に送りたいのですが、可能でしょうか? よきアドバイスをお願い致します。 void main() { Kmode=0; PORTA=0b00000000; //PORTAの中身をきれいにする PORTB=0b00000000; //PORTBの中身をきれいにする CMCON=0b00000111; //PORTAをデジタル入出力使用に設定 TRISA=0b00000001; //RA0を1:入力に、他を0:出力に設定 TRISB=0b00000010; //PORTB RB1:入力、他7ヶは出力設定 Usart_Init(2400); //通信速度を2400 band rateに設定 do { if(Button(&PORTA, 0, 1, 0)) { //スイッチONの場合 Usart_Write(1); }else{ Usart_Write(0) } while(1); }

  • picからpicへのデータ送信方法について

    pic16f690間でUSARTを使用して、データのやり取りを行おうとしています。 送信側から1~25の10進数を送信し、受信側で受けとった数値の回数の処理を行おうとしています。 コンパイラはCCS社のものを使用しています。 データ送信側は printf("%2x",送りたいデータ) 受信側は usart受信割り込みで  getc(受信したデータを入れる変数) 上記のようにコードを書いています。 しかし、受信側で正しい数値を受信できていないようです。 ただ単に1又は2桁の数値を受信する場合はどのようにすればいいでしょうか? よろしくお願い致します。

  • PIC 文字 を 数値に 変換

    アセンブラ言語(PIC)で、シリアルで受信した文字列数値を数値に変換したいのですが、どなたかプログラムを教えてくださいませんか?

  • PICマイコンによる乱数の表示について

    度々こちらで、お助け頂いております。 さて、今回の主旨はPICマイコンによりLCD表示器へ6個の数字を 表示する方法についてご質問させていただきました。 プログラミングはPIC用コンパイラCCS社のCコンパイラを使用し、 Micro chip社のMPLABと統合動作させています。 一般的なC言語と異なる部分があり、扱づらい面のあるコンパイラです。 では、問題のソースコードを次に記述します。 細部の設定や定義は省いて記述してあります。 1.void main() 2. { 3.int data,i; 4.srand((unsigned)time(ULL)); 5.data = 0; 6.表示器の初期化 7.カーソル位置をHomeへ 8.while(1) 9.{ 10.入力信号判定式 11.for(i = 0; i < 6; i++) 12. { 13. data=rand( )%6 + 1; 14. printf(lcd_data"%3d",data); 15. } 16.入力信号判定式 17.break; 18. } 19. } 以上、これだけのソースコードですが、コンパイルすると、 行番4コードがコンパイルエラーとなります。 (※英語のメッセージは読取れません。(勉強不足)) PICに関するrand( )とsrand( )関数について、いろいろと調べてみましたが、 それらに該当する項目が見当たりません。 そこで、行番4の部分をsrand(data);に変更したら、何とかコンパイル成功します。 それをPICに書込み、ターゲットに実装試験してみると、 100回乱数表示のうち、18回同じ組合せの数が出てしまいます。 どうも、srandの初期化が上手く出来てないみたいですが・・・ 何処が不具合となっているのでしょうか? また、同じソースコードをパソコンの標準Cで試してみると、 130回とも全てランダムに画面表示されます。 そこでどなた様か、PICに詳しい方のお知恵を拝借し、 ご指南頂けるなら、大変幸いに思います。 何卒宜しくお願い申し上げます。

  • Tera Term Pro version 2.3 の使用法

    Tera Term をインストールしたのですが、使い方がわかりません。 ホスト名とポート番号を入力し、接続することは出来たものの、 Tera Term の画面に[SSH-1.5-1.2.27]と表示されるだけで何も入力出来ず、 enterを押すと画面が自動的に消えてしまいます。 どうすればいいでしょうか。 ちなみにWindows XPです。(Tera Term 日本語版のHPにXP対応となっていたので対応はしてると思います)

  • PICマイコンのI/Oについて教えてください。

    PIC16F1936を使っています。 各ポートをデジタル出力にしLEDを順に点灯させていますが RB0に接続したLEDのみうっすらとしか光りません。 (プログラムで意図したとおり点滅はします。) テスターで電流を計測したところRB0のみほとんど流れていませんでした。 また電源投入時にRB0に接続したLEDだけ一瞬光ります。 PICは初期状態でI/Oは入力になっているので光らないと思うんですが・・・ MPLABX+XC8で開発しています。 以下の切り分けを行いました。 ・LED単体での点灯:正常点灯 ・他のLEDをRB0に接続:現象再現 ・他のブレットボードで作動:現象再現 データシートとかなり睨めっこしたんですがそれっぽい部分がみつかりません ご教示いただけると助かります。 ソースは以下のとおりです。 #include <xc.h> #pragma config CLKOUTEN = OFF,\ WDTE = OFF,\ PWRTE = ON,\ CP = OFF,\ BOREN = OFF,\ FCMEN = OFF,\ MCLRE = ON,\ CPD = OFF,\ IESO = OFF,\ FOSC = INTOSC,\ STVREN = OFF,\ BORV = LO,\ LVP = OFF,\ VCAPEN = OFF,\ WRT = OFF,\ PLLEN = ON #define uchar unsigned char #define uint unsigned int void init(void){ //ポート初期化 PORTA = 0b00000000; PORTB = 0b00000000; PORTC = 0b00000000; PORTE = 0b00000000; TRISA = 0b00000000; TRISB = 0b00000000; TRISC = 0b00000000; TRISE = 0b00000000; //全てデジタル ANSELA = 0b00000000; ANSELB = 0b00000000; //8mhz OSCCON = 0b11110000; OPTION_REG = 0b00000000; APFCON = 0; WPUE = 0; } void Wait(unsigned int num){ for (int i=0 ; i<num ; ++i) { for( int j = 0; j < 100; ++j){ NOP(); } } } void main(void){ init(); while(1){ PORTC = 0b00000100; Wait(1000); PORTC = 0b00000000; PORTB = 0b00001000; Wait(1000); PORTB = 0b00100000; Wait(1000); PORTB = 0b00000001; Wait(1000); PORTB = 0b00000000; } }

  • またまたテストの復習なんですが・・・

    処理内容 基数、および変換対象数値(10進数)を入力させ、それに応じた基数変換を行う。その結果を画面に出力する。 ソースプログラム #include<stdio.h> #define MAX_OUT (16) int InputNum(int, int); char ChangeNum(int); /* メイン処理 */ main(){ int i; /* カウンタ */ int num; /* 対象数値 */ int num_base /* 基数 */ int num_next, num_out; char str[MAX_OUT]; /* 変換後文字格納用 */ while (1){ printf("基数を入力してください(2~32)\n"); printf("(2~32以外の入力で終了)\n"); num_base=InputNum(2,32); if (-1==num_base) { break; } printf("対象の数値を入力してください(0~65535)\n"); printf("(0~65535以外の入力で終了)\n"); num=InputNum(0,65535); if (-1==num) { break; } /* 変換開始 */ ( 1 ) for (i=0; i<MAX_OUT; i++){ /* 変換終了か判定する */ if (num_base>num_next){ /* 変換後文字の格納 */ str[i++]=ChangeNum(num_next); break; } /* 数値文字を抽出 */ num_out=( 2 ) str[i]=ChangeNum(num_out); /* 次の行へ */ num_next=( 3 ) } /* 変換結果を出力 */ printf("対象数値%dの%d進数表現は\n",num, num_base); for (i -= 1; 0<=i; i--) { printf("%c", str[i]); } printf("\nです\n"); } printf("終了します\n"); } /* 数値入力処理 */ int InputNum(int min, int max){ int ret; scanf("%d", &ret); if ((min>ret) || (max<ret)){ ret=-1; } return ret; } /* 数値を文字に変換 */ char ChargeNum(int num){ char ret=0; if (10>num){ ret=num+'0'; } else{ ret=( 4 )+'A'; } return ret; } という問題なんですが、(1)~(4)の答えと説明をどなたかして頂けないでしょうか?どうぞよろしくお願いします!ちなみにwhile(1)は無限ループです。

  • geko201とマイコンのシリアル通信について

    GPS受信機(geko201)をマイコン(pic18f452)の基板にrs23-2cで接続して、 GPS受信機からのデータを取り、その数値を計算するプログラムをC言語で組んでいます。 処理手順としては マイコン側のボタンを押すと、 GPS受信機からのデータ(@051125004805N3529538E13638632G005+00041E0000N0000D0000) を受信してその値の計算をはじめます。 そこで問題があり、 仮想GPSとしてプログラムで任意のタイミングで一件だけマイコンにGPSデータを送った場合 ちゃんと計算してくれるんですが、 本物のGPS受信機は1秒毎にデータを垂れ流し状態で そこで受信したら、受信待ちで止まってしまいます 改善策がわからないので、どなたか教えてください 受信部分のソース↓ while(1) { if(input(PIN_A0)){ gets(mes);          以下略 } }//roop end

専門家に質問してみよう