H8/36064のAD変換データの文字列化について

このQ&Aのポイント
  • H8/36064のAD変換データを文字列化する方法について調査中です。
  • 前回の質問後、10ビットのA/D変換データを文字列に置き換える方法を調べstatic void uint2Hex()によって文字列に置き換えを行っていますが、解消できませんでした。
  • H8/36064を使用しTera Termに取り込むことでAD変換データを確認しています。シリアル通信の設定はマイコン側、Tera Term側で合わせています。
回答を見る
  • ベストアンサー

H8/36064のAD変換データの文字列化について

たびたびの質問失礼いたします。 前回シリアル通信によって文字化けがおきることについて質問させていただいたものです。 前回の質問後、10ビットのA/D変換データを文字列に置き換える方法を調べstatic void uint2Hex()によって文字列に置き換えを行っているのですがまだうまく解消できませんでした。 申し訳ないのですが再び助言をいただけないでしょうか。 H8/36064を使用しTera Termに取り込むことで確認を行っています。 ボーレートなどのシリアル通信の設定はマイコン側、Tera Term側であわせてあります。 #include "iodefine.h" #include <machine.h> //割り込みマスクビット変更関数set_imask_ccr() を使用するためのインクルードファイル #include <stdio.h> void main(void) { init(); while(1){ if(AD.ADCSR.BIT.ADF == 1) Getad(); } } init() //A/D変換およびタイマV初期設定用関数 { set_imask_ccr(1); //割り込み禁止設定 AD.ADCSR.BIT.SCAN = 1; AD.ADCSR.BIT.CH = 101; TV.TCRV1.BIT.ICKS = 0; TV.TCRV0.BIT.CKS = 3; //Φ/128 TV.TCORA = 115-1; //コンペアマッチAの値 TV.TCRV0.BIT.CCLR = 1; //タイマカウンタクリア TV.TCRV0.BIT.CMIEA = 1; //割り込み発生フラグ設定 set_imask_ccr(0); //割り込み禁止解除 } void initSCI3(void) //シリアル通信設定 { unsigned int dmy; IO.PMR1.BIT.TXD = 1; //TXD端子使用設定 SCI3.SCR3.BYTE = 0; //SCR3クリア SCI3.SMR.BYTE = 0; //SMRフォーマット設定 SCI3.BRR = 47; //9600bps for(dmy = 280;dmy > 0;dmy--); SCI3.SCR3.BIT.TE = 1; //送信動作許可 } void rs_putc(char c) //1文字送信 { while(SCI3.SSR.BIT.TDRE == 0); //トランスミットデータレジスタエンプティが真になるまで待機 SCI3.TDR = c; //トランスミットデータレジスタに送信データ(8bit)をセット SCI3.SSR.BIT.TDRE = 0; //「送信中」フラグを立てる } void rs_puts(char *st) //文字列送信 { while(*st != 0){ rs_putc(*st); st++; } } static void uint2Hex(unsigned long n, short upper, char *buf) { char c; char a = 'a'; short len = 0; short i, half; if(upper) a = 'A'; // 大文字/小文字の設定 // 16進文字列へ変換し文字数をカウント do{ i = n & 0x0F; if(i > 9) buf[len] = (unsigned char)(i + a - 10); else buf[len] = (unsigned char)(i + '0'); len++; n >>= 4; }while(n != 0); half = len >> 1; // 文字の並び順を直す for(i=0; i < half; i++){ c = buf[i]; buf[i] = buf[(len-1)-i]; buf[(len-1)-i] = c; } buf[len]='\0'; // 終端コードの挿入 } Getad() { volatile unsigned int *data = (unsigned int *)0xfa00; volatile unsigned int *data2 = (unsigned int *)0xfa10; initSCI3(); // SCI3初期化 *data =AD.ADDRA; *data = *data >> 6;//右に6bitシフト *data2 =AD.ADDRB; *data2 = *data2 >> 6;//右に6bitシフト rs_putc(*data); rs_putc(*data2); AD.ADCSR.BIT.ADF = 0; AD.ADCSR.BIT.ADST = 0; } #pragma interrupt (TimerV(vect=22)) //割り込み処理関数としてTimerVを宣言 void TimerV(void) { static int count; //20000回(0.1秒)ごとにGetad // コンペアマッチフラグを0に戻し、次のコンペアマッチに備える。 TV.TCSRV.BIT.CMFA = 0; if(count<100) count++; else { count = 0; AD.ADCSR.BIT.ADST = 1; //AD変換開始 } }

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

  • ベストアンサー
