ニキシー管時計の自作方法とプログラムについて

このQ&Aのポイント
  • ニキシー管時計を自作する際のプログラムについて教えてください。
  • ニキシー管時計の自作にはどのようなプログラムが必要ですか?
  • ニキシー管時計の自作方法とプログラムについて詳しく教えてください。
回答を見る
  • ベストアンサー

ニキシー管時計の自作について

ニキシー管時計を自作しているのですか、スイッチ入力のプログラムが分かりません。 #include <16f1938.h> #fuses INTRC_IO,NOWDT,NOPROTECT,NOCPD,NOMCLR,NOPUT,NOBROWNOUT,NOIESO #use delay(clock=16MHZ) // クロック周波数は16MHz #byte RA = 0x0c //RAをポートAのアドレス0Ch番地に設定 #bit MODE_SW = RA.0 #bit UP_SW = RA.1 #bit DOWN_SW = RA.2 #bit NIXI_8 = RA.6 #bit NIXI_9 = RA.7 #byte RB = 0x0d //RBをポートBのアドレス0Dh番地に設定 #byte RC = 0x0e //RCをポートCのアドレス0Eh番地に設定 void io_init(void); // i/o設定関数 signed int sec=56,min=34,hour=12; void disp_nixi(int v); int flag=0; /*-------------------------------------- timer0割り込み 1ms間隔 ---------------------------------------*/ #INT_TIMER0 void timer0(void) { static signed int flag=0; static signed long m_sec=0;//msカウンタ set_timer0(131); //256-125 =131 125* 8us = 1000us //全て消灯 RB=0x00; disp_nixi(10); delay_us(10); m_sec++; if(m_sec>1000){ sec++; m_sec=0; } if(sec>60){ min++; sec=0; } if(min>60){ hour++; min=0; } if(hour>=24){ hour=0; } if(flag<6)flag++; else flag=0; switch(flag){ case 0: disp_nixi(sec%10); RB=0x01;//1桁ON break; case 1: disp_nixi(sec/10); RB=0x02;//2桁ON //RB=0x02;//2桁ON break; case 2: disp_nixi(min%10); RB=0x04;//3桁ON break; case 3: disp_nixi(min/10); RB=0x08;//4桁ON break; case 4: disp_nixi(hour%10); RB=0x10;//5桁ON break; case 5: disp_nixi(hour/10); RB=0x20;//6桁ON break; }//end switch } // end timer0(void) void main(void) { long int flag=0,i; io_init(); while(1){ //ここにプログラムを書きたいです }// end while() } // end main(void) void io_init(void){ setup_oscillator(OSC_16MHZ); // 内部クロックを16MHzに設定 RA=0x00; RB=0x00; RC=0x00; setup_adc_ports(NO_ANALOGS); // ポートAはデジタルI/Oに設定 //timer0の設定 setup_timer_0(RTCC_INTERNAL | RTCC_DIV_32); // 4ck 1命令 4/16M = 0.25us 0.25us*32 : 1ct = 8us タイマ0のモード設定 set_timer0(131); //256-125 =131 125* 8us = 1000us // TRIS_aの設定 A0~A7:入力 1111 1111 A2:sw2 A1:sw1 A1:sw1 set_tris_a(0x3f); // TRIS_bの設定 set_tris_b(0x00); //H-side ドライブ0~5 // TRIS_cの設定 set_tris_c(0x00); //7~4:free  C3~0:L-side ドライブ // TRIS_eの設定 set_tris_e(0xff); enable_interrupts(INT_TIMER0);//tmr0割り込み許可 enable_interrupts(GLOBAL);//グローバル割込み許可 } void disp_nixi(int v){ switch(v){ case 0: NIXI_8 =0; NIXI_9 =0; RC=0b10000000; break; case 1: NIXI_8 =0; NIXI_9 =1; RC=0b00000000; break; case 2: NIXI_8 =0; NIXI_9 =0; RC=0b00010000; break; case 3: NIXI_8 =1; NIXI_9 =0; RC=0b00000000; break; case 4: NIXI_8 =0; NIXI_9 =0; RC=0b00000010; break; case 5: NIXI_8 =0; NIXI_9 =0; RC=0b00000100; break; case 6: NIXI_8 =0; NIXI_9 =0; RC=0b00001000; break; case 7: NIXI_8 =0; NIXI_9 =0; RC=0b00000001; break; case 8: NIXI_8 =0; NIXI_9 =0; RC=0b01000000; break; case 9: NIXI_8 =0; NIXI_9 =0; RC=0b00100000; break; default : NIXI_8 =0; NIXI_9 =0; RC=0b00000000; } } ↑のプログラムのwhile文部分にプログラムを書きたいのですが、 どのようなプログラムを書いたらよいのでしょうか。 教えていただけると助かります。

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

  • ベストアンサー
  • koujikuu
  • ベストアンサー率43% (428/992)
