• ベストアンサー

マイコンプログラム - 16進をキャラクタに

10BitのADCのメモリを読んでキャラクタに変換、UARTで送信、と言ったことを考えています。 (unsigned short)adcmem = 0x03FF →  (unsigned char)res[4] = {'0','3','F','F'} ただC言語環境下でのマイコンプログラムであるためsprintfなどといった関数は使用できず困っています。 何かよい案があればよろしくお願いします。

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

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

unsigned short adcmem = 0x03FF; unsigned char res[4]; int i; for (i = 0; i < 4; i++)  res[i] = "0123456789ABCDEF"[(adcmem >> (12 - i*4)) & 0xf]; でどうですか?

Reduction
質問者

お礼

初見で正直まったくわかりませんでした。 しかしやってみるとすごくわかりやすいですね。 このようなキャラクタの選択方法があるとはまったく知りませんでした。 勉強不足を痛感します。ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • arain
  • ベストアンサー率27% (292/1049)
回答No.1

ASCIIコードへの変換でいいのかな? であれば、 ------ unsigned short adcmem unsigned char res[4]; int i, j; unsigned short work; for(i = 3, j = 0; i > 0; i--, j++) { work = (admem >> (4 * i)) & 0x000F; /* 4bit取り出し */ if( (0 <= work) && (work <= 9)) /* 0-9 */ { res[j] = (unsigned char)(work + 0x30); } else /* A-F */ { res[j] = (unsigned char)(work + 0x37); } } ------ みたいに4bitずつ取り出して、ASCIIコードに変換すればいいけど。

Reduction
質問者

お礼

とてもわかりやすい回答ありがとうございます。 やはり4Bitずつ取り出すのが最善のようですか。 もっと勉強します。

Reduction
質問者

補足