回答No.3

> static void uint2Hex()によって文字列に置き換えを行っているのですが とのことですが、unit2Hex() は一度も呼ばれていないようです。 つまり、文字列の置き換えなどされてないと言うことです。 また、data1, data2 をそれぞれ、0xfa00, 0xfa10 番地に割り当てているようですが、これも意図が理解できません。 ここには、未定義のレジスタが存在するようですが、定義されないところを何かに使うのは、良くない気がします。 その他にも、rs_puts() が定義してあるのに使っていないとか、ずいぶんと不思議な気がします。 他のところがあっているとすれば、 Getad() { unsigned int data; char buff[16]; initSCI3(); // SCI3初期化 data = AD.ADDRA >> 6; uint2Hex(data, 0,buff); rs_puts(buff); rs_putc(':'); // 区切り記号(適当に) data = AD.ADDRB >> 6; uint2Hex(data, 0, buff); rs_puts(buff); rs_putc('\x0d'); // 区切り記号(適当に) AD.ADCSR.BIT.ADF = 0; AD.ADCSR.BIT.ADST = 0; } こんな感じで、16進の文字列で出てくる気がします。 data も省くなら、 Getad() { char buff[16]; initSCI3(); // SCI3初期化 uint2Hex(AD.ADDRA >> 6, 0, buff); rs_puts(buff); rs_putc(':'); // 区切り記号(適当に) uint2Hex(AD.ADDRB >> 6, 0, buff); rs_puts(buff); rs_putc('\x0d'); // 区切り記号(適当に) AD.ADCSR.BIT.ADF = 0; AD.ADCSR.BIT.ADST = 0; } でも、いけるのではないかと思います。

rokuMK2
質問者

お礼

ありがとうございました。おかげさまでTera Term上に表示させることができました。 data,data2にそれぞれ0xfa00,0xfa10を割り当てたのはHEW上で確認を行うためのものでした。

その他の回答 (2)

  • tsunji
  • ベストアンサー率20% (196/958)
回答No.2

rs_putc(*data); rs_putc(*data2); の部分を以下の様に書き換えてみてください。 rs_putc(':'); rs_putc((*data / 1000) % 10 + '0'); rs_putc((*data / 100) % 10 +'0' ); rs_putc((*data / 10) % 10 +'0' ); rs_putc(*data % 10 + '0'); rs_putc(':'); rs_putc((*data2 / 1000) % 10 + '0'); rs_putc((*data2 / 100) % 10 +'0' ); rs_putc((*data2 / 10) % 10 +'0' ); rs_putc(*data2 % 10 + '0'); 10進数で結果が出力されると思います。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

具体的には ・何がどうなることを期待していて ・実際には何がどうなる のでしょうか?

rokuMK2
質問者

補足

data,data2に格納されたA/D変換のデータを16進数の文字列に変換し、 シリアル通信を使ってTera Teramに表示することが目的です。 しかし、今のままではTera Teramに表示はできるのですが、 送られてくるデータが文字化けしてしまっています。

関連するQ&A

  • H8/36064を使ったシリアル通信について

    今学校のほうでH8/36064をつかってA/D変換したデータをPCに送るためのプログラムを作っているのですが、取り込んだデータをシリアル通信を使ってPCに送るとどうしても文字化けしてしまいます。 だめな原因などを教えていただけないでしょうか。 /*プログラム*/ #include "iodefine.h" #include <machine.h> //割り込みマスクビット変更関数set_imask_ccr()を              //使用するためのインクルードファイル #include <stdio.h> void main(void) { while(1){ if(AD.ADCSR.BIT.ADF == 1) Getad(); } } init() //A/D変換およびタイマV初期設定用関数 { set_imask_ccr(1); //割り込み禁止設定 AD.ADCSR.BIT.SCAN = 1; AD.ADCSR.BIT.CH = 101; TV.TCRV1.BIT.ICKS = 0; TV.TCRV0.BIT.CKS = 3; //Φ/128 TV.TCORA = 115-1; //コンペアマッチAの値 TV.TCRV0.BIT.CCLR = 1; //タイマカウンタクリア TV.TCRV0.BIT.CMIEA = 1; //割り込み発生フラグ設定 set_imask_ccr(0); //割り込み禁止解除 } void Sci3() //シリアル通信設定 { unsigned int dmy; IO.PMR1.BIT.TXD = 1; //TXD端子使用設定 SCI3.SCR3.BYTE = 0; //SCR3クリア SCI3.SMR.BYTE = 0; //SMRフォーマット設定 SCI3.BRR = 47; //9600bps for(dmy = 280;dmy > 0;dmy--); SCI3.SCR3.BIT.TE = 1; //送信動作許可 } void sendCharSCI(char data) //データ送信設定 { while(SCI3.SSR.BIT.TDRE==0); //トランスミットデータレジスタエンプティが真になるまで待機 SCI3.TDR = data; //トランスミットデータレジスタに送信データ(8bit)をセット SCI3.SSR.BIT.TDRE = 0; //「送信中」フラグを立てる return; } void print(char *str) { while(*str !='\0') { sendCharSCI(*str); str++; } return; } Getad() { volatile unsigned int *data = (unsigned int *)0xfa00; volatile unsigned int *data2 = (unsigned int *)0xfa10; *data =AD.ADDRA; *data = *data >> 6; //右に6bitシフト *data2 =AD.ADDRB; *data2 = *data2 >> 6; //右に6bitシフト AD.ADCSR.BIT.ADF = 0; AD.ADCSR.BIT.ADST = 0; Sci3(); // SCI3初期化 sendCharSCI(*data); sendCharSCI(*data2); } #pragma interrupt (TimerV(vect=22)) //割り込み処理関数としてTimerVを宣言 void TimerV(void) { static int count; //20000回(0.1秒)ごとにGetad // コンペアマッチフラグを0に戻し、次のコンペアマッチに備える。 TV.TCSRV.BIT.CMFA = 0; if(count<100) count++; else { count = 0; AD.ADCSR.BIT.ADST = 1; //AD変換開始 } }

  • h8マイコンで AD変換ができなくて困っています

    マイコンでAD変換をしようと思っています>< #include<3048.h> void ioinit(); void adinit(); int i; int ADDRA; main() { ioinit(); adinit(); while(1){ AD.ADCSR.BIT.ADST = 1; // A/D変換スタート while(AD.ADCSR.BIT.ADF==1); // A/D変換終了まで待つ int i = ADDRA; // レジスタに格納された値をiとする if (i>=0xA5){ // 電圧が6.5vより高くなった場合 P5.DR.BYTE = 0x01; } else if (i<=0x19){ // 電圧が1vより小さくなった場合 P5.DR.BYTE = 0x02; } else if (0x19<=i<=0xA5){ // それ以外の電圧だった場合 P5.DR.BYTE = 0x03; } AD.ADCSR.BIT.ADF=0; //フラグクリア } } // I/OポートDDR設定 void ioinit() { P5.DDR=0xff; } // A/D変換設定 void adinit() { AD.ADCSR.BYTE = 0x33; } このプログラムでAD変換がまったくできません><電圧を変えていくことでP5につながっているLEDで変換結果を見たいと思っています。ADDRAのプログラムあたりがおかしいと思っています;;ちなみにポート7に電圧計とつなげています。その電圧値を変えていくことで結果を見ようとしています。0xA5は6.5Vのときの反応だから回路も分圧させたものにして10Vまでの対応にしました><どこがおかしいのか教えていただけるとてもうれしいです><助けてください;;

  • H8-3052Fを用いた文字列の受信

    私は現在、H8-3052Fを用いて別の回路と画像データなどを送受信するソフトをGCC-Developpers Liteを用いて作っています。 H8-3052Fを用いてunsigned char型の文字列をRS-232Cで受信して、配列に格納する方法を教えて下さい。 現在は下記の1文字受信関数を用いていますが、うまく出来ません。 Main文では常に文字列受信を待っている状態で、またITU割り込みで1秒ごとに別の処理が走るようにしています。 char SCI1_IN_d(void) //受信文字を返す { char c; //受信データ格納変数 while (!(SCI1.SSR.BYTE&0x78)); //受信もしくはエラーフラグが立つまで待つ if(SCI1.SSR.BIT.RDRF==1) //受信完了でRDRF=1 { c=SCI1.RDR; //データ取り出し SCI1.SSR.BIT.RDRF=0; //受信フラグクリア } else { //受信完了していないならRDRF=0 SCI1.SSR.BYTE&=0x80; //エラーならエラーフラグクリア c=0; } return c; //受信文字を返す } 以上です。 何分素人なので解りかねることがあると思いますが、宜しくお願い致します。

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

    H8マイコンでのシリアル通信についてお聞きしたいことがあります。 現在PCとマイコン(H8/3052F)をRS32Cでシリアル通信ができています。 今回は有線ではなく無線(Bluetooth)を利用してシリアル通信が行いたく、RBT-001というものを購入しました。 そのマニュアルには一番簡単に通信する方法としてPICマイコンとの例が挙げられており、要するに初期設定さえすれば無線を意識せずに使えるとの事だったのですが、どうも出来ていないみたいです。 --------------------私のプログラム---------------------- #include<3052.h> void initSCI1 (void){ int i; SCI1.SCR.BYTE = SCI1.SMR.BYTE = 0;//初期値は0、本文参照 SCI1.BRR = 80; //ビットレート for (i = 0; i <4000; i++) ; //待つ SCI1.SCR.BYTE = 0x30; //受信割り込み許可、送受信許可 SCI1.SSR.BYTE; //ダミーリード SCI1.SSR.BYTE = 0x80; //エラーフラグクリア } //1文字受信 char SCI1_IN_d(void){ //受信文字を返す。 unsigned char c; //受信データの格納変数 while (!(SCI1.SSR.BYTE & 0x78)); //受信またはエラーフラグが立つまで待つ if (SCI1.SSR.BIT.RDRF == 1) { //受信完了なら c = SCI1.RDR; //データを取り出す。 SCI1.SSR.BIT.RDRF = 0; //受信フラグクリア } else { SCI1.SSR.BYTE &= 0x80; //エラーならエラーフラグクリア c = 0; } return c; } //1文字送信 void SCI1_OUT_d(char c) //文字コードを受け取る。 { while (SCI1.SSR.BIT.TDRE == 0); //0でデータあり、1になるまで待つ。 SCI1.TDR = c; //受け取った文字を送信 SCI1.SSR.BIT.TDRE = 0; //TDREビットをクリア } //BLUETOOTH初期設定 void BT_Init(void){ SCI1_OUT_d(0x02); SCI1_OUT_d(0x52); SCI1_OUT_d(0x4E); SCI1_OUT_d(0x01); SCI1_OUT_d(0x00); SCI1_OUT_d(0xA1); SCI1_OUT_d(0x03); SCI1_OUT_d(0x03); return; } int main (void){ unsigned char rd; BT_Init(); initSCI1(); while(1){ rd=SCI1_IN_d(); SCI1_OUT_d(rd); } } ------------------------------------------------------------ 問題はmain文中「initSCI1();」でSCI1を初期化するとズット変な文字化けみたいなのを延々と吐き出して、逆に初期化しないとPCでなんらかのキーを押すとRBT-001は点滅はするけど、文字を返してこないという状況です。 なので「initSCI1();」がおかしいのかと思うのですが、有線では現にこれで出来ているのでなにが原因かわかりません。 良かったらどこがダメでどうするべきか教えてください。 本当に困っています。よろしくお願いします。 通信速度9600bps データ長8ビット長 ストップピット1 パリティ無 CPU最高動作周波数25MHz -------------------RBT-001マニュアルに記載されているサンプルプログラム------------------------- char text; void BT_Init(); void MPU_Init(); int TRISB,ANSEL,ANSELH; int _LCD_FIRST_ROW,_LCD_CURSUR_OFF,_LCD_CLEAR; void main(){ MPU_Init(); BT_Init(); while(1){ if(Uart1_Data_Ready()){ text = Uart1_Read(); Uart1_Write(text); Lcd_Chr_Cp(text); } } } void MPU_Init(){ TRISB = 0; ANSEL = 0; ANSELH = 0; Uart1_init(9600); Lcd_Init(); Lcd_Cmd(_LCD_FIRST_ROW); Lcd_Cmd(_LCD_CURSUR_OFF); Lcd_Cmd(_LCD_CLEAR); return; } void BT_Init(){ Uart1_Write(0x02); Uart1_Write(0x52); Uart1_Write(0x4E); Uart1_Write(0x01); Uart1_Write(0x00); Uart1_Write(0xA1); Uart1_Write(0x03); Uart1_Write(0x03); return; } -------------------------------------------------------------------

  • 文字列

    下のプログラムは何をするためのプログラムなのか教えてください。 個人的にはJISコードに関係していると思うのですがさっぱりわかりません。 どなたか詳しい説明お願いします。 #include <stdio.h> #define LEN 255 int main(void) { char str[LEN]; char cipher[LEN]; int ikey; int i,n; printf("文字列を入力せよ : "); scanf("%s", str); printf("鍵を入力 : "); scanf("%d", &ikey); i = 0; while (str[i]!='\0') { n = (str[i]-'A'+ikey)%26; cipher[i] = 'A'+n; ++i; } cipher[i] = '\0'; printf("%s\n", cipher); return 0; }

  • c言語の文字列の逆順のプログラムがわかりません

    文字列を逆順して出力するプログラミングがわかりません。 #include <stdio.h> #include <string.h> void reverse(char *moji, char *gyaku); int main(void) { char x[30]; char y[30]; puts("文字を入力してください。\n"); scanf("%s", x); reverse(x, y); printf("逆順すると%sです。\n", y); return (0); } void reverse(char *moji, char *gyaku) { int i, len; len = strlen(moji); gyaku = moji + len - 1; for(i = 0; i < len; i ++){ putchar((int)*gyaku); gyaku--; } } 理想とする実行結果は 文字を入力してください。 abcdefg 逆順するとgfedcbaです。 なんですが、 上記のソースを実行すると 文字を入力してください。 abcdefg gfedcba逆順すると(謎の漢字)です。 となります。 どこがおかしいんでしょうか? よろしくおねがいします。

  • ファイルから文字を読み込んで文字列を変換する

    ファイルから文字を読み込んで文字列を変換したいのですが 読み込み元が改行されていた場合がうまく変換できません。 読み込み元が改行されている事を教えればうまく行くと思うのですがどのようにすれば出来ますか? 出来ればソースの書き込みお願いします。 ---以下ソース--- #include <stdio.h> #include <stdlib.h> #include <string.h> int hen(char *buf, char *mae, char *ato); void main(void){ FILE *fp; char *f1="赤<br>と<br>白<br>"; char *h1="黄と黒"; char buf[200]; char set[200]; fp = fopen("ren2.html", "r+"); while( fgets( set, 200, fp ) != NULL ){ strcpy(buf,set); while(hen(buf, f1, h1)); printf("%s", buf); } fclose(fp); } int hen(char *buf, char *mae, char *ato){ char *nw; size_t zen,go; zen = strlen(mae); go = strlen(ato); if(zen == 0 || (nw = strstr(buf, mae)) == NULL){ return 0; } memmove(nw + go, nw + zen, strlen(buf) - (nw + zen - buf ) + 1); memcpy(nw, ato, go); return 1; } ---ソースここまで--- ---ren2.htmlの内容--- <html> <head> <title>練習</title> </head> <body> 赤<br> と<br> 白<br> </body> </html> ---ren2.htmlここまで---

  • C言語の課題で困っています;

    C言語の課題で困ってます; 学校の課題で、キーボードから文字を入力する(最大80文字)。入力された文字列と、入力した文字列を逆順にした文字列を表示する。(malloc,freeを使って作成して下さい) ヒントで #invlude <stdio.h> void main(void){ char *buf; //入力文字列用 char *seq; //入力文字列用コピー用 char *rev; //逆順文字列用 int lec, i; buf =(char*)malloc(81); printf("文字列を入力:"); scanf("%s"buf ); for(i = 0; buf[i] ??? '\0'; i++){ } Ien = i; /* lenに文字列の長さが入る */ seq = ???(??? + 1); /* len+1文字文確保*/ for(i = 0; ???; i++){ seq[0] = buf[0]; } free(buf); rey = ???(len + 1); for(i = 0; < len; i++){ rev[len - i - 1] = seq[i]; } ren[i] ~ '\0'; printd("入力文字列 : %s\n",sep); でたんですが、全然分からなくて足りない部分の答えを教えてもらえると助かります;

  • 文字列の扱い方

    初歩的な質問ですみません… str文字列からcという文字を見つけたら添字を返すという関数を作ったのですが、 iにこの関数を代入して、if文の制御式にiを使って比較するまでは正常なのですが、 真文にiを使うと何故か偽文(という言い方でいいのでしょうか…この場合("そんな値はありません。"というところです)が実行されてしまいます。 よろしければご教授お願い致します。 #include <stdio.h> int str_char(const char str[],int c) { int len = strlen(str); int i; for (i = 0;i < len;i++) { if (str[i] == c) return i; } return -1; } int main() { char str[64] = "Fucking Brutal Death Metal"; int ch,i; printf("どの文字を調べますか?"); scanf("%c",&ch); i = str_char(str,ch); if (i >= 0) printf("その文字は%d番目にあります。",str_char(str,ch) + 1); //何故かiだと動かない else printf("そんな値はありません。"); return 0; }

  • AD変換

    H8/3664でのAD変換についての質問なのですが、このマイコンだと通常8つあるAD変換をスキャンモードで1度で4つまでしか処理できないのですが グループ0のAN0とグループ1のAN4が同一レジスタで結果が格納されていると思われますが この二つを1度に処理したいのですが、どのようなプログラムにすればいいのですか? AD変換あたりのプログラムを抜粋したので、後半のAD.ADDRB をAN4のAD.ADDRAに変えた場合のプログラムを教えて下さい char aflag=0; //割り込みフラグ void main(void) { char carray0[20],carray1[20],carray2[20]; long ad_data_0,ad_data_1,arrey0,arrey1,ad0,ad1,t,G_data,A_data,hensa_now,hensa_mae,A_out_put; int i; timervset(); timeraset(); IO.PDR5.BYTE = 0xff; // ポート7の出力設定をあらかじめ1に設定 IO.PCR7 = 0x00; // ポート7を全て入力ポートに設定(タクトSW1,SW2,SW3) IO.PCR5 = 0xff; // ポート5を全て出力ポートに設定 IO.PCR1 = 0xa0; // ポート1のP15,P17を出力ポートに Init_rs(); //通信の初期化 AD.ADDRA=0; AD.ADDRB=0; AD.ADDRC=0; AD.ADDRD=0; //AD変換設定 //A/Dコンバータ設定 AD.ADCSR.BYTE = 0x33; // (0011 0011)*/ // スキャンモード,高速変換(70ステート),入力端子:AN0~AN3 set_imask_ccr(0); //割り込み可 while(1) { if(aflag==1){ aflag=0; ad_data_0=AD.ADDRA >> 6; // 「>>」:シフト演算子(ビットを右に6ずらす) ad0=ad_data_0*5000/1024; LToStr(G_data,carray0);//グローブ角度表示 rs_puts("ch.0="); rs_puts(carray0); rs_crlf(); wait(1); G_data=(ad0-2333)*(-0.0426);//グローブ角度 ad_data_1=AD.ADDRB >> 6; // 「>>」:シフト演算子(ビットを右に6ずらす) ad1=ad_data_1*5000/1024; LToStr(A_data,carray1);//アーム角度表示 rs_puts("ch.1="); rs_puts(carray1); rs_crlf(); wait(1);

専門家に質問してみよう