• ベストアンサー

実行結果をデジタル時計みたいな数字のみの4桁(LEDみたいな?)に表示

おせわになってます。勉強中かなり初心者です。 映画「24」の数字みたいな表示形式の画面に、時刻表の計算結果を表示したいのですが(お分かりいただけたでしょうか。。。) int main(void) { char type; int a;   do { nt table[] = { // 時刻表 610, 636, 659, 723, 750, 820, 837, 906, 933, 951, 1032, 1110, 1149, 1230, 1310, 1349, 1427, 1505, 1542, 1608, 1640, 1708, 1736, 1806, 1835, 1900, 1938, 2008, 2035, 2056, 2117, 2155, 2233, 2319, 2348, -1, //テーブル終印 }; int findtime; // 0000形式に変換後の現在時間 int *search; // テーブル内の検索時間 int h; // 時 int m; // 分 time_t timer; // 現在時刻を取得し地方形式に struct tm *local; time(&timer); // 現在時刻の取得 local = localtime(&timer); // 現在時刻を構造体に変換 h = local->tm_hour; // 時 m = local->tm_min; // 分 findtime = h * 100 + m ; // 現在時間を0000形式へ変換 // 該当時間検索 for ( search = table ; *search != -1 ; search++ ) { if ( *search > findtime ){ break; } } // 結果表示 // テーブル内の-1に当たったら06:10 if ( *search == - 1 ) { printf( "06:10\n\n" ); } else { printf( "%02d:%02d\n\n", (*search / 100), // 「時」取り出し (*search % 100) ); // 「分」取り出し } scanf("%c", &type); // Enterで再度プログラム開始 } while (type == '\n'); return 0; } 上記ソースの結果を点灯(表示)させたいのです。 下記ソースは時刻表とは関係なしに「8888」と点灯させた場合です //Printer's port no. (メモリのアドレス?) #define PRN_PORTD 0x0378 #define PRN_PORTC 0x037a int main(void) { int ret = ioperm(PRN_PORTD, 4, 1)); outb (0x7f, PRN_PORTD); // 以下右の一桁目点灯 // ↑ 0x7f は 8表示 0x06は1    // 0x5bは2 0x4fは3 0x66は4 // 0x6dは5 0x7dは6 0x27は7 // 0x6fは9 0x3fは0 outb (0x00, PRN_PORTC); // 「桁」選択 outb (0x00|0x04, PRN_PORTC); // STROBEをON outb (0x00, PRN_PORTC) // STROBEをOFF outb (0x7f, PRN_PORTD); // 以下右から二桁目点灯 outb (0x01, PRN_PORTC); outb (0x01|0x04, PRN_PORTC); outb (0x01, PRN_PORTC);  ・・・以下四桁目までつづく ret = ioperm(PRN_PORTD, 4, 0); return 0; } 会社の課題でして、上司の指示は、「何桁目にはこの数字を入れる」みたいな関数を作ってスッキリしたソースを見せてくれと。。。 ネットや関連書籍にも記載がありません。 本当に困っています。表示させるマシンの仕様も、上記説明では分からないと思いますが、「私だったらこうします」みたいなサンプルソースを見せて頂けたら幸いです。チョットしたヒントでも歓迎です。 長々と本当に申し訳ないです。ご教授願います。

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★映画「24」は見ていましたが、どんな表示形式か忘れました。 ・もう少し分かりやすい別表現が欲しかった。  要するに単純なデジタル表示にしたいのですよね。 ・main() 関数が2つありますが、上の main()と下の main() 関数の違いは何ですか?  組み込み系のプログラミングには詳しくありませんが、下の main() 関数にある  outb() の第一引数は表示する7セグメント LED の点灯ビットですね。  確認の為に聞きますが、7セグメント LED の上を a とすると時計回りで b、c、d、e、fとなり、  日の中心の横棒が g となりますよね。そして、a~g の対応が次のようになりますよね。  a…0x01  b…0x02  c…0x04  d…0x08  e…0x10  f…0x20  g…0x40  上記であっていますよね。ソースから解読すると。 ●本題 ・アドバイスとしては outb で1桁表示する部分をサブ関数にすれば簡単ですよ。  つまり、  outb( LED, PRN_PORTD );  outb( loc, PRN_PORTC );  outb( loc|0x04, PRN_PORTC );  outb( loc, PRN_PORTC );  上記の4行を1つの関数にして引数に num、loc の2つを受け取るのです。 ・LED は点灯したい LED の点灯ビットで、loc は桁数を表す値です。 サンプル: // 1桁の7セグメント LED を表示する関数 void lightLED( int num, int loc ) {  static int table[] = {   0x3F, // 0   0x06, // 1   0x5B, // 2   0x4F, // 3   0x66, // 4   0x6D, // 5   0x7D, // 6   0x27, // 7   0x7F, // 8   0x6F, // 9  };    outb( table[ num ], PRN_PORTD ); ←table[ num ] で数値から点灯ビットに変換  outb( loc, PRN_PORTC );  outb( loc|0x04, PRN_PORTC );  outb( loc, PRN_PORTC ); } // 時刻表の時:分を表示する関数 void digitalLED( int findtime ) {  int ret, a, b, c, d;    a = ((findtime / 1000) % 10); ←4桁目を取り出す  b = ((findtime / 100) % 10); ←3桁目を取り出す  c = ((findtime / 10) % 10); ←2桁目を取り出す  d = ((findtime / 1) % 10); ←1桁目を取り出す    ret = ioperm( PRN_PORTD, 4, 1 );  lightLED( a, 0x03 ); ←『時』の10桁を表示  lightLED( b, 0x02 ); ←『時』の 1桁を表示  lightLED( c, 0x01 ); ←『分』の10桁を表示  lightLED( d, 0x00 ); ←『分』の 1桁を表示  ret = ioperm( PRN_PORTD, 4, 0 ); } 解説: ・digitalLED() 関数の引数 findtime は時分をパックした整数値です。  つまり、23時59分ならば 2359 という整数値です。 ・digitalLED() 関数は7セグメントの1桁を表示する専用の関数です。  第一引数 num が表示する数字 0~9 ですが、これを点灯ビットに変換する必要があります。  この変換には table[10] を用意してテーブル参照することで簡単に出来ます。  ただし、0~9 までの整数にして下さい。負の値や 10 以上を与えるとどうなるか不明ですよ。 ・なお、サンプルでは分かりやすくするために繰り返し文を使っていません。  実際には for、while 文などで繰り返しで記述すればスッキリします。→digitalLED() を改良。 その他: >int table[] = { // 時刻表  のテーブルには static をつけたほうが良い。つまり、  static int table[] = { // 時刻表   610, …, 951,    :   2319, 2348, -1, //テーブル終印  };  とします。 ・以上。参考に。

onarav
質問者

お礼

いつも親切にありがとうございます。 毎回驚かされます、 とても分かりやすいので。 今回もびっくりしました。 よく上記質問を解読されましたね。 上記ご回答の☆印~●印までの確認されている内容は、おっしゃる通りです。 サブ関数にすることを思い付けないトコが初心者ですね。 staticは静的変数に変える意味を持つんでしたよね。。。たしか。 このご回答を無駄にしないようにがんばります。

onarav
質問者

補足

お世話になってます。 度々すみません。 >第一引数 num が表示する数字 0~9 ですが、これを点灯ビットに変>換する必要があります。 >この変換には table[10] を用意してテーブル参照することで簡単に>出来ます。 新しくテーブを追加するという意味でしょうか? この箇所で考えております。 よろしければご教授願います。

その他の回答 (2)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★新しくテーブルは追加しなくても良い。 ・理由は既にテーブルを lightLED() 関数に用意して記述しているので。  lightLED() 関数内の table[] がそれ。この table[] が変換テーブルですよ。 ・int num に 0~9 の数値を引数で受け取り、table[num] と参照すると  table[0]⇒0x3F  table[1]⇒0x06  table[2]⇒0x5B  table[3]⇒0x4F  table[4]⇒0x66  table[5]⇒0x6D  table[6]⇒0x7D  table[7]⇒0x27  table[8]⇒0x7F  table[9]⇒0x6F  と変換されるのです。0x3F~0x6F は LED の点灯ビットですよ。 ・もう少しサンプルで載せた関数 lightLED()、digitalLED() を読み取ってくれませんか。  そうすれば、変換テーブルは必要なく、既に記述されている分かるんですけど。 ・ついでにコメントも入れてあるしね。 >outb( table[ num ], PRN_PORTD ); ←table[ num ] で数値から点灯ビットに変換  上記の1行が、矢印で変換テーブルを参照しているというコメントですよ。 ・以上。おわり。

onarav
質問者

お礼

おかげで理解しました。 ありがとうございます。

回答No.1

> 上司の指示は、「何桁目にはこの数字を入れる」みたいな関数を作ってスッキリしたソースを見せてくれと。。。 そのまんまやないですか? void display(int column, int value) {  column桁目にvalueを表示する } なんて関数をこしらえればいい。

onarav
質問者

お礼

まんまですね。 ありがとうございます! さっそくやってみます。

関連するQ&A

  • テーブル(配列)の初期化を外部ファイルに指定

    お世話になっております。 以下は列車の時刻表を検索するCのソースです // ヘッダー省略 #define PRN_PORTD 0x0378 #define PRN_PORTC 0x037a void lightLED( int num, int loc ) { static int table[] = { 0x3F, // 0 0x06, // 1 0x5B, // 2 0x4F, // 3 0x66, // 4 0x6D, // 5 0x7D, // 6 0x27, // 7 0x7F, // 8 0x6F, // 9 }; // table[ num ] で数値から変換 printf("num[%x] port[%x]\n loc[%d]",     able[ num ], PRN_PORTD, loc ); // デバックの為 outb( table[ num ], PRN_PORTD ); outb( loc, PRN_PORTC ); outb( loc | 0x04, PRN_PORTC ); outb( loc, PRN_PORTC ); } // 時刻表の時:分を表示する関数 void digitalLED( int time ) { int ret, four, three, two, one; four = ((time / 1000) % 10); // 4桁目を取り出す three = ((time / 100) % 10); // 3桁目を取り出す two = ((time / 10) % 10); // 2桁目を取り出す one = ((time / 1) % 10); // 1桁目を取り出す ret = ioperm( PRN_PORTD, 4, 1 ); lightLED( four, 0x03 ); // 時の10桁を表示 lightLED( three, 0x02 ); // 時の 1桁を表示 lightLED( two, 0x01 ); // 分の10桁を表示 lightLED( one, 0x00 ); // 分の 1桁を表示 ret = ioperm( PRN_PORTD, 4, 0 ); exit(0); } // ここまでのソースはLEDに表示させる関数です int main(void) { char type; int ret; do {     // ↓テーブル初期化。本来はこれを使用したいのですが。 // static int table[] = { ここで外部ファイル指定 }; / int findtime; // 0000形式に変換後の現在時間 int *search; // テーブル内の検索時間 int h; // 時 int m; // 分 FILE *file; time_t timer; // 現在時刻を取得し地方形式に struct tm *local; time(&timer); // 現在時刻の取得 local = localtime(&timer); // 現在時刻を構造体に変換 h = local->tm_hour; // 時 m = local->tm_min; // 分 findtime = h * 100 + m ; // 現在時間を0000形式へ変換 file = fopen( "jikoku.txt", "r" ); if( file == NULL ) { puts( "jikoku.txtが開けません" ); return 1; } while ( !feof(file)) { fscanf(file, "%d", &*search); printf("%d\n", *search); // 該当時間検索 // for ( search = table ; *search != -1 ; search++ ) {   // ↑時刻表を外部ファイルにしたことによって使わなく   //  なったのですが。。。 if ( *search > findtime ){ break; } } // 結果表示 if ( *search == - 1 ) { // テーブル内の-1に当たったら                              //06:10表示       // ↓table[0]の形に要修正 printf( "06:10\n\n" ); digitalLED( 610 ); } else { digitalLED( *search ); printf( "%02d:%02d\n\n", (*search / 100), // 「時」取り出し (*search % 100) ); // 「分」取り出し } fclose(file); scanf("%c", &type); // Enterで再度プログラム開始 } while (type == '\n'); } テーブルの外部ファイルは以下の様な感じです 610 650 ..... 2310 2350 -1 まだ勉強中の初心者です。汚いソースで申し訳ないです。 これでもみなさんに強力して頂きながら数日かけて、やっとここまでできました。 【困っている箇所】 ・この状態ですと、現在時間の「時」が2桁(10~23時)の場合、セグメン テーションエラーですとの表示で実行できなくなります。 ・コメントになってしまっているテーブル初期化を外部ファイル (jikoku.txt)にしたいのですが(teble[0]→6:10 teble[1]→  6:50 ...の様に。)ファイル名を入れたり色々試したのですがなかなかで きません ・テーブル内で-1に当たったら、6:10分を表示させる箇所も、テーブル使い たいのですが、これも自分でコーディングするとコンパイルが通りませ  ん。 長々と申し訳ありません。ご教授願います。 --前回ご覧頂いた方-- 結局期限を明日までにのばしてもらいました。。

  • PICによる7セグLED3桁制御

    PICによる7セグLED3桁制御 度々こちらに、お世話になっております。 今回は、3桁のLEDを1から999までカウント表示する プログラムに取組んでいるところ希望通りに、動いてはくれません。 このソースのベースは2桁(1から99までカウントUP)の ソースコードを変更して、3桁表示させる様にしてみました。 コード概要はtimer0割込みで3.2msのインターバルタイムの間、 LEDをダイナミック点灯させ、timer1では、100msのインターバルタイムを 10回繰り返し(1秒毎に)counterを1プラスしてLEDの表示を1ずつ 増して999まで表示後、また000から繰返すと言う単純な動作のものです。 main()関数内はtimer0とtimer1の割込み設定及び 割込み開始、許可を繰返すだけです。 問題の#timer0,#timer1割込み関数処理部分における実行結果は、 000から111と言う具合に3桁が同時にカウント表示されてしまい、 しかも繰り上がる時間は1秒毎の筈が、100秒毎になります。 このコードはCCS-Cコンパイラに準拠していて、 標準Cとは多少異なる部分があり解りにくいと思いますが どうかどなた様からも検証より不具合コード部分のご指摘と修正を 頂くことが出来るなら、大変光栄に思います。 そこで、PICにおけるconfigu部分は省き、概ねのコードを記します。 //// 1:static long int number; 2:static int counter; 3:int const LED_SEG[11]= {0x7E,0xCC,...略} 4:#int_timer0 5:void isr() { 6:static int a,b,c = 0; 7:int x; 8:out_low(PIN_C0); // LED 1桁目off 9:out_low(PIN_C1); // LED 2桁目0ff 10:out_low(PIN_C2);// LED 3桁目0ff 11:a = number % 10; 12:x = number/10; 13:b = x % 10; 14:c = x / 10; 15:output_b(LED_SEG[a]); 16:output_high(PIN_C0);//1桁目ON 17:output_b(LED_SEG[b]); 18:output_high(PIN_C1);//2桁目ON 19:output_b(LED_SEG[c]); 20:output_high(PIN_C2);//3桁目ON } 21:#int_timer1 22:void isr() { 23:set_timer1(0x0BDC);//100ms再設定 24:counter++; 25:if(counter>9)//10回か { 26:counter = 0; 27:number++; } 28:if(number>1000) { 29:number = 0; } } 30:void main() { 略 31:setup_timer0(3.2msセット) 32:setup_timer1(100msセット) 33:timer0割り込み許可 34:timer1割り込み許可 35:GLOBAL全体割り込み許可 36:while(1){} } //// 以上宜しくお願いいたします。

  • コマンドプロンプト 実行結果の桁をそろえたい

    バッチの実行結果の件数%count%を、5桁の右寄せ(結果が1桁のばあいは、スペース4桁を頭に入れてる)でテキストファイルresult.txt に出力したいのですが、下記のように書くと、 table1 : ("d\n",0) 件  と出力されてしまいます。 table1 :    0 件   と出力されるようにするにはどうしたらよいのでしょうか? for /f %%i in ('mysql -u root -p ^< "c:\bat\test.sql"') do set count=("%5d\n",%%i) echo table1 : %count% 件 >> "c:\bat\result.txt"

    • ベストアンサー
    • MySQL
  • 実行結果を表示させたいです。

    以下のプログラムの計算結果を表示したいのですが、 うまく表示させられません。 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> #define KMAX 100 #define XMAX 300 #define PI 3.14159265358979323846 int main(void) { double ek = PI * 2.0 * 0.7 / XMAX; double a = 2.5 - 1.0; double fmax = 0.0; double fmin = 0.0; double f[XMAX]; int x, k; srand((unsigned)time(NULL)); for(x = 0; x < XMAX; x++){ f[x] = 0.0; for(k = 0; k < KMAX; k++){ double rk = k + 1.0; double kx = ek * rk * x; f[x] += pow((ek * rk), -a) * (ga() * cos(kx) - ga() * sin(kx)); } if(fmax < f[x]) fmax = f[x]; if(fmin > f[x]) fmin = f[x]; } } ga()はランダムな変数です。 どなたか教えてください。

  • 割り込みで並列処理

    ATmega168とWinAVRで割り込みのプログラミングをしています。 #include <avr/io.h> #include <avr/interrupt.h> ISR(TIMER1_OVF_vect) { TCNT1 = 65500; PORTC ^= 0x02; } int main() { int i; DDRC = 0x07; PORTC ^= 0x01; TCCR1B = 0x00; TCNT1 = 65500; TIMSK1 = _BV(TOIE1); TCCR1B = 0x05; sei(); while (1) { PORTC ^= 0x04; for(i=0;i=500;i++){} } } 上記のプログラムを組んでみたのですが。while文に入ってfor文に少し入ってからISRの処理が始まるのですが。ISRの処理が終わってから又for文の処理に戻ろうとしません。なのでPORTC0x04の点滅が起こりません。PORTC0x04の点滅もしながらPORTC0x02の点滅もしたいのですがどうすれば良いのでしょうか?

  • 実行結果を倍精度浮動小数点数(double)で表示させたいです

    C言語の勉強をしている大学生です。 プログラミングをしている中で、質問が3つほど出てきました。 互いに関連しているのでまとめて質問させてください。 無限等比級数を計算するプログラムを作成しました。 これをコンパイルして実行すると、double型で定義しているのに 小数点以下7桁となってしまいます。 doubleは15桁ということなので、15桁で出力したいのです。 これが1つめの質問です。 <実行結果> input n:10 1.500000 1.750000 1.875000 1.937500 1.968750 1.984375 1.992188 1.996094 1.998047 pow関数がmath.hに含まれているのかも定かではなく、 インターネットでmath.hというものがあると書いてあったので、 インクルードしてみましたが、これは適切でしょうか? これが2つめの質問です。 最後になりますが、インターネットで多倍長ライブラリというものが あるということを知りましたが、この使用方法がわかれば具体的な例を 挙げながら教えていただきたいと思います。 ------------------------------------------------------------ #include <stdio.h> #include <math.h> int main(void) { int n; int i; double total; printf("input n:"); scanf("%d",&n); if (n<1){ printf("unable\n"); return 0; } for(i=1; i<n; i++){ total += 1.0 / pow(2.0,i); printf("%f\n",total+1.0); } } ------------------------------------------------------------

  • 32×16ドットLEDマトリクス表示装置をCで動かしたい!

    AKI-H8-3048/Fを使って32×16ドットLEDマトリクス表示装置を動かそうとしています。以前投稿して、そのときの意見やいろんなサイトを参考にCでプログラムを作ってみましたが動きません。 ↓が作ったプログラムです。 #include <3048f.h> #include <stdio.h> /* 待ち時間発生初期化 ************************************/ void timer_init(void){ ITU0.TCR.BYTE = 0x23; ITU0.GRA = 0x07d0; ITU.TSTR.BIT.STR0 = 0; return; } /* 待ち時間発生 引数に、必要なミリ秒を指定する***********/ void wait(int msec){ int i; ITU.TSTR.BIT.STR0 = 1; for(i=0;i<msec;i++){ do{ }while(ITU0.TSR.BIT.IMFA == 0); ITU0.TSR.BIT.IMFA = 0; } ITU.TSTR.BIT.STR0 = 0; return; } /* 表示 ********************************************/ void print(void){ int a=0; int sin1[16]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; int sin2[16]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; int sin3[16]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; while(1){ P1.DR.BIT.B0 =0; wait(100); P1.DR.BIT.B0 =1; wait(100); P1.DR.BIT.B4 =1; for(a=0;a<=16;a++){ P1.DR.BIT.B2 =sin1[a]; P1.DR.BIT.B1 =sin2[a]; P1.DR.BIT.B3 =sin3[a]; } } return; } /* メイン関数 ********************************************/ void main(void){ timer_init(); /* timerの初期化 */ P1.DDR = 0x1f; /* port1出力に設定 */ print(); } 何が違うのかわからないのでご指摘をお願いします。

  • scanf関数のプログラムをgetchar関数で

    scanf関数を使って四則演算、論理輪、論理積をint、float、double型で表示するプログラムを作ったのですが これをscanf関数ではなく、getchar関数で組みなおし、関数化する課題が出ました。 そのままscanf関数のところだけを変えても型が違うというエラーが出てうまくいきません。 どうすればいいでしょうか? 一応scanf関数で組んだプログラムの一部を載せておきます。 #include <stdio.h> #include <math.h> main() { float a , b; float x[5]; printf("正の数字を2つ入力して下さい(小数点を含めて4ケタまで):\n"); for(;;) { printf("\na="); scanf("%f" , &a); if(a>=0 && a<=9999 && a) { break; } else { printf("****aに入力エラー****\n"); printf("数字は4ケタ以内の正数を入力:\n"); continue; } } for(;;) { printf("b="); scanf("%f" , &b); if(b>=0 && b<=9999 && b) { break; } else { printf("****bに入力エラー****\n"); printf("数字は4ケタ以内の正数を入力:\n"); continue; } } x[0] = a+b; x[1] = a-b; x[2] = a*b; x[3] = a/b; x[4] = a||b; x[5] = a&&b; printf("\n"); printf("int型 結果:\n足し算=%d\n" , (int)x[0]); printf("引き算=%d\n" , (int)x[1]); printf("掛け算=%d\n" , (int)x[2]); printf("割り算=%d\n" , (int)x[3]); printf("論理和=%d\n" , (int)x[4]); printf("論理積=%d\n" , (int)x[5]); printf("\n"); printf("float型 結果:\n足し算=%f\n" , x[0]); printf("引き算=%f\n" , x[1]); printf("掛け算=%f\n" , x[2]); printf("割り算=%f\n" , x[3]); printf("論理和=%f\n" , x[4]); printf("論理積=%f\n" , x[5]); ・ ・ ・ getchar(); }

  • c言語の実行結果どうか教えてくださいませ

    double fA(double a) { printf("kansu fA\n'); returna/2.0 } double fB(double b) { double a; printf("kansu fB\n"); a=fA(b); printf("fA(b)=%f\n",a); return a; } int main(void) { fB(210.0); return 0; } 特に小数の表示でございます… 他のサイトでも聞いたのですモヤモヤしまして 何卒宜しくお願いします。

  • 【C言語プログラミング】 time()関数について

    現在の時刻を表示させるプログラムをC言語で作成したいのですが、 書籍などを参考に以下のコーディングを行いました。 #include <stdio.h> #include <time.h> int main(void) { time_t timer; /* 現在の時刻を取得する */ timer = time(&timer); /* 現在の時刻を出力する */ printf("現在の時刻: "); printf("%s", ctime(&timer)); printf("です。\n"); return 0; } 質問内容は以下の通りです。 (1)「time_t timer;」とは、time_t型の変数timerを宣言し、   この変数にはtime()関数で取得した現在時刻の値が入る? (2)「timer = time(&timer);」に関して、time()関数で取得した値   を変数timerが指すアドレスの場所に入れる? その場合、   返り値を格納する変数timerに、time()関数の引数と同じtimerが   指定されているのはなぜ? (3)プログラムを実行すると以下の結果となる。(time.exeを実行)   C:\>time   現在の時刻: 12:52:07.61   新しい時刻を入力してください:   現在の時刻を表示した直後に「新しい時刻を入力して下さい」が   表示される。これはtime()関数の仕様どおり? 以上です。初歩的な質問で申し訳ございませんが、ご回答よろしく お願いいたします。

専門家に質問してみよう