回答No.1

キースイッチはチャタリングがあるので、on/offのみで判別できません  キースイッチonの時間が50mS以上あるか?、次にoffの時間が50mS以上ある時のみ、一回キー入力ありと判別しています (時間はスイッチにより調整します) 具体的には、割り込み内で、カウンタを使い キーon/off 時間を計測し、キー入力フラグを立てています

kowasan
質問者

お礼

なるほど、そうだったのですね。 まだまだ勉強が足りないと改めて感じました。

関連するQ&A

  • PICのマシンのプログラムについての質問です。

    #include <16f873a.h> #fuses HS,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP #define use_portb_lcd TRUE #use delay (clock=10000000) #include <lcd.c> void port_ini(void); void lcd_express(int); void motor_drive(int); main() { int mode; port_ini(); while(1){ mode = (input_a() & 0b00000110); lcd_express(mode); motor_drive(mode); } } void port_ini(void) { setup_adc_ports(NO_ANALOGS); setup_counters(RTCC_INTERNAL,RTCC_DIV_2); port_b_pullups(FALSE); set_tris_a(0xff); set_tris_b(0x00); set_tris_c(0x00); output_b(0x00); output_c(0x00); lcd_init(); } void lcd_express(int disp) { lcd_gotoxy(1,1); lcd_putc("<DC-motor mode>"); delay_ms(5); lcd_gotoxy(1,2); switch(disp){ case 0:{ lcd_putc("- Go!Go! -"); break; } case 2:{ lcd_putc("- L-Bend -"); break; } case 4:{ lcd_putc("- R-Bend -"); break; } case 6:{ lcd_putc("- R-Turn!-"); break; } default: break; } } void motor_drive(int mode) { switch(mode){ case 0:{ output_c(0b00110000); break; } case 2:{ output_c(0b00111000); break; } case 4:{ output_c(0b01110000); break; } case 6:{ output_c(0b01010000); delay_ms(800); while(!(4==(input_a() & 0b00000110))){} output_c(0b00101000); delay_ms(100); break; } default:break; } } この文でlcdに何も表示しないようにしたいのですがどこを消せばいいのでしょうか? あと、void文などもできれば消して動かせるようにしたいのですが、どのようにすればいいでしょうか? ちなみにプログラムは、SW1・2を押しているときに、それぞれ片方タイヤを回転させ、両方押しているときに両方回転させて前進、両方押していないときは後退するというプログラムです。 ×字の台に張られた黒いテープをたどって最終的に真ん中でとまるという競技のプログラムです。 できればlcd関連のプログラムをすべて消したいです。

  • C言語による簡易電卓の作成

    四則演算に加えてべき乗、階乗を使えるような電卓を作りたいのです。 四則演算は #include <stdio.h> #include <ctype.h> void Factor( int *x ); void MulDiv( int *x ); void AddSub( int *x ); int expression( void ); int main( void ) { printf( "%d\n", expression() ); return 0; } void Factor( int *x ) { int num = 0, flag = 1, c = 0; c = fgetc( stdin ); if( c == '-' || c == '+' ){ c = fgetc( stdin ); flag = (c == '+' ) ? 1 : -1; } if( isdigit(c) ){ int n = 0; while( isdigit(c) ){ n = n * 10 + ( c - '0' ); c = fgetc( stdin ); } num = n * flag; }else{ if( c == '(' ){ num = expression(); if( fgetc( stdin ) != ')' ){ exit(-1); } c = 0x0100; } } if( c != 0x0100 ) ungetc( c, stdin ); (*x) = num; } void MulDiv( int *x ) { int num = 0, c = 0; Factor( x ); num = (*x); c = fgetc( stdin ); while( c == '*' || c == '/' || c == '%' ){ switch( c ) { case '*': Factor( x ); num = num * (*x); break; case '/': Factor( x ); num = num / (*x); break; case '%': Factor( x ); num = num % (*x); break; } c = fgetc( stdin ); } ungetc( c, stdin ); (*x) = num; } void AddSub( int *x ) { int num = 0, c = 0; MulDiv( x ); num = (*x); c = fgetc( stdin ); while( c == '+' || c == '-' ){ switch( c ) { case '+': MulDiv( x ); num = num + (*x); break; case '-': MulDiv( x ); num = num - (*x); break; } c = fgetc( stdin ); } ungetc( c, stdin ); (*x) = num; } int expression( void ) { int x = 0; AddSub( &x ); return x; } これで正しく動くことを確認できたのですが、階乗、べき乗の書き方が全くわかりません。どなたか、詳しい方いらっしゃいましたら、ご教授願います。

  • PIC16F877AでRA0をデジタルI/Oに

    PICプログラミング初心者です。 テスト回路を作っていたのですが、下記の回路でRB0のスイッチ入力部をRA0に変更したいのですが いろいろ試してどうしてもRA0ではうまく出来ませんでした。 わかるかた教えて下さい、宜しくお願いします。 //HI-TECH //PIC16F877 LED Momentary SW ON_OFF #include <pic.h> #include <htc.h> #define _XTAL_FREQ 20000000 //セラミック発振子:20MHz ディレイ関数用 __CONFIG( PWRTEN // パワーアップタイマ有 enable power up timer & BORDIS // ブラウンアウトリセット有enable brown out reset & UNPROTECT // コードプロテクト無 use UNPROTECT & WDTDIS // ウォッチドックタイマ無 & LVPDIS // 低電圧プログラミング無 low voltage programming disabled & HS // 外部ハイスピード発振子 EXTRC Oscillator, RC on RA7/OSC1/CLKIN ); short int Led = 0; //LED Mode : LED On_Mode = 1, LED Off_Mode = 0 /*///////////////////////// 1mse ディレー関数 /////////////////////////*/ void delay_ms(unsigned long int msec) { while(msec) { msec--; __delay_ms(1); //1msec delay } } void interrupt ISR(void) { INTE = 0; // ext INT Disable PEIE = 0; //Peripheral INT Disable GIE = 0; // Gloval INT Disable delay_ms(50); if(RB0 == 0)//←ここをRA0に変更したい { if(Led == 0) //if LED Not Lighed { Led = 1; //LED Mode : LED ON Mode RD0 = 0; // LED Turn ON } else //if LED Lighted { Led = 0; //LED Mode : LED OFF Mode RD0 = 1; //RD0 port LED Turn off } } INTF = 0; // LED Flag Clear INTE = 1; // ext INT Enable PEIE = 0; // Peripheral INT Disable GIE = 1; //Gloval INT Enable } int main() { ADCON0 = 0x00; ADCON1 = 0x00; //アナログセレクタ アナログ不使用 TRISA=0b11111111;//入出力設定 A,Bポートすべて入力に TRISB=0b11111111; TRISC=0b10111111;//RC6 = TxDなので出力に。RC7はRxDなので入力にする必要あり。 TRISD=0b00000000; INTEDG = 0; // Down Edge Trigger Led = 0; //LED Mode : OFF Mode RD0 = 1; //RD0 port LED Turn off INTF = 0; //INT Flag Clear INTE = 1; //ext-INT Enable PEIE = 0; // Peripheral INT Disable GIE = 1; // Gloval INT Enable while(1) { } return 0; }

  • C言語でプログラミングし、PICマイコンでLEDを制御する

    現在PICを使ってLEDを制御する事を勉強しています。 3つのLEDを3秒間隔で点灯させ、それを無限に繰り返すプログラムを考えてみました。LEDは一つのポートに一つのLEDを割り振るのではなく、ICを使って制御しています。 これを発展させ、待ち時間の3秒間にRA2ポートに入力があるとLEDの点灯をその場所で停止させ、もう一度RA2ポートに入力するとループが再開するといった内容にしようと考えていますが、調べてもどうすればいいのか分かりません、分かる方は教えて頂けないでしょうか # include <16f84a.h> # fuses HS, NOWDT, NOPROTECT # use delay(clock=20000000) int flag, sec, count; main() //main関数の開始宣言 { set_tris_a(0x10); set_tris_b(0x10); #use fast_io(a) //port_aの高速処理を行う設定 #use fast_io(b) //port_bの高速処理を行う設定 while(1){ //無限ループのwhile文の宣言 output_low(PIN_A0); //RA0の出力 output_low(PIN_B5); //RB5の出力 output_low(PIN_B6); //RB6の出力 output_low(PIN_B7); //RB7の出力 //LED1が点灯 delay_ms( 3000 ) ; //3秒待つ   output_high(PIN_A0); //RA0の出力 output_low(PIN_B5); //RB5の出力 output_low(PIN_B6); //RB6の出力 output_low(PIN_B7); //RB7の出力 //LED2が点灯 delat_ms( 3000 ) ; //3秒待つ        output_low(PIN_A0); //RA0の出力 output_high(PIN_B5); //RB5の出力 output_low(PIN_B6); //RB6の出力 output_low(PIN_B7); //RB7の出力 //LED3が点灯 delay_ms( 3000 ) ; //3秒待つ }

  • 最小値の問題

    平面上に3点A、B、Cがあり、点P(x,y)の周りに60°回転させたときの像をA’、B’、C’とする。 △AA’P+△BB’P+△CC’Pの面積が最小になるときのP(x,y)を求めよ。 という問題なんですが、どうやって求めればいいかわかりません。 とりあえず、3つの三角形はどれも正三角形になって一辺をそれぞれra, rb,rcとすれば、合計面積Sは S=(√(3)/4)(ra^2+rb^2+rc^2)になると思います。ここから相加平均 相乗平均を使うとra^2+rb^2+rc^2=>定数にならず。P(x,y)の関係も見えてきません。 どなたかわかる方がいたら教えていただきたいです。 偏微分なども用いてもらって結構です。 お願いします。

  • realloc関数の使い方

    前回のmalloc関数の使い方の続きみたいな感じです。 参考書にはmalloc関数とcalloc関数については載っていましたがrealloc関数については記述はありませんでした。 realloc関数はメモリの拡張や縮小ができるというみたいなのでdo~while文の中に入れています。 どこが間違っているのでしょうか。 /* 課題3-6 */ #include <time.h> #include <stdio.h> #include <stdlib.h> int user; /* プレーヤの手 */ int comp; /* コンピュータの手 */ int win_no; /* 勝った回数 */ int lose_no; /* 負けた回数 */ int draw_no; /* 引き分けた回数 */ int *a; int *b; int *a1; int *b1; int i; int stage = 0; char *hd[] = {"グー", "チョキ", "パー"}; /* 手 */ /* initialize関数の宣言 */ void initialize(void); /* jyanken関数の宣言 */ void jyanken(void); /* count_no関数の宣言 */ void count_no(int result); /* disp_result関数の宣言 */ void disp_result(int result); /* confirm_retry関数の宣言 */ int confirm_retry(void); /* rireki関数の宣言 */ void rireki(void); /* メイン関数 */ int main(void) { int judge; /* 勝敗 */ int retry; /* もう一度 */ initialize(); /* 初期処理 */ a = (int *)calloc(5, sizeof(int)); b = (int *)calloc(5, sizeof(int)); do{ jyanken(); /* じゃんけん実行 */ /* コンピュータとプレーヤの手を表示 */ printf("私は%sで、あなたは%sです。\n", hd[comp], hd[user]); judge = (user - comp + 3) % 3; /* 勝敗を判定 */ count_no(judge); /* 勝/負/引分け回数を更新 */ disp_result(judge); /* 判定結果を表示 */ retry = confirm_retry(); a1 = (int *)realloc(a, sizeof(int) * (draw_no+lose_no+win_no+1)); b1 = (int *)realloc(b, sizeof(int) * (draw_no+lose_no+win_no+1)); rireki(); }while(retry == 1); for(i=0; i<draw_no+lose_no+win_no; i++){ printf("%d回目 ユーザ%c コンピュータ%c\n", i+1, hd[b1[i]], hd[a1[i]]); } printf("%d勝%d敗%d分けでした。\n", win_no, lose_no, draw_no); free(a); free(b); return (0); } /*--- 初期処理 ---*/ /* initialize関数の定義 */ void initialize(void) { win_no = 0; /* 勝った回数 */ lose_no = 0; /* 負けた回数 */ draw_no = 0; /* 引き分けた回数 */ srand(time(NULL)); /* 乱数の種を初期化 */ printf("じゃんけんゲーム開始!!\n"); } /*--- じゃんけん実行(手の読み込み/生成) ---*/ /* jyanken関数の定義 */ void jyanken(void) { int i; comp = rand() % 3; /* コンピュータの手 (0~2) を乱数で生成 */ printf("\n\aじゃんけんポン …"); for(i=0; i<3; i++) printf(" (%d)%s", i, hd[i]); printf(":"); scanf("%d", &user); /* プレーヤの手を読み込む */ } /*--- 勝/負/引き分回数を更新 ---*/ /* count_no関数の定義 */ void count_no(int result) { switch(result){ case 0: draw_no++; break; case 1: lose_no++; break; case 2: win_no++; break; } } /*--- 判定結果を表示 ---*/ /* disp_result関数の定義 */ void disp_result(int result) { switch(result){ case 0: puts("引き分けです。"); break; /* 引き分け */ case 1: puts("あなたの負けです。"); break; /* 負け */ case 2: puts("あなたの勝ちです。"); break; /* 勝ち */ } } /*--- 再挑戦するか確認 ---*/ /* confirm_result関数の定義 */ int confirm_retry(void) { int x; printf("もう一度しますか … (0)いいえ (1)はい:"); scanf("%d", &x); return (x); } /*--- 履歴の表示 ---*/ /* rireki関数 */ void rireki(void) { a1[stage] = comp; b1[stage] = user; stage++; }

  • switch文で文字を比較することは出来ませんか?

    switch文で文字を比較することは出来ませんか? 例えば… int main(void){ char buf[5]; buf = 'b'; switch(buf){ case 'a': ・  ・  ・  break; case 'b': ・  ・  ・  break; }

  • 矢印キーの反応が悪くなります

    このコードをmain関数とキーコントロール関数とに分けたところ、 キーのレスポンスがわるくなりました。 このソースコードをどのように分割すれば一つのファイルで書いたように、 動いてくれるのかわかりません。 よろしくお願いします。 /* 分割前のソースコード */ #include <stdio.h> #include <conio.h> int main(int argc, char *argv[]){ int key=0; while(key!='q'){ //終了キー 'q' key=_getch(); //Keyによって分岐 switch((key == 0x00 || key == 0xe0) ? _getch(): key) { case 0x48:printf("上");break;//上 case 0x50:printf("下");break;//下 case 0x4b:printf("左");break;//左 case 0x4d:printf("右");break;//右 default:break; } } return 0; } /*--ここから下が分割してみたソースコード---*/ /* arrowkey.h */ #ifndef ARROWKEY_H #define ARROWKEY_H int arrowkey(void); #endif //ARROWKEY_H /*---------------------------------*/ /* arrowkey.c */ #include <stdio.h> #include <conio.h> #include "arrowkey.h" int arrowkey(void){ int key=_getwch(); //Keyによって分岐 switch((key == 0x00 || key == 0xe0) ? _getch(): key) { case 0x48:printf("上");break;//上 case 0x50:printf("下");break;//下 case 0x4b:printf("左");break;//左 case 0x4d:printf("右");break;//右 case 0x71:break;//終了 default:break; } return key; } /*---------------------------------*/ /* main.c */ #include "arrowkey.h" int main(int argc, char *argv[]){ int key=0; while(key!='q'){ //終了キー 'q' key=arrowkey() } return 0; }

  • ボールが勝手に動き困ってます。

    前回にひき続き困ってます>< タイトル画面→(Enterクリック)→ゲーム画面までできたんですが ゲーム画面でボールとタイマーを動かしたくてやってみるとタイマーはうまく いったのにボールが動く速度を変更できず、勝手に動いてしまいます><どう 改善すればいいでしょうか。ソースコードみにくいですが助言お願いします。 import java.awt.Color; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class JavaGame3 { public static void main(String age[]) { JFrame frame = new JFrame(); frame.setTitle("ゲームフレーム"); frame.setSize(500, 550); frame.setLocation(1000, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Testpanel panel = new Testpanel(); frame.add(panel); frame.setVisible(true); } } class Testpanel extends JPanel implements Runnable{ private Ball[] balls; static final int TITLE = 0; static final int GAME = 1; private int mode; private int sec; private Timer timer; private Thread t; public Testpanel() { balls = new Ball[5]; java.util.Random rr = new java.util.Random(); for(int i=0; i<balls.length; i++) balls[i] = new Ball(10*i+6,10*i+31,rr.nextInt(5)+1, rr.nextInt(5)+1); sec = 0; setBackground(Color.black); addKeyListener(new JavaKeyListener()); setFocusable(true); timer = new Timer(1000, new JavaActionListener()); mode = TITLE; t = new Thread(this); } class JavaActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (sec == 30) { timer.stop(); } else { sec++; } } } private void drawTitle(Graphics g) { g.setColor(Color.blue); g.drawString("タイトル", 165, 150); g.setColor(Color.white); g.drawString("Hit Enter Key!", 150, 350); } public void drawGameOver(Graphics g) { g.setColor(Color.white); g.setColor(Color.red); g.drawString(sec + "sec", 230, 300); repaint(); for (int i=0; i<balls.length; i++) balls[i].draw(g); } protected void paintComponent(Graphics g) { super.paintComponent(g); if(mode == TITLE) { drawTitle(g); } else if(mode == GAME) { drawGameOver(g); } } class JavaKeyListener implements KeyListener { public void keyPressed(KeyEvent e){ int key = e.getKeyCode(); if(mode == TITLE) { switch(key) { case KeyEvent.VK_ENTER: mode = GAME; timer.start(); t.start(); sec = 0; break;} } else { switch (key) { case KeyEvent.VK_ENTER: mode = TITLE; break; } }repaint(); } public void keyReleased(KeyEvent e){} public void keyTyped(KeyEvent e){} } public void run() { while(true) { try { Thread.sleep(100); } catch (Exception e) {} repaint(); } } } class Ball { private int x, y, vx, vy, r; public Ball(int x, int y, int vx, int vy) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; r = 30; } public void draw(Graphics g) { g.fillOval(x, y, r, r); x += vx; y += vy; if(x < 0 || x > 457) vx = -vx; if(y < 0 || y > 433) vy = -vy; } }

    • ベストアンサー
    • Java
  • mainクラス内に書いたメソッドの宣言の仕方(staticの必要性)

    java を勉強中の超初心者です、宜しくお願いします。 main と同じクラスに disp というメソッドを作成してやり、” void disp(int a , int b )”と書いてやりましたが、mainからアクセス出来ません。 そこで、” static void disp(int a , int b )” という風に” static ” を先頭につけてやりましたら、うまく動きました。 これは、mainメソッドから他のメソッドにアクセスする場合には、必ず” static ” をつけてやる必要があるということでしょうか。 ======================================================= class クラス練習 { public static void main(String[] args) { disp(5,10); } /*static*/ void disp(int a , int b ) { System.out.println("a+b = " + (a+b)); } }

    • ベストアンサー
    • Java

専門家に質問してみよう