アプリ版:「スタンプのみでお礼する」機能のリリースについて

おせわになってます。勉強中かなり初心者です。

映画「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;
}
会社の課題でして、上司の指示は、「何桁目にはこの数字を入れる」みたいな関数を作ってスッキリしたソースを見せてくれと。。。

ネットや関連書籍にも記載がありません。
本当に困っています。表示させるマシンの仕様も、上記説明では分からないと思いますが、「私だったらこうします」みたいなサンプルソースを見せて頂けたら幸いです。チョットしたヒントでも歓迎です。
長々と本当に申し訳ないです。ご教授願います。

A 回答 (3件)

★映画「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, //テーブル終印
 };
 とします。
・以上。参考に。

この回答への補足

お世話になってます。
度々すみません。

>第一引数 num が表示する数字 0~9 ですが、これを点灯ビットに変>換する必要があります。
>この変換には table[10] を用意してテーブル参照することで簡単に>出来ます。

新しくテーブを追加するという意味でしょうか?
この箇所で考えております。

よろしければご教授願います。

補足日時:2007/05/16 17:53
    • good
    • 0
この回答へのお礼

いつも親切にありがとうございます。

毎回驚かされます、
とても分かりやすいので。

今回もびっくりしました。
よく上記質問を解読されましたね。

上記ご回答の☆印~●印までの確認されている内容は、おっしゃる通りです。

サブ関数にすることを思い付けないトコが初心者ですね。

staticは静的変数に変える意味を持つんでしたよね。。。たしか。

このご回答を無駄にしないようにがんばります。

お礼日時:2007/05/16 01:22

★新しくテーブルは追加しなくても良い。


・理由は既にテーブルを 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行が、矢印で変換テーブルを参照しているというコメントですよ。
・以上。おわり。
    • good
    • 1
この回答へのお礼

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

お礼日時:2007/05/16 21:42

> 上司の指示は、「何桁目にはこの数字を入れる」みたいな関数を作ってスッキリしたソースを見せてくれと。

。。

そのまんまやないですか?

void display(int column, int value) {
 column桁目にvalueを表示する
}

なんて関数をこしらえればいい。
    • good
    • 0
この回答へのお礼

まんまですね。

ありがとうございます!

さっそくやってみます。

お礼日時:2007/05/16 00:43

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!