秒数が出ないのですがどこが違うのでしょうか?
#define TCNT0 (*(volatile unsigned int *)0xffff68)
#define GRA0 (*(volatile unsigned int *)0xffff6a)
#define GRB0 (*(volatile unsigned int *)0xffff6c)
#define TCR0 (*(volatile unsigned char *)0xffff64)
#define TIOR0 (*(volatile unsigned char *)0xffff65)
#define TIER0 (*(volatile unsigned char *)0xffff66)
#define TSR0 (*(volatile unsigned char *)0xffff67)
#define TSTR (*(volatile unsigned char *)0xffff60)

#define ITU_CLOCK8 3
#define ITU_CLEAR_GRA 32
#define ITU_IE_IMFA 1

#define DI asm( "orc.b #0xc0,ccr" )
#define EI asm( "andc.b #0x3f,ccr" )

void start_itu0();
void int_imia0(void) __attribute__ ((interrupt_handler));

int cnt = 0, sec = 0, min = 0, hour = 0;
char str[] = "timer 00:00:00";

int main(void)
{
lcd_init();
lcd_puts(str);
start_itu0();
EI;
for(;;) {
if (cnt >=100) {
cnt = 0;
sec++;
if (sec >=60) {
sec = 0;
min++;
if (min >= 60) {
min = 0;
hour++;
if (hour >= 24) hour = 0;
}
str[6] = '0' + hour /10;
str[7] = '0' + hour %10;
str[9] = '0' + min /10;
str[10] = '0' + min %10;
str[12] = '0' + sec /10;
str[13] = '0' + sec %10;
lcd_home();
lcd_puts(str);
}
}
}
return 0;
}

このQ&Aに関連する最新のQ&A

A 回答 (5件)

がると申します。


えっと………。
lcd_initとかlcd_putsとか拝見するに、かなりハードよりのプログラムだと思うのですが。
とりあえずまず「普通に動くCプログラム」を書いてからのほうがよろしいように思われますがいかがなものでしょうか。

