• 締切済み

H8マイコンでC言語で、パルスモータを制御

パルスモータを使用した、自動車のパワーウィンドウシミュレートプログラムを作成したいのですが、if文の書き方がわかりません。 1.プログラム開始時、窓が閉まっている状態を想定。2.完全に閉じた状態から左回りに5回転したときの状態を完全に開いた状態とする。3.完全に開いた状態から右回りに5回転したときに、窓が完全に閉じた状態となる。 キー入力は、A :左回り全開:窓が完全に閉じた状態(5回転目)になるまで左回転し、停止。B :左回り部分開:キー押下時に左回転。キーを離す、窓が完全に閉じた状態になったら停止。C :右回り部分閉:キー押下時に右回転。キーを離す、窓が完全に開いた状態になったら停止。D :右回り全閉 :窓が完全に開いた状態(5回転目)になるまで右回転し、停止。 ヒントを教えてください。お願いします。 #include <stdio.h> #include <key.h> /* 外部ポート A1,B1,C1 */ #define EPA1 (*((unsigned char *)0x60000)) #define EPB1 (*((unsigned char *)0x60001)) #define EPC1 (*((unsigned char *)0x60002)) #define EPCW1 (*((unsigned char *)0x60003)) void wait(long); void counterclockwise (void); void clockwise (void); unsigned char Keydat, count, cf, state; int cwpuls,ccwpuls; void main(){ //開始時は、窓が閉じている状態 state = 0; //回転数を初期化 count = 0; /* uPD71055(82c55) 初期化 */ init_key(); Keydat = 0; cf = 0; while (1) { if((Keydat = get_key_code())==KEY_A){ //左回り全開 clockwise(); //全開(5回転目)になったら停止 EPC1 = 0; /* 一度電流OFF */ wait(90000);/* 時間まち */ } else if (Keydat == KEY_B){ //左回り部分開 clockwise(); //全開(5回転目)になったら停止 EPC1 = 0; /* 一度電流OFF */ wait(90000);/* 時間まち */ } else if (Keydat == KEY_C){ //右回り部分閉 counterclockwise(); //全閉(5回転目)になったら停止 EPC1 = 0; wait(90000); } else if (Keydat == KEY_D){ //左回り全閉 counterclockwise(); //全閉(5回転目)になったら停止 EPC1 = 0; wait(90000); } } } void wait(long time) { long i; for (i = 0; i < time; i++) ; } void counterclockwise (void){ for (cwpuls = 0; cwpuls < 96; cwpuls++){/* CW方向96パルス回す*/ cf++; if (cf == 4) { cf = 0; } /* 励磁相カウンタ+1*/ switch (cf) { case 0:EPC1 = 0x50; /* 励磁パターン出力 */ break; case 1:EPC1 = 0x60; break; case 2:EPC1 = 0xa0; break; case 3:EPC1 = 0x90; break; } wait(1000); // モーター速度 } } void clockwise (void){ for (ccwpuls = 0; ccwpuls < 96;ccwpuls++){/* CCW方向96パルス回す*/ cf--; if (cf == 0xff) { cf = 3; } /* 励磁相カウンター -1 */ switch(cf) { case 0:EPC1 = 0x50; /* 励磁パターン出力 */ break; case 1:EPC1 = 0x60; break; case 2:EPC1 = 0xa0; break; case 3:EPC1 = 0x90; break; } wait(1000); //200~500が限界 } }

みんなの回答

  • Interest
  • ベストアンサー率31% (207/659)
回答No.5