後で見直すためにも補足させてもらいます。 コンパイラの警告で pointless comparison of unsigned integer with zero が表示される場合はworkがunsignedのため。= 0以下にならない。 そのため (0 <= work) && の書式は符号つきの場合に必要。 For文が4回いかないため i > 0 を i >= 0に。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • マイコンのCプログラミングで未使用のプログラム領域のアドレスを指定して読み込みできる?

    いまPICマイコンのプログラミングをしています。コンパイラはCSSというものを使っています。 設定した値を読み込んでその値でタイマーを動かそうと思っているのですが、12F509というマイコンはEEPROM領域がないので、なんとかしてこれを実現するにはと思い2kワードのプログラミング領域を半分くらいしか使っていないことに気づいたので、その領域の一番後ろの0x07FF番地に何かしらデータを書いてその番地にアクセスしてそこからタイマーの時間を呼び出そうと思ったのですが、このようなことはできるのでしょうか? C言語だとポインターを使えばよかったと思うのですが、その場合どのように書いたら良いのでしょうか? ご教授よろしくお願い致します。 たぶん、 unsinged char *timer_add; timer_add = (unsigned char *)0x07FF; get_value = timer_add; これでよかったでしょうか?

  • マイコンとADコンバータとのインターフェース回路

    マイコン初心者です。 マイコンと外付けADCとのインターフェース回路について質問です。 CH数や分解能といった事情より、外付け(8ch、16bit)程度のADCを利用したいと考えております。 こういったADCの場合、出力がシリアルデータなのですが、マイコンとのインターフェースはどうしたら良いのでしょうか。(マイコン内蔵のSCIは他の用途に割当済みで使えません) UART ICでシリアル/パラレル変換する?などと考えるのですが、一手として全うな手法なのでしょうか? 他にどういったやり方があるのか教えてください。 参考になるマイコン周辺回路の参考書等も併せて教えていただけますと助かります。 基本的な質問で恐縮ですが、よろしくお願いいたします。

  • マイコンのプログラム(C言語)について

    マイコンのサンプルプログラムの中に以下のような記述がありました。 ヘッダーファイル内 struct st_hudi { union { unsigned short WORD; struct { unsigned short TI:8; } BIT; }SDIR; }; #define HUDI (*(volatile struct st_hudi *)0xFFFE2000) そして、この構造体の使い方は HUDI.SDIR.WORD = 0; と、いった感じです。 通常は、構造体の宣言(struct st_hudi aなど)を行わないと使えないと思うのですが、以上のプログラムでエラーは出ません。 1.上記のような場合は、構造体の宣言はいらないのでしょうか? 現在は、#defineの部分でアドレスを指定してあるため、構造体の宣言はいらない、という認識を持っています。 2.volatileがなくても動きそうなのですが、これは必要なのでしょうか? アドレスを明記しているため、volatileがなくても正常に動きそうな気がします。 回答よろしくお願いします。

  • c言語 優先順位について

    c言語 優先順位について 下記の優先順位で1番目は、()関数呼び出しであれば左結合なので(unsigned char)を呼ばれないで、(++(f) -> fpi)[-1]を呼ばれる理由を教えて頂きたい。      (unsigned char)(++(f) -> fpi)[-1]

    • ベストアンサー
    • CGI
  • マイコン組み込みC言語の戻り値について

    例えば、 unsigned char kansuu(){ 文   return = 1   文 } のような戻り値がある関数の場合、return = 1 と書くと、 その関数の最後の } まで飛んで離脱してくれます。 そのことを利用して、戻り値がない関数の場合でも return と書いたら、その関数の最後の } まで飛んで離脱してくれるのでしょうか。 意図としましては、関数内である条件を満たすと、 その関数を離脱するようにしたかったからです。 マイコンはルネサスのr8cです。 そもそも、戻り値がない関数でも場合でも、 return を記述しても良いのでしょうか?

  • 文字列変換プログラムのポインタについて

    いかの関数は、文字列を16進文字列に変換する関数です。過去の質問を参考に自分で作りました。 動作することはするんですが、よく見るとpoとpiは領域確保していません。これってプログラム上まずいでしょうか。 char *conv( char *buff, char *str ) {   char *po;   char *pi;   for(po=buff, pi=str; *pi; pi++)   {     if(0 <= *pi && *pi <= 15)     {       sprintf(po, "%x", 0);       po++;       sprintf(po, "%x", *pi);       po++;     }else {       sprintf(po, "%x", (0x0f & (*pi >> 4)));       po++;       sprintf(po, "%x", (0x0f & (*pi % 16)));       po++;     }   }   *po='\0';   return(buff); }

  • CRC16コード作成プログラムについて

    お世話なります。 PCと対象機械との通信を行おうと思っております。 内容としてCRC16のコードを使って、日時設定をPC→対象機器へ行いたいです。 CRC16の生成プログラムをいろいろ調べてみたところ、 今、自分のスキルでなんとかわかりそうなCRC16のソースが次の通りでした。 (行列の計算ぐらいならC言語で作れる程度です。。。) unsigned short crc_cal(unsigned short lng, unsigned char *str) { unsigned short crc, i, j, t; crc = 0xffff; for (i = 0; i < lng ; i++) { crc ^= (unsigned short) str[i]; for (j = 1; j <= 8; j++) { if (crc & 1) { // carry bit on crc = crc >> 1; crc ^= 0xa001; } else { // carry bit off crc = crc >> 1; } } } return crc; } “0C0C0C0C0C0C”と入力したら、CRCコードが算出されるプログラムを作りたく、 入力部分を作成してみたのですが・・・ int main(void) { unsigned short i,j, t; unsigned char str[256]; unsigned char str0; unsigned short crc; int k=0; printf("Please input key (HEX)\n"); for(k=0; k < 256; k++) { scanf("%c",&str0); // 文字列標準入力 if( str0=='\n') // Enterが押されたときの実行 { str[k]='\0'; // 文末にNULL文字 break; // for文のループ終了 } else { str[k]=str0; // NULLでなければ入力された文字を代入 } } crc = crc_cal(k,str); printf("crc=%X\n", crc); return 0; } 文字列を分解して・・・やるんだろうなってまではなんとなくわかるのですが、 どのようにしたらよいでしょうか。。。 ご教授よろしくお願いします。

  • AVRマイコン UART動作異常

    AVRマイコンのATmega168にてPCとRS-232Cにてシリアル通信(UART)を行うと最初のスタートビット'L'が正常に出ず、スタートビット'L'の後すぐに'H'に戻ってその後データビットを送っています。2回目以降のスタートビットは正常に'L'が指定したボーレートの時間幅で出ており、問題はありません。最初のスタートビットが正常に出ない原因がわかりませんので教えてください。 システムクロック:1MHz(内部発振器のみ) ボーレート:4800bps データビット数:8bit ストップビット数:1bit パリティビット数:なし -------------------------------------------- #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h> #define sbi(addr,bit) addr |= (1<<bit) #define cbi(addr,bit) addr &= ~(1<<bit) void port_init(void){ PORTB = 0xFE; DDRB = 0xFF; asm("NOP"); } void uart_init(void){ sbi(DDRD,1); cbi(DDRD,0); asm("NOP"); } void uart_putchar(unsigned char c){ loop_until_bit_is_set(UCSR0A,UDRE0); // asm("NOP"); UDR0 = c; } void _delay_1s(void){ int i; for(i=0;i<100;i++){ _delay_ms(10); } } int main(void) { port_init(); uart_init(); UCSR0B = _BV(TXEN0); UCSR0C = 0b00000110; UBRR0H = (uint8_t)0; UBRR0L = (uint8_t)12; while(1) { uart_putchar(0b01011010); _delay_1s(); } return 0; } -----------------------------------------------

  • C言語のキャストについて

    お世話になります。 CRC-16の計算プログラムをC言語でつくりました。 例えば・・・1F 08 00 00 12 34 なら“1F0800001234”と入力すると【EEC2】と表示するプログラムです。 ただ・・・.Net SDKでコンパイルするとできたのですが、Visual C++2008でコンパイルするとエラーが出てしまいます。 (48) : error C2664: 'strlen' : 1 番目の引数を 'unsigned char [256]' から 'const char *' に変換できません。(新しい機能 ; ヘルプを参照) 1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 (52) : error C2664: 'strtol' : 1 番目の引数を 'unsigned char [3]' から 'const char *' に変換できません。(新しい機能 ; ヘルプを参照) 1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 型変換が必要ってことまではわかったのですが・・・必要なのはわかって行き詰まり状態です。。。 どのようしたらよいのでしょうか?ご教授をよろしくお願いします。 ソースは以下の通りです。 #include "stdafx.h" #include <stdio.h> #include <string.h> #include <stdlib.h> unsigned short crc_cal(unsigned short lng, unsigned char *str) { unsigned short crc, i, j, t; t= 0x0000; crc = 0xffff; for (i = 0; i < lng ; i++) { crc ^= (unsigned short) str[i]; t = (unsigned short) str[i]; for (j = 1; j <= 8; j++) { if (crc & 1) { // carry bit on crc = crc >> 1; crc ^= 0xa001; } else { // carry bit off crc = crc >> 1; } } } return crc; } int main(void) { unsigned char str[256],data[128],hexstr[3]; unsigned short crc,CRC,len; while(1) { printf("Please input key (HEX)\n"); scanf("%255s",str); hexstr[2]='\0'; for(len=0; len<(strlen(str)/2) ;len++) { hexstr[0]=str[len*2]; hexstr[1]=str[len*2+1]; data[len]=(unsigned char)strtol(hexstr, NULL, 16); } crc = crc_cal(len,data); CRC = (crc>>8) | (crc<<8); printf("\nCRC16 = %04X\n\n", CRC); } return 0; }

  • 1Byte→Hex文字列変換がうまく行かない。

    PICマイコン用にCを勉強中です。 1Byte→Hex文字列変換関数を作ろうとしています。 メモリを出来るだけ使いたくないのでコンパイル後のメモリを極少なくするようにしたいと思い以下のようなコードを書きましたが、うまくいきません。 void ByteToHex(unsigned short b, char *p) {   unsigned short t;   t = b >> 4   *p = t + (t < 10 ? 0x30 : 0x41);   t = b & 0x0f;   *(p+1) = t + (t < 10 ? 0x30 : 0x41);   *(p+2) = 0; } (p+2):ポインタのアドレスは加減算できるんかな?? ちなみに使っているコンパイラは"mikroC"です。