• ベストアンサー

PIC制御で出力ピンの名前に変数を使うには?

はじめまして 高校でC言語を使いPIC制御しているのですが動きません泣 ピンの番号や命令中に変数を使いたいんですどうしたら良いでしょう? 簡単なプログラムで言うと、 for(x = 0; x <= 5; x++){ y = 1; output_bit(PIN_Ax,y); if(y==1){y = 0;} } 見たいな事をしたいのですが動きません ポート制御すればいいみたいな話じゃなくてです お願いします

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

  • ベストアンサー
  • taunamlz
  • ベストアンサー率20% (175/843)
回答No.3

void portb(long addt) { PIN_A0 = 0x01 & addt; PIN_A1 = (0x02 & addt) >> 1; PIN_A2 = (0x04 & addt) >> 2; PIN_A3 = (0x08 & addt) >> 3; ... PIN_A7 = (0x80 & addt) >> 7; } こーゆー事ってPICじゃ出来ないんですか?(マイコンとかDSP位しか使ったことが無いもので。) 俺ならこんな関数作っちゃいますけど。 使う時は void portb(long addt); void main(void) { long A; A=read_adc; portb(A); } って感じですかね。 output_bit(PIN_A0,y)っていうのが使ったこと無いのでよくわからないんですが、置き換えるなら多分 PIN_A1 = (0x02 & addt) >> 1;  →  output_bit(PIN_A1,(0x02 & addt) >> 1); 見たいな感じで動くと思います。

atsuGT
質問者

お礼

あぁなるほどシフトでの切り出しを使えば1発っすね PICでも出来ると思います ありがとうございます 助かりました

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

その他の回答 (2)

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

PIC, H8, SH などのマイコンで遊んでいる者です。 PICのCコンパイラには何をお使いですか? > ポート制御すればいいみたいな話じゃなくてです ぱっと見て、ポインタにポート名代入するか、switch case で振り分けるかと思ったのですが、ポートの話ではないのですね??? 具体的に何をしたいのですか? 「動きません」ではなく、 1.どのような出力を期待して作ったか 2.結果はどのような出力になっているか を書いてください。

atsuGT
質問者

補足

はじめまして 回答ありがとうございます コンパイラはMPLABを使ってます 質問分かりづらくてホントすんません 具体的に言うと少し長くなるのですが 短く言うとPIC16f873のアナログ入力をA/D変換してUSBを通してVBで読むというのをしたいんです PICの中でやりたい事はread_adcをした値を2進数にしてそれをポートBを使って出力したいんです それでひとまず作ったプログラムで動かすことは出来たのですが、長くて... Aはアナログ入力をぶち込んだやつです for(x = 0; x <= 8; x++){ Y[x] = A % 2; A = (A - Y[x]) / 2; } このforループの中でポートBの'x'pinに'Y[x]'←(1or0)を出力したいです バカなプログラムですんません 他にいい方法があればそれでもいいのですが あとswitchで分けるというのは switch(x){ case '0': output_bit(PIN_A0,y); ... } って事っすか? まだ質問が下手なことがあったらまた言ってください

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

質問の意図が、「定数値PIN_A0、PIN_A2、…、PIN_A5があって、変数xの値を1として、PIN_Axという記述がPIN_A1を意味するコーディング法が知りたい」という事なら、一般的なCでは無理かと(根性入れて、evalを実装するという手もありますが)。 素直に、配列PIN_Aを用意して、 PIN_A[0] = PIN_A0; (以下略) ――と初期化しといて、 output_bit( PIN_A[x], y ); ――でアクセスすれば良いのでは。 外してるかな?

atsuGT
質問者

お礼

回答ありがとうございます 分かりづらい質問ですみませんでした 無理なんですか... わかりました その方法でやってみます 本当にありがとうございました

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