で、#1さんのおっしゃるとおり、拝見しているロジックの限りでは
・cntをインクリメントしていないのでそもそも無限ループしっぱなしで処理が続かない
です。このプログラムで「カウントはしてくれ」というのが非常に不思議です(或いは違うソースで動いてませんか?)
あと、インクリメントがあると仮定して、直接的に秒がちゃんと動かないのは
・文字列を作成する処理が
  if (sec >=60) {
   sec = 0;
 という処理の内側にいるので、文字列作成のタイミングでは常に0しか入り得ない。

のが原因です。

まずは、ループとかifのネストとかをもう少し整理されることを強くお勧めいたします。
    • good
    • 0
この回答へのお礼

返信が遅れてすみませんでした!!
もう少し自分なりに勉強してみます!
ありがとうございました☆

お礼日時:2006/02/25 11:35

>カウントはしてくれ、minとhourは出るのですが


>secだけでないのですが???

ということなので、cntは別プロセスでインクリメントされているのでしょう。
#ほかの方の指摘にあるように、
#volatile指定がなくて平気ですか?

で、secだけ【出ない】。出ないというのは
表示されないのか、常にゼロが出力されるのか。

質問や補足があいまいなので推測ですが、たぶん
表示されないのでしょう。

であれば問題は、lcd_puts(const char*); の中じゃないですか?
    • good
    • 0
この回答へのお礼

自分なりに一から勉強してみます!!
そのとき躓いたらまたお願いします!
ありがとうございました☆

お礼日時:2006/02/25 11:41

ソースを見た感じでは、H8用のGCCですよね。



encyさんのご指摘どおり、
if (sec >= 60)
のときしか表示を更新しないので、secは常に0になりますね。

そして、もう一つ問題があります。
H8/300Hとみなして、-O2オプションを付けてコンパイルすると、

  mov.w  @_cnt,r2
  mov.w  @_sec,r3
  mov.w  #10,r4
.L13:
  cmp.w  #99,r2
  ble .L13

となってしまい、割り込み処理でcntを更新しても反映されません。
割り込み処理や他のタスクと変数を共有する場合は、必ずvolatileをつけましょう。
    • good
    • 0
この回答へのお礼

そうです!H8/3052Fです☆
基礎から勉強して出直してきます!
ありがとうございました☆

お礼日時:2006/02/25 11:39

sec が表示されない理由は、No2 galludaさんの回答のとおりですね。


LCD に表示させる (と勝手に思い込んでいますが。。。) 箇所を、もう一度よく見直してみてください。
60s に 1回しか通らないことがわかると思います。

ところで、cnt についてですが、これは私の勝手な予想です。
おそらく 10ms 周期で割込みが入って、そのハンドラの中で cnt がインクリメントされているのでしょう。

最初にある volatile なポインタ経由でレジスタアクセスしそうなマクロもそうですが、lcd_****() などというコードを見て、なんとなく組込み機器のソースのような気がしました。

# 私も、組込み屋さんなものでして。。。
    • good
    • 0
この回答へのお礼

返信が遅れてすみません!!
土台を作らないままプログラミングをしているのでもう少し勉強します!
ありがとうございました☆

お礼日時:2006/02/25 11:37

cntのインクリメントがないように見えますが。

この回答への補足

カウントはしてくれ、minとhourは出るのですがsecだけでないのですが???

補足日時:2006/02/23 20:57
    • good
    • 0

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

このQ&Aと関連する良く見られている質問

Qchar *str; と char* str;

char *str; と char* str;
どっちも同じことを意味しているんですか?

Aベストアンサー

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染むのでしょう。ちなみにそういう風な人たちは

char *str1, *str2;

とは、書けない体になっています。

char* str1;
char* str2;


変数の宣言だと、C に慣れていれば、char* str というのはちょっと違和感があるのは
私も分かりますが、関数のプロトタイプ宣言だと、どちらの方がすっきりしますか?

extern char *memcpy(char *, const char *);

extern char* memcpy(char*, const char*);


# まあ、どっちが正しい、っていうんじゃ無いんですよね

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染む...続きを読む

Qdc.TextOut(0 ,0 , *str) ;について

環境 WIN98 VC++6.0 MFC にて

パターンBはOKですが、パターンAだと不正な処理で落ちてしまいます。

どうしてなのかお教えください。

void CFffView::OnPaint()
{
CPaintDC dc(this);
//パターンA
CString* str ;
str = (CString*)("999");
dc.TextOut(0 ,0 , *str) ;

//パターンB
CString aaa ;
aaa = (CString)("999");
dc.TextOut(0 ,0 , aaa) ;
}

Aベストアンサー

両方ダメ。
Aのパターンで動くのは、たまたま。

CString aaa ;
aaa = "999";
dc.TextOut(0 ,0 , aaa) ;

これで十分。

あえてキャストするんだったら、
CString aaa ;
aaa = (LPCSTR)"999";
dc.TextOut(0 ,0 , aaa) ;


aaa=のところでは、ただの代入が行われているわけではありません。
オーバーロードされたオペレータが呼ばれています。


>str = (CString*)m_array.GetAt(i) ;

これは、m_arrayの要素にCString*を入れていて、初めて成り立つ式です。
値をいれているところと、m_arrayの宣言を確認してください。

str = (CString*)("999");
も、
aaa = (CString)("999");
も、リテラル文字列をつっこもうとしています。
リテラル文字列とCStringはまったく別物です。

QH8マイコン C言語でのプログラミング *((volatile unsigned char *)ってなんですか??

現在、ある参考書に載っている、マイコンを用いてマザーボード上のLEDを点滅させるCのプログラムを勉強のために見ています。

その中に、

#define P5DDR (*(volatile unsigned char *)0xfffc8)

という一行があるんですが、この中の*(volatile unsigned char *)という表現を見たことがなくて困っております。これは簡単に言うと、

#define P5DDR *0xfffc8

と、『P5DDRを0xfffc8のポインタで置き換える』と言い換えていいのでしょうか??

Aベストアンサー

#define P5DDR (*(unsigned char *)0xfffc8)
なら、解りますか?

P5DDR = 0x00ff;
とかかれた場合、H8のPort5 DDRに0x00ffを書き込めという意味になります。
0xfffc8番地に0x00ffを書けというのと等価ですね。

さて、volatileのほうなのですが、「最適化をするな」という意味になります。

int i;

for (i = 0; i < 10; i++) {
P5DDR = 0x00ff;
}
と書いた場合、賢いコンパイラーは、この3行を
P5DDR = 0x00ff;
だけに置き換えてしまいます。
ハードウエアレジスタの場合、意味あって複数回同じ値を書かせる場合もあるのに、コンパイラーのほうが気を利かせて、論理的に無駄な部分を省略してしまうのです。
この動作を禁止するのが、volatileです。

Q#define NULL ((void *)0) の弊害

よく話題にされるヌルポインタについての疑問です。

定数の0は、それがポインタと解されるべき文脈では
ヌルポインタに読み替えられますが、
可変長引数のようにポインタであることがコンパイラには判断できない文脈では、
明示的にキャストしてやらなければなりません。
このとき、#define NULL 0 と定義されている処理系では、
NULLを使っても定数の0を書いたのと全く同じであり、
上のような場合におけるキャストの必要性からは逃れられません。
しかし、たまたま自分の処理系で
#define NULL ((void *)0) と定義されていれば、
キャストを行わなくてもNULLを使うことによって正しく動いてしまいます。
ということは、#define NULL ((void *)0) と定義された処理系しか
使ったことの無いプログラマは、
「NULLを使うこと自体が、これはポインタだよという意志表示になる」
と錯覚してしまう危険性をはらんでいることになります。
この人の書いた「NULLを使い、必要なキャストを省略しているソース」を、
#define NULL 0 と定義された処理系でコンパイルすると
正しく動作しない可能性があります。

こういう弊害があるにもかかわらず、
ANSI Cでは #define NULL 0 のほかに
#define NULL ((void *)0) も許しているのは、
一体なぜなのでしょうか。
メリットもあるのでしょうか?

よく話題にされるヌルポインタについての疑問です。

定数の0は、それがポインタと解されるべき文脈では
ヌルポインタに読み替えられますが、
可変長引数のようにポインタであることがコンパイラには判断できない文脈では、
明示的にキャストしてやらなければなりません。
このとき、#define NULL 0 と定義されている処理系では、
NULLを使っても定数の0を書いたのと全く同じであり、
上のような場合におけるキャストの必要性からは逃れられません。
しかし、たまたま自分の処理系で
#define NULL ((voi...続きを読む

Aベストアンサー

(1)
> ポインタと数値との内部構造の共通性から
> 結果として正しく動く、という意味でよろしいでしょうか?
その解釈でよいと思います。
私は「NULLは0または0Lと同一構造をもつ無効ポインタ」という解釈で使っています。

(2)
> すなわちNULLをキャスト無しで用いて大丈夫な場合が無くなってしまうのでしょうか?
例えばintel16bit系ではコンパイラが「デフォルトポインタ構造」を提供します。
メモリモデルと呼ばれるもので、コンパイルオプションによって16bitポインタと32bitポインタが指定可能です。
デフォルトポインタ構造を持つ無効ポインタをNULLと表現することは可能になります。
しかし、コンパイルオプションで16bitポインタを指定している場合でも、32bitポインタが必要なことがあり、この場合は適切なキャストが必要です。
他の処理系でも同様な措置によって「多くの場合はNULLが利用可能」と言うことになるでしょう。
しかし、「デフォルトのポインタ構造が可変」という状況はポータビリティーを阻害する可能性があることは間違いありません。

(1)
> ポインタと数値との内部構造の共通性から
> 結果として正しく動く、という意味でよろしいでしょうか?
その解釈でよいと思います。
私は「NULLは0または0Lと同一構造をもつ無効ポインタ」という解釈で使っています。

(2)
> すなわちNULLをキャスト無しで用いて大丈夫な場合が無くなってしまうのでしょうか?
例えばintel16bit系ではコンパイラが「デフォルトポインタ構造」を提供します。
メモリモデルと呼ばれるもので、コンパイルオプションによって16bitポインタと32bitポインタが指定可能で...続きを読む

Qint i,j; \n i=0,j=5;

int i,j;
i=0;
j=5:
と書いてあるソースは普通ですが、
int i,j;
i=0,j=5:
と書いてあるソースもあります。
後者はC++の正しい書式ですか?

カンマ演算子というのは後者のカンマのことですか?

Aベストアンサー

 正しい書式です。

i=0,j=5;
 における、「,」をカンマ演算子といいます。2項の演算子です。カンマで区切られた演算を「左から順番に」実行し、最後の演算を結果として返します。
 したがって、例の文であれば、i=0を実行し、次にj=5を実行。そして、j=5の結果の5を結果として返します。
 ・・・
 が、本来的には、あまり、例のような使い方はしませんね。よく見られるのは、次のような場合です。

 for (i=0,j=0 ; i < 50 ; ++i,++j) {

 のような形でよく見られます。for文の各式は、一つの式でなければならないので、こんな書き方をするわけです。初期化と更新部が一つにまとまり、ループが読みやすくなるのが利点かな。


人気Q&Aランキング

おすすめ情報