度々登場、失礼します。今度は細かい話です。 ご質問のタイトルには「H8マイコンで」とありますが、ソースコードを見る限りではH8に関係ありそうなコードが見当たりません。ヘッダファイルにすらH8の影が無いのに、動くのでしょうか? ステッピングモータを回す以前に、LED1個を狙った周期で点滅させるプログラム、書けてますか?動かせてますか?<組み込み系のHello world見たいなものですね それから、突然 #include <key.h> というものが出てきているのですが、どこのCコンパイラを使っているのですか? ポートの定義ですが、 #define EPA1 (*((unsigned char *)0x60000)) これ、 #define EPA1 (*((volatile unsigned char *)0x60000)) としましょう。volatile は、コンパイラに最適化禁止を指示します。 これがないと、例えば EPA1 = 0x00; EPA1 = 0x01; EPA1 = 0x00: という処理を行わせようと思ったのに、コンパイラが最適化してしまって、 EPA1 = 0x00; に省略されてしまうおそれがあります。 同様に、ここで出てきたwait関数もコンパイラの最適化によって動作が変わるおそれ大。 void wait(long time) { long i; for (i = 0; i < time; i++) ; } これが、何もしない無駄ループと見做されて省略されるからです。 それに、この関数、時間の単位は何ですか? ちゃんとやるならH8が持っているタイマー(例えばウォッチドッグタイマをインターバルモードで使用するとか)の割り込みで正確に時間を作りましょう。 続いて大切なステッピングモータ(=パルスモータ)の駆動方法。普通は励磁パターンをテーブルにしておき、タイマ割り込み毎にポインタの移動を移動させて励磁パターンを変化させます。ステッピングモータを扱う上で忘れちゃいけないのがスローアップ・スローダウン。これをやらないと簡単に脱調します。加速テーブルを使ったH8でのステッピングモータ制御プログラムのサンプルが http://www.robotics.ee.shibaura-it.ac.jp/micromouse/ に載っていますので参考にしてみてください。

全文を見る
すると、全ての回答が全文表示されます。
  • Interest
  • ベストアンサー率31% (207/659)
回答No.4