関連するQ&A

  • PIC マイコンの原因不明の破壊

    PIC16F873A を使用してます RB ポートの入力に変化があったとき、RB の内容によってあるパターンを1秒間だけ RC に出力する内容で動作させています ところが、おそらく電源の ON/OFF のタイミングで RB ポートが壊れてしまいます 具体的な症状として、入力ポートにもかかわらず勝手に Low 状態(著しく電圧が下がる状態)になり、そのまま Low 状態と誤認識してしまいます 一度 Low に落ちてしまったピンは、プログラムを書き直してもずっと Low の状態です RB ポートのうち、どのポートが壊れるのかはランダムです 複数壊れる場合もあります RB へのプルアップ抵抗は 100K Ωです 電源はバッテリーから DCDC コンバーター(OBR05SC0512)で5Vにしたものを供給しています ノイズ対策の為、DCDC コンバーターは別の基盤に取り付け、該当の基盤から離しています 4.98V で安定出力しているようです PIC の電源付近にノイズ対策のため、積層セラミックコンデンサの 104 を置いてます 該当箇所のプログラムは以下のとおりです if (InputMemory != input_b()) { InputMemory = nput_b(); if ((!input(PIN_B0)) && (CountStart != TRUE)) { output_c(Speed0); } else if ((!input(PIN_B1)) && (CountStart != TRUE)) { output_c(Speed1); } else if ((!input(PIN_B2)) && (CountStart != TRUE)) { output_c(Speed2); } else if ((!input(PIN_B3)) && (CountStart != TRUE)) { output_c(Speed3); } else if ((!input(PIN_B4)) && (CountStart != TRUE)) { output_c(Speed4); } else if ((!input(PIN_B5)) && (CountStart != TRUE)) { output_c(Speed5); } CountStart = TRUE; TimerCount = 0; for (; CountStart == TRUE; ) { if (InputMemory == input_b()) { TimerCount++; delay_ms(100); if (TimerCount == 10) { output_c(0b11111111); CountStart = FALSE; } } else { CountStart = FALSE; } } } else { output_c(0b11111111); } お手数ですが、ご解答よろしくお願いいたします

  • C言語のPICプログラミングなんですが、

    C言語のPICプログラミングなんですが、 これのどこがおかしいか教えてください。 if(input(PIN_B1)) { while(input(PIN_B2) == 0) { output_high(PIN_B7); //前進後進パルス出力 delay_us(50); //変換待ち output_low(PIN_B7); delay_us(16000); //共通遅延16000us } break; } if(input(PIN_B1)) { while(input(PIN_B2) == 0) { output_high(PIN_B7); //前進後進パルス出力 delay_us(50); //変換待ち output_low(PIN_B7); delay_us(16000); //共通遅延16000us } break; }

  • 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秒待つ }

  • picからsg12864を制御しています。

    picからsg12864を制御しています。 直線の描画を行った際、まっすぐな縦線が点線のようになってしまいます。 横線・斜線は問題なく描画できます。また、ビットマップをそのまま表示した場合も問題なく描画できます。 後閑さんのプログラムを使用しています。下記のlcd_Lineを使用しています。 for文を使用して、1秒間隔でlcd_Pixelで点を打って直線を描画て動作を確認したところ、一度は黒いドットが表示されますが、消えてしまう箇所がありました。消えてしまう箇所はいつも同じです。 どなたか、解決方法がわかる方はいらっしゃいませんでしょうか? #define abs(a) (((a)>0) ? (a) : -(a)) void lcd_Line(int x0, int y0, int x1, int y1) { int steep, t; int deltax, deltay, error; int x, y; int ystep; /// 差分の大きいほうを求める steep = (abs(y1 - y0) > abs(x1 - x0)); /// x、yの入れ替え if(steep){ t = x0; x0 = y0; y0 = t; t = x1; x1 = y1; y1 = t; } if(x0 > x1) { t = x0; x0 = x1; x1 = t; t = y0; y0 = y1; y1 = t; } deltax = x1 - x0; // 傾き計算 deltay = abs(y1 - y0); error = 0; y = y0; /// 傾きでステップの正負を切り替え if(y0 < y1) ystep = 1; else ystep = -1; /// 直線を点で描画 for(x=x0; x<x1; x++) { if(steep) lcd_Pixel(y,x,1); else lcd_Pixel(x,y,1); error += deltay; if((error << 1) >= deltax) { y += ystep; error -= deltax; } } } void lcd_Pixel(int Xpos, int Ypos, char On){ char cs, data, page, pos, count, i; /* if colum >127 then do nothing */ if(Xpos<128){ if(Xpos>63){ // 64=<colum<=127? Xpos = Xpos-64; // shift 64 dot cs = 1; } else cs = 2; page = (char)(7-Ypos/8); // set page lcd_Write(cs, 0xB8+page, 1); lcd_Write(cs, 0x40+Xpos, 1); // set colum data = lcd_Read(cs,0); // get current data lcd_Write(cs, 0x40+Xpos, 1); // set colum ???? data = lcd_Read(cs,0); // get current data ???? pos =1; // set bit position count = (char)(7-Ypos%8); // set bit for(i=0; i<count; i++) // caluculate 2^n pos *= 2; lcd_Write(cs, 0x40+Xpos, 1); // back address if(On==1) // set or reset bit lcd_Write(cs, data | pos, 0); // set 1 else lcd_Write(cs, data & ~pos, 0); // set 0 } }

  • PICのピンの割り当て、この記述は正しいのでしょうか?

    現在C言語によるプログラムを勉強しているのですが、わからない箇所が出てきました。 PICのピンの入出力の割り当てをする部分の set_tris_a(0x10); //RA1,RA3を入力,RA0,RA2,RA4を出力に設定している。 という部分です。 調べたところ"0x"という部分は16進表記であるという意味で、その後の部分で格ピンの入出力を表しているようなのですが、"10"の部分は10進法表記ではないかと思うのです。 (16進なら"A"と表記するのが正しいのではないでしょうか) また"0x"は16進表記との事ですが、他に、たとえば10進や2進表記で格ピンの割り当ては可能なのでしょうか?

  • PICによるLED制御について

    大学の講義でPICのLED制御の課題がよくわかりません。 どなたか教えていただけないでしょうか? [問]  PIC16F84Aにおいて、動作を実現するプログラムを示せ。  メインルーチンでLED出力の点燈箇所を1秒ごとに巡回させる。   RA3=Low(OFF)のとき、左向きに巡回シフト(RLF命令)させる。   RA3=High(ON)のとき、右向きに巡回シフト(RRF命令)させる。  また割り込みルーチンによって、RA0~RA2の3ビットの値に応じて  点灯速度を変化させる(値が大きいほど速く)  ただし、ポートAは全て入力モード、ポートBはRB0以外を出力モードとし(RB0は割り込み用)、ポートBの初期出力を0000100*(LED出力の初期点燈位置は第3ビットのみ)とせよ。

  • 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){} } //// 以上宜しくお願いいたします。

  • PICでのプログラミングについて教えて下さい。

    現在電圧計を製作していて4桁の7セグダイナミック点灯で行き詰っております(超初心者です)。 PICは16F873Aを使用、コンパイラはCCS、書き込みはピックライタ、あとシリアルデバッカを使用しています。 外部から電圧をかけそれをAD変換し、AD変換結果(0~5V)を7セグに表示させようとしています。 一応今の状態でも電圧表示はできていることはできているのですが一桁目から4桁目まで目で追えるくらい遅いスピードでこれを改善したいです。ソースは下記のソースを製作しました。この状態で3日間悩んでおります...知恵をお貸しいただけないでしょうか。 よろしくお願いします。 #include <16F873a.h> #device ADC=10 //A/D変換10bitモード #use fast_io(A) /* TRISレジスタの設定が必要 */ #use fast_io(B) #use fast_io(C) #use delay (clock=10000000) //10MHz #use RS232( BAUD = 9600, XMIT = PIN_C6, RCV = PIN_C7, PARITY = N, BITS = 8 ) #fuses HS,NOWDT,PUT,NOPROTECT,NOBROWNOUT,NOLVP #define VOLTAGE PIN_A0 // (in) #define CORRENT PIN_A1 // (in) #define VREF1 PIN_A2 // (in) #define VREF2 PIN_A3 // (in) #define RESERVE1 PIN_A4 // (out) #define RESERVE2 PIN_A5 // (out) #define LED_DP PIN_B0 // (out) #define LED_A PIN_B1 // (out) #define LED_B PIN_B2 // (out) #define LED_C PIN_B3 // (out) #define LED_D PIN_B4 // (out) #define LED_E PIN_B5 // (out) #define LED_F PIN_B6 // (out) #define LED_G PIN_B7 // (out) #define DIG_0 PIN_C0 // (out) #define DIG_1 PIN_C1 // (out) #define DIG_2 PIN_C2 // (out) #define DIG_3 PIN_C3 // (out) #define INI_TRIS_A_VAL 0x0F // 7:x 6:x 5:out 4:out 3in 2:in 1:in 0:in #define INI_TRIS_B_VAL 0x00 // 7:out 6:out 5:out 4:out 3out 2:out 1:out 0:out #define INI_TRIS_C_VAL 0x80 // 7:in 6:out 5:out 4:out 3:out 2:out 1:out 0:out int ct;//数字の更新間隔 long val;//表示する数字 int digit;//表示する桁 //表示パターン int segment_data[]={0x81,0xF3,0x49,0x61,0x33,0x25,0x05,0xF1,0x01,0x31}; char st[4]; void main() { float ata1,data2,data3,data4; long data5; long val; SET_TRIS_A( INI_TRIS_A_VAL ); SET_TRIS_B( INI_TRIS_B_VAL ); SET_TRIS_C( INI_TRIS_C_VAL ); setup_adc_ports(AN0_AN1_VSS_VREF); setup_adc(ADC_CLOCK_DIV_32); //Fosc/32 最高速度 digit=0; ct=1;//数字を更新する周期 val=0;//表示する値 while(1) { output_low(RESERVE2); //動作ランプ //////////////////////電圧測定///////////////////////////////// set_adc_channel(0); delay_us(50); //アクイジションタイム待ち(マイクロ秒) data1 = read_adc(); //AD変換結果読み込み printf("ADC V %9.3f \r\n", data1 ); //AD変換データ表示 data2 = (data1 * 4.959695) / 1024; //BCDに変換 printf("Volt %6.3f \r\n", data2 ); //変換データ表示 data5 = data2 * 1000 ; //data2を整数に変換 val = data5 ; printf("val %ld \r\n", val); //整数にし表示 /////////////////////7SEG表示////////////////////////////////// ct --; if(ct == 0){//数字の更新 st[3]=val/1000; //4桁目数値取り出し st[2]=val/100-st[3]*10;//3桁目数値取り出し st[1]=val/10-((st[3]*100)+(st[2]*10));//2桁目数値取り出し st[0]=val%10;//あまり val++; if(val==1000) val=0; ct=20; } if(digit== 3){//第4桁の表示 output_b( segment_data[st[3]]); output_bit(DIG_0,1);  //4桁表示開始 output_low(LED_DP);  //小数点表示  delay_us (5); //表示期間(ミリ秒) output_bit(DIG_0,0); //表示を消す output_high(LED_DP); //小数点を消す delay_us(50); //待ち(マイクロ秒) } if(digit== 2){ output_b( segment_data[st[2]]); output_bit(DIG_1,1); delay_ms (5); output_bit(DIG_1,0); delay_us(50); } if(digit== 1){ output_b( segment_data[st[1]]); output_bit(DIG_2,1); delay_ms (5); output_bit(DIG_2,0); delay_us(50); } if(digit == 0){ output_b( segment_data[st[0]]); output_bit(DIG_3,1); delay_ms (5); output_bit(DIG_3,0); delay_us(50); } digit ++;//表示桁を変更 if(digit ==4 ) digit=0; } }

  • 3桁7SEG時計(PIC16F648A)を作りた…

    3桁7SEG時計(PIC16F648A)を作りたい・・ 3桁時計を作りたいです。 割り込みを使って1秒を作って0:00から9:59まで表示する時計。 私はプログラムの方はあんまり得意ではないので、 ご教授の方よろしくお願いいたします。 以下、必要と思われる情報です。 Device:PIC16F648A マイクロチップテクノロジ コンパイラ:CCS社製PICC MATLAB+CCSコンパイラの環境です。 このハードウェアで0~999までカウント するプログラムは動作しています。 クロック:内臓4MHzです。 ハードウェアポート仕様 PORTA_A1:7SEGLED Cathode Common制御 分(1の位)NPNトランジスタON/OF    A2:7SEGLED Cathode Common制御 分(10の位)NPNトランジスタON/OF    A3:7SEGLED Cathode Common制御 時(1の位)NPNトランジスタON/OF PORTB_B0:7SEGLED Anode 制御 7SEG_a PORTB_B1:7SEGLED Anode 制御  7SEG_b PORTB_B2:7SEGLED Anode 制御  7SEG_c PORTB_B3:7SEGLED Anode 制御  7SEG_d PORTB_B4:7SEGLED Anode 制御  7SEG_e PORTB_B5:7SEGLED Anode 制御  7SEG_f PORTB_B6:7SEGLED Anode 制御  7SEG_g PORTB_B7:7SEGLED Anode 制御  7SEG_h 下記のプログラムは0~600までカウントするプログラムです。 val値でカウントする値を可変できます。 #include <16f648a.h> #fuses INTRC_IO,NOWDT,NOLVP,NOMCLR //内部クロック、WDT,LVPなし #use delay(CLOCK=4000000) //クロック4MHz //#define TIME_OUT unsigned int const LED_SEG[]=      //7SEG表示用テーブル { 0b00111111, /* 0= "0" [1] */ 0b00000110, /* 1= "1" [2] */ 0b01011011, /* 2= "2" [3] */ 0b01001111, /* 3= "3" [4] */ 0b01100110, /* 4= "4" [5] */ 0b01101101, /* 5= "5" [6] */ 0b01111100, /* 6= "6" [7] */ 0b00100111, /* 7= "7" [8] */ 0b01111111, /* 8= "8" [9] */ 0b01101111, /* 9= "9" [10]*/ 0b10000000,   /* 10= "." [11]*/ 0b01000000, /* 11= "-" [12]*/ }; unsigned int ct; //数字の更新間隔 unsigned long val; //表示する数字 unsigned int digit; //表示する桁 unsigned char st[3]; void main(void) { set_tris_a(0b11110000); set_tris_b(0b00000000); digit=0; ct=1; //数字を更新する周期 val=0; //表示する値 while(1) { ct --; if(ct == 0) { //数字の更新 st[2]=val/100; // st[1]=val/10-st[2]*10; //計算 st[0]=val%10; //計算 val++; if(val==600) val=0; ct=20;          //200にすると                          //約1秒間隔の表示に                          //なります。 } if(digit== 2) { //第3桁の表示 output_b(LED_SEG[st[2]]); output_bit(PIN_A3,1);//3桁表示開始 delay_ms (5); //表示期間(ミリ秒) output_bit(PIN_A3,0); //表示を消す delay_us(100); } if(digit== 1) //第2桁の表示 { output_b(LED_SEG[st[1]]); output_bit(PIN_A2,1); delay_ms (5); output_bit(PIN_A2,0); delay_us(100); } if(digit == 0) //第1桁の表示 { output_b(LED_SEG[st[0]]); output_bit(PIN_A1,1); delay_ms (5); output_bit(PIN_A1,0); delay_us(100); } digit ++; if(digit == 3) digit=0;//表示桁を変更 } }

  • PIC18F2520を用いたLCD制御について

    こんにちは。 作りたいものがあって、PICに初めて挑戦しています。 その初めとしてPIC18F2520を用いて秋月製キャラクタ液晶(SC1602BSLB)の制御(簡単な文字表示)を行おうとしているのですが、 web記事を参考にプログラムを記述しても初期化されません。 web記事では主にPIC16系の記載なので LIST P=18F2520 #include <P18F2520.INC> と書き換え、コンフィグも移植しました。 ポート初期化の際に16F系では必要なBANK切替命令については削除しています。 その他の命令については互換性があるとの事なので変更していません。 初期化コマンドのwaitタイミング等色々変化させてみたのですが状況に好転がなく、煮詰まってしまいました。 恐らくは独学ゆえ基本的な部分が抜け落ちているものと思っています。 皆さんからアドバイスが頂けたらと思います。 開発環境はMPLAB-IDE8.10、ライタはPICKit2(Ver.2.51)です。 何卒よろしくお願いいたします。

封筒印刷の方法がわからない
このQ&Aのポイント
  • 封筒印刷方法についての相談です。
  • 使用している製品はDCP-j963Nです。
  • パソコンのOSはWindows10で、無線LANで接続しています。関連ソフトはwordです。光回線を使用しています。
回答を見る