ANo.3 投稿後に早速間違い発見してしまいました。ごめんなさい。 【改定】 PFUNC stateTransitionTable[ STATE_NUM ][ EVENT_NUM ] = { // EV_AUTO_OPEN EV_MANUAL_OPEN EV_MANUAL_CLOSE EV_AUTO_CLOSE   { nothing,      nothing,        manualClose,       autoClose }, // ST_FULL_OPEND   { autoOpen,     manualOpen,     manualClose,      autoClose } // ST_HALF_OPEND   { autoOpen,    manualOpen,     nothing,           nothing } // ST_CLOSED }; 修正もテーブルだけですむから簡単! という例だと思ってください(汗)

全文を見る
すると、全ての回答が全文表示されます。
  • Interest
  • ベストアンサー率31% (207/659)
回答No.3

ANo.1 = Interest です。ナイスフォローありがとうございます >DT200様 switch-case を使った例をANo.2で示していただきましたが、状態の数、イベントの数が増えるとメンテナンスが非常に煩雑になります。そこで、関数へのポインタを活用すると、メンテナンスがずっと楽になります。(ちょっとハイレベルなやり方です。) たとえば、ANo.1の状態遷移表を関数へのポインタ(のテーブル)で実装すると、 enum STATE { ST_FULL_OPEND, ST_HALF_OPEND, ST_CLOSED, STATE_NUM }; enum EVENT { EV_AUTO_OPEN, EV_MANUAL_OPEN, EV_MANUAL_CLOSE, EV_AUTO_CLOSE, EVENT_NUM }; typedef void ( * PFUNC ) ( STATE *state ); void nothing(STATE *state){ return; } void autoOpen(STATE *state) { (窓を全部開ける処理);  state = ST_FULL_OPEND; } void manualOpen(STATE *state) { (窓をちょっとだけ開ける処理);  if(窓が全部開いたら)    state = ST_FULL_OPEND;  else    state = ST_HALF_OPEND; } void manualClose(STATE *state) { (窓をちょっとだけ閉める処理);  if(窓が全部閉まったら)    state = ST_CLOSED;  else    state = ST_HALF_OPEND; } void autoClose(STATE *state) { (窓を全部閉める処理);  state = ST_CLOSED; } PFUNC stateTransitionTable[ STATE_NUM ][ EVENT_NUM ] = { // EV_AUTO_OPEN EV_MANUAL_OPEN EV_MANUAL_CLOSE EV_AUTO_CLOSE   { nothing,     manualOpen,     manualClose,     autoClose }, // ST_FULL_OPEND   { autoOpen,     manualOpen,     manualClose,    autoClose } // ST_HALF_OPEND   { autoOpen,    manualOpen,     manualClose,     nothing } // ST_CLOSED }; STATE state = ST_CLOSED; EVENT evetn; for(;;){   event = getKeyCode();   stateTransitionTable[ state ][ event ]( &state ); } ANo.2同様、動作は未確認。処理構造を示すための擬似コードだと思ってください。また、この例ではイベント名とアクション名を同じにしてしまいましたが、一般論では別になると思ってください。 ステートマシンの要素は、 「状態、イベント、アクション、遷移後の状態」 です。 まず、enum を使って状態とイベントを定義しつつ、状態とイベントの数がそれぞれいくつになるかコンパイラに数えさせます。 つづいて、アクションを実行する関数へのポインタの型を作ります。状態遷移後にどの状態を取るかはアクション依存なので、状態(state)を関数内で参照、変更できるように引数としてポインタをもらってくることにします。 アクションを実行する関数は、適当に(笑) 関数の終わりで状態を変更してあげます。 状態遷移テーブルは、見てわかるとおり素直に作ります。そのほうが、メンテナンスが楽ですし、わかりやすいからバグが乗りにくい。 実際に状態とイベントからアクションを選択実行するところは恐ろしくシンプルです。switch-case を使うと分岐の数だけCPUの処理ステップが必要ですが、関数ポインタのテーブルなら1ステップで実行する関数が決まります。 ほかにも、 volatile つけろ! とか、 無限ループで待ち時間を作ったらコンパイラに無視されるよ!とか いろいろ突っ込みどころがありますが、それはおいおい指摘していきます。

全文を見る
すると、全ての回答が全文表示されます。
  • DT200
  • ベストアンサー率38% (63/164)
回答No.2

ANo1さんの続き。 ちなみに反時計回り(左回り)をCCW、時計回り(右回り)がCWです。 clockwise()とcounterclockwise()が96パルス一度に出力するのではなく、 引数に設定されたパルス数を出力するようにする。として、一つの例。 条件: 脱調はないものとします。 #define PLUSE_LIMIT 96 /* 96パルスで5回転とする */ pluse_num = 0; state = CLOSED; event = 0; for(;;){   event = get_key_code();   switch( state ){   case FULL_OPEND:     if( event == AUTO_CLOSE ){       CCW( PLUSE_LIMIT );       state = FULL_CLOSED;       pluse_num = 0;     }     else if( event == MANUAL_CLOSE ){       CCW( 1 );       pluse_num -= 1;       if( pluse_num == 0 ){         state = FULL_CLOSED;       }       else{         state = HALF_OPEND;       }     break;   case HALF_OPEND:     if( event == AUTO_OPEN ){       CCW( PLUSE_LIMIT - pluse_num );       state = FULL_OPEND;       pluse_num = PLUSE_LIMIT;     }     else if( event == MANUAL_OPEN ){       CCW( 1 );       pluse_num += 1;       if( pluse_num < PLUSE_LIMIT ){         state = HALF_OPEND;       }       else{         state = FULL_OPEND;       }     }     else if( event == MANUAL_CLOSE ){       CW( 1 );       pluse_num -= 1;       if( pluse_num == 0 ){         state = FULL_CLOSED;       }       else{         state = HALF_OPEND;       }     }     else if( event == AUTO_CLOSE ){       CW( pluse_num );       state = FULL_CLOSED;       pluse_num = 0;     }     break;   case CLOSED:     if( event == AUTO_OEPN ){       CW( PLUSE_LIMIT );       state = FULL_OPEND;       pluse_num = PLUSE_LIMIT;     }     else if( event == HALF_OPEND ){       CW( 1 );       pluse_num += 1;       if( pluse_num < PLUSE_LIMIT ){         state = HALF_OPEND;       }       else{         state = FULL_OPEND;       }     }   } } ------------------------------------------------------------- 当然、動作の検証を行なっていません。よって、動作保証はできませんし、 細かいところがだめかも知れません。 雰囲気だけでも。 実際は、FULL_OPENDとFULL_CLOSEDの直前にセンサを設けると思います。 その場合、その制御が加わります。

全文を見る
すると、全ての回答が全文表示されます。
  • Interest
  • ベストアンサー率31% (207/659)
回答No.1

こんにちは。 ダメなところが多すぎて一度には直しきれませんが、一番大きいところから攻めて行きましょう。まずはプログラム全体の考え方のベースとなる状態遷移について考えます。 とりあえず、「状態遷移表」「ステートチャート」「ステートマシン」などをweb上で検索して、何の話をしているのか調べてみてください。その上で、上記の問題を次のように定義しなおします。 初期状態は CLOSED とする。 (event)    AUTO_OEPN, MANUAL_OPEN, MANUAL_CLOSE, AUTO_CLOSE --------------------------------------------------------------- (state) FULL_OPEND   何もしない, 何もしない, ※2,   CLOSED HALF_OPEND  -> FULL_OPEND, ※1,   ※2,   CLOSED CLOSED    -> FULL_OPEND, ※1,  何もしない, 何もしない ※1 全部開いたらFULL_OPEN, それまではHALF_OPEN ※2 全部閉まったらCLOSED, それまではHALF_OPEN AUTO_OPEN = Key D MANUAL_OPEN = Key C MANUAL_CLOSE = Key B AUTO_CLOSE = Key A と定義します。そして、この状態遷移表を実装します。 実装方法は swich-case で行う方法、関数ポインタのテーブルで行う方法などがありますが、初心者にはswich-case のほうが分かりやすいでしょう。 例: switch(state){ case STATE_A: if(event1) hogehoge; else if(event2) fugafuga; break; ・・・ }

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

関連するQ&A

  • モータの制御

    //ステッピングモータの回転 //右に2回転、停止、左に1回転、停止これを3回繰り返す //ITUO使用、フラグが立つのを待つ //10msごとにモータに出力 //str_4.c #include <3048f.h> void ioinit(void) { PB.DDR = 0xff; } void ituinit(void) { ITUO.TCR.BIT.CCLR = 1; //カウンタクリア要因 ITUO.TCR.BIT.TPSC = 3; //タイマプリスケーラ 25MHz/8=3.125MHz ITUO.GRA = 31249; //3.125MHz/31250=100Hz、10ms、100pps ITUO.TIER.BIT.IMIEA = 0; //IMFAフラグによる割り込み禁止 } void wait(void) //停止時間 { Long t=200000; while(t--); } int main(void) { int i = 3; //繰り返しカウンタ int p; //回転パルス数 int md = 0x11; //モータ出力データ ioinit(); ituinit(); PB.DR.BYTE = md; wait(); ITU.TSTR.BIT.STR0 = 1; //タイマスタート while(i--){ for(p=0;p<96;p++){ //2回転 PB.DR.BYTE = md; md <<= 1; //右回転 if(md == 0x110) //4回シフトしたかの判断 md = 0x11; //4回シフトで初期値に戻す while(!ITU0.TSR.BIT.IMFA); //フラグが立つのを待つ ITU0.TSR.BIT.IMFA = 0; //フラグクリア } wait(); //少し停止 for(p=50;p>0;p--){ //1回転、1パルス多くした PB.DR.BYTE = md; md >>= 1; //左回転 if(md == 0x08) //4回シフトしたかの判断 md = 0x88; //4回シフトで初期値に戻す while(!ITU0.TSR.BIT.IMFA); //フラグが立つのを待つ ITU0.TSR.BIT.IMFA = 0; //フラグクリア } wait(); } PB.DR.BYTE = 0x00; //モータ励磁OFF while(1); //ここでとまっている } このプログラムのフローチャートがわかりません。

  • マイコンH8-3664 走行カー C言語プログラム改良

    SW0がONで3秒間前進して停止 SW0がOFFの後、再度ONで3秒間前進して停止  するプログラムです! これを、 3秒間前進後、3秒右旋回(右モーターのみ回転)後、3秒間前進、3秒右旋回を繰り返し、元の位置に戻るというプログラムに改良せよ!というのですが? /**************************************************************/ #include <stdio.h> #include <sysio.h> /*タイマーA*/ #define TMA (*((volatile unsigned char *)0xFFA6) /*割り込み*/ #define IENR1 (*((volatile unsigned char *)0xFFF4)) #define IRR1 (*((volatile unsigned char *)0xFFF6)) #define PDR8 (*((volatile unsigned char *)0xFFDB)) #define PCR8 (*((volatile unsigned char *)0xFFEB)) long count = 0; long x = 0; void interrupt timer( ) { IRR1 &= ~0x40 ; if( count == 300 ) { x = 1 ; count = 0 ; } else { count++; } } void main( ) { unsigned char a; TMA = 0x03 ; IENR1 |= 0x40 ; PCR8 = 0x0f ; while(1){ a = PDR8 >> 4 ; if( x == 0 && a == 0x0e ) { PDR8 = 0x0a ; _ei( ) ; } else if( x == 1 ) [ PDR8 = 0x00; _di( ) : if (( PDR8 >> 4) == 0x0f) { x = 0 ; } } } } /**************************************************************/ 尚、SW はプルアップされている!

  • C言語での方向キー入力判定

    C言語でキーの入力判定をするプログラムを作ってい ます。下の例だとeやエンターを押したときは認識できる のに、方向キー↑を押したときはなぜか無反応です。 コンパイラはボーランドでOSはXPでコンパイルした のですが、何がいけなかったのでしょうか? #include <stdio.h> #include <conio.h> #include <windows.h> void check(void){ int key; key = getch(); switch (key){ case 'e': puts("e"); break; case VK_RETURN: puts("ENTER"); break; case VK_UP: puts("UP"); break; } } int main(void) { while(1){ check(); } return 0; }

  • 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; } これで正しく動くことを確認できたのですが、階乗、べき乗の書き方が全くわかりません。どなたか、詳しい方いらっしゃいましたら、ご教授願います。

  • c言語初心者です。ついに。。

    西暦月日にちを入れると何曜日かを表示できるプラグラムをつくれましたー。まだif switch do while文しかしらないけど、switch文だけでできました。でも欠点があってうるう年の1月と2月はうまくできなんです。原因わわかっていてさいごの式bに-1をしなければいけないのですがそのうるう年だけ-1という計算をどうすればできるのかが思いつきません。もし詳しい人がいたら教えてくださいーー。 #include <stdio.h> int main(void) { int y, m, l, z,v,h,q,f,x,o,j,e,a,r,b; printf("西暦何年何月か入力してください\n"); printf("西暦。:"); scanf("%d",&y); printf("何月。:"); scanf("%d",&m); printf("何日。:"); scanf("%d",&l); z=y%400; v=y%100; h=z-v; f=h/100; switch(f) { case 3 : q=0; break; case 1 : q=4; break; case 2 : q=2; break; case 0 : q=6; break; } o=y%100; j=o/4; e=o+j; a=m; switch(a) { case 1 : r=0; break; case 2 : r=3; break; case 3 : r=3; break; case 4 : r=6; break; case 5 : r=1; break; case 6 : r=4; break; case 7 : r=6; break; case 8 : r=2; break; case 9 : r=5; break; case 10 : r=0; break; case 11 : r=3; break; case 12 : r=5; break; } b=q+e+r+l; switch (b % 7){ case 0 : puts("日曜日です。"); break; case 1 : puts("月曜日です。"); break; case 2 : puts("火曜日です。"); break; case 3 : puts("水曜日です。"); break; case 4 : puts("木曜日です。"); break; case 5 : puts("金曜日です。"); break; case 6 : puts("土曜日です。"); break; } return (0); }

  • C言語で電卓を作成する。

    C言語を用いて三項まで計算できる電卓を作りたいのですが、どうも上手くいきません。 四則演算(+、-、×、÷)の優先順位を用いたプログラミング方法が分かりません。 以下に自分で作成したソースを添付します。 このソースに修正や追加して3項までの四則演算できるプログラミングを教えていただけますか? 宜しくお願いします。 #include <stdio.h> int main(void) { int answer; /*答え*/ int x,y,z; /*x=第一項,y=第二項,第三項*/ char op1,op2; /*演算子1、演算子2*/ while(1){ printf("式を入力してください\n"); printf("式:"); scanf("%d %c %d %c %d" ,&x,&op1,&y,&op2,&z); if((op1=='+'|'-'|'*'|'/') && (op2=='+'|'-'|'*'|'/')){ switch(op2){ case '+': answer=y+z; break; case '-': answer=y-z; break; case '*': answer=y*z; break; case '/': if(z==0){ printf("ERROR\n"); return 0; } answer=y/z; break; default: printf("ERROR\n"); return 0; } switch(op1){ case '+': answer=x+answer; break; case '-': answer=x-answer; break; case '*': answer=x*answer; break; case '/': if(y==0){ printf("ERROR\n"); return 0; } answer=x/answer; break; default: printf("ERROR\n"); return 0; } printf("答え:%d\n",answer); } else { switch(op1){ case '+': answer=x+y; break; case '-': answer=x-y; break; case '*': answer=x*y; break; case '/': if(y==0){ printf("ERROR\n"); return 0; } answer=x/y; break; default: printf("ERROR\n"); return 0; } printf("答え:%d\n",answer); } } } 左辺に×、÷が来ても優先的に計算されません。

  • H8を使って、モータの正逆回転を制御するプログラムを作成したいのですが

    H8を使って、モータの正逆回転を制御するプログラムを作成したいのですがうまくいきません。よろしくお願いします。  h8 <3067F.h>を使ってDC電圧を入力してモータを制御するプログラムなのですが、入力電圧が2.5V(0x80)時は静止、2.5V(0x80)以上なら正回転、2.5V(0x80)以下なら逆回転するようにしたいのですがうまくいきません。プログラムはこんな感じです。 #include <3067F.h> #pragma interrupt(adi) void initITU(void); void initITU1(void); void initAD(void); void initPA(void); main() { initPA(); initAD(); initITU(); initITU1(); /* Initalize ITU ch1 */ ITU.TSTR.BIT.STR1 = 1; /* Start ITU ch1 */ AD.CSR.BIT.ADST = 1; /* A/D変換 start */ while(1){ ; } } void initPA(void){ PADDR = 0xff; /* PortA 出力モード */ PADR.BYTE = 0x00; /* PA Clear */ } void initAD(void){ AD.CR.BIT.TRGE = 0; /* AD変換外部トリガ開始禁止 */ AD.CSR.BYTE = 0x00; /* ADCSR初期化, ch0のみ */ AD.CSR.BIT.ADIE = 1; /* AD変換終了後割り込み */ AD.CSR.BIT.CKS = 0; /* AD変換時間 : 135ステート */ AD.CSR.BIT.SCAN = 0; /* 単一モード */ } void initITU(void) { ITU.TSTR.BYTE = 0x00; ITU.TSNC.BYTE = 0x00; ITU.TISRA.BYTE = 0x00; /* Disable Interruption */ ITU.TISRB.BYTE = 0x00; /* Disable Interruption */ ITU.TISRC.BYTE = 0x00; /* Disable Interruption */ } void initITU1(void) { ITU.TMDR.BIT.PWM1 = 1; /* CH1 PWM mode */ ITU1.TCR.BYTE = 0x20; /* clear GRA comparematch,1/clock */ ITU1.GRA = 0; /* A/D変換器の保証bitは上位8bit */ ITU1.GRB = 0; ITU1.TIOR.BYTE = 0X00; /* prohibit GRA&GRB'output of comparematch */ } void adi(void) { AD.CSR.BIT.ADST = 0; /* A/D変換停止 */ if(ITU1.GRB > 0x80)            2.5v以上かの場合分け { ITU1.GRB = (AD.DRA - 0x80 >> 8); ここで正回転の方向と速度を決める。 PADR.BIT.B1 = 1; PADR.BIT.B2 = 0; } else                    その他 { ITU1.GRB = (0x80 - AD.DRA >> 8); ここで逆回転の方向と速度を決める。 PADR.BIT.B1 = 0;               PADR.BIT.B2 = 1; } AD.CSR.BIT.ADF = 0; AD.CSR.BIT.ADST = 1; /* A/D変換開始 */ }  if文のところで、減算を行い正なら正回転、elseは減算したら負になり逆回転する命令にしたいのですがどうしたらいいでしょうか。 よろしくお願いします。

  • 助けてください(C言語)

    初心者です。 足し算と引き算をするプログラムを作りましたが コンパイルまではとおっていますが、実行し、 5+3= とうつと、804399520 804399524 804399528[1] Done とでます。 どこがいけないのか?ご教授いただければと思います。 回答でなくても良いのでヒントを下さい。 #include<stdio.h> /* 演算を実行し,値を返す関数を設ける */ int tashizan(int keyInpInt1,int keyInpInt2); int hikizan(int keyInpInt1,int keyInpInt2); tashizan(int keyInpInt1,int keyInpInt2) /* 加算 */{ return(keyInpInt1 + keyInpInt2); } hikizan(int keyInpInt1,int keyInpInt2) /* 減算 */{ return(keyInpInt1 - keyInpInt2); } void main(void) { /*入力用と,出力用の変数を定義*/ int keyInpInt1,keyInpInt2,x; char F,tougou; /* 計算式の入力受付 */ printf("式-->"); scanf("%d %c %d %c",&keyInpInt1,&F,&keyInpInt2,&tougou); switch(F){ case '+' :x = tashizan(keyInpInt1,keyInpInt2); break; case '-' :x = hikizan(keyInpInt1,keyInpInt2); break; } /* 演算結果を出力 */ printf("%d %c %d %c %d",&keyInpInt1,&F,&keyInpInt2,&tougou,&x); }

  • C言語プログラミングについて…Arduinoを用い

    C言語プログラミングについて…Arduinoを用いて、以下の文でスイッチ「RedSwitch(赤スイッチ)」が押された回数だけ後で光るというプログラミングを作りました。次にその使用した「switch case」文を「if」文、もしくは「if else」に変換して同じプログラミングを作りなさいという課題が出て、いろいろと変えてみたのですが、シリアルモニタを見るとif文を用いた時に「RedSwitch」が押された「回数」ではなく連続的に?押した「秒数」をカウントして困ってます。どうやったら改善できるのでしょうかか?ご教授お願いしたします。 void sw_check(void) { switch(SW_RedSwitch) { case 0: if ( digitalRead(2)==SW_ON ) { SW_RedSwitch=1; } break; case 1: if ( digitalRead(2)==SW_OFF ) { SW_RedSwitch=2; } break; } } void blink(void) { digitalWrite(13,LED_ON); delay(500); digitalWrite(13,LED_OFF); delay(500); } void loop() { unsigned char SW_CNT=0,SW_TIME=0,i; while( (SW_TIME<100) || (SW_CNT==0) ) { sw_check(); if ( SW_RedSwitch==2 ) { SW_RedSwitch=0; SW_CNT++; SW_TIME=0; } SW_TIME++; delay(20); } for (i=1 ; i<=SW_CNT ; i++) { blink(); } }

  • C言語

    現在、ストップウォッチの一時停止およびラップをとる機能のプログラムを作成しているのですが、 「計測中にtを押すと一時停止.一時停止中にtで計測再開」の部分は計測していないときに計測が開始されてしまいます。(計測中の処理は上手く動作できました) 「計測中にlを押すとラップをとる」という使い方の部分も同様に計測していないときに計測が開始されてしまいます。それから、実際に計測中にlを押したとき、ラップタイムではなく、スピリットタイムで表示されてしまい、上手く動作しません。 至急、修正または追加のほうお願いします。 #include <windows.h> #include <mmsystem.h> #include <stdio.h> #include <conio.h> #pragma comment(lib, "winmm.lib") void disp(DWORD time_value) { printf("%02d:%02d:%02d:%03d\r",time_value/3600000,(time_value/60000)%60,(time_value/1000)%60,time_value%1000); } int main(void) { int add_flag = 0; DWORD counter=0,start_time,cur_time; printf("使い方:小文字の's'でカウントスタート.カウント中,小文字の's'で停止.次の's'でまた0からスタート\n"); printf("使い方:どんな状態でも小文字の'r'でカウントリセットして停止\n"); printf("使い方:qでプログラム終了\n\n"); printf("使い方:計測中にtを押すと一時停止.一時停止中にtで計測再開\n"); printf("使い方:計測中にlを押すとラップをとる\n"); disp(counter); for (;;){ start_time = timeGetTime(); while (start_time == (cur_time = timeGetTime())) { if (kbhit()) { switch (_getch()){ case 's': disp(counter); printf(add_flag ? "\n計測中止\n" : "\n計測開始\n"); add_flag = !add_flag; start_time = cur_time = timeGetTime(); counter = 0; break; case 't': disp(counter); printf(add_flag ? "\n一時停止\n" : "\n計測再開\n"); add_flag = !add_flag; start_time = cur_time = timeGetTime(); break; case 'r': disp(counter); printf("\nカウンタリセット,停止\n"); add_flag = 0; counter = 0; start_time = cur_time = timeGetTime(); break; case 'l': disp(counter); printf("\nラップ\n"); add_flag = 1; break; case 'q': printf("\n終了\n"); return 0; } disp(counter); } } if (add_flag != 0){ counter += cur_time - start_time; disp(counter); } } }

英検2級についての質問
このQ&Aのポイント
  • 英検2級の勉強において、文章で翻訳できる単語力をつける方法や日→英の翻訳の重要性、単語帳の選び方、英熟語の使用方法などについて質問があります。
  • 質問文章には、中2の生徒が英検2級取得に向けての課題について述べており、単語帳や翻訳の困難さ、単語の表現力、ライティングのポイントなどを取り上げています。
  • 具体的な質問として、文章で翻訳できる単語力をつける方法、日→英の翻訳の重要性、単語帳をどう選ぶべきか、英熟語の使用方法に関する質問が挙げられています。
回答を見る