if else文でドットマトリクスLEDをスイッチで制御できない

このQ&Aのポイント
  • ドットマトリクスLEDを3個のスイッチで切り替えて点灯できるようにしたいが、動作できない。
  • プログラムのPORTA、C、D、EでLEDの点灯形を決めている。
  • if〜elseのところがおかしいと考えているが、原因がわからない。解決のヒントを教えてほしい。
回答を見る
  • ベストアンサー

if else文

ドットマトリクスLEDを3個のスイッチで切り替えて点灯できるようにしたいのですが、うまく動作できません。プログラムのPORTA、C,D,EのところでLEDが点灯する形を決めています。 PORTB0,1,2でスイッチの制御をしています。 たぶん if~else のところがおかしいと考えているのですがいろいろ調べたのですが原因がわかりません。 何か解決のヒントでも気になったとこでもいいのでよろしくおねがいします。 #include<pic.h> __CONFIG,_CONFIG1 , _DEBUG_ON , _LVP_OFF , _FCMEN_OFF , _IESO_OFF , _BOREN1_OFF , _BOREN0_OFF , _CPD_ON , _CP_ON , _MCLRE_ON , _PWRTE_OFF , _WDTE_ON , _FOSC2_OFF , _FOSC1_ON , _FOSC0_OFF; __CONFIG,_CONFIG2 , _WRT1_ON , _WRT1_ON , _BOR4V_OFF; void ioport(void); void main() { ioport(); while(1) { if(RB0 == 0)         {    PORTA = 0b111000; PORTB = 0b00000111; PORTD = 0b11111110; PORTC = 0b11111111; PORTE = 0b001; break; } else if(RB1 == 0) { PORTA = 0b111000; PORTB = 0b00000111; PORTD = 0b11111100; PORTC = 0b00111111; PORTE = 0b001; break; } else if(RB2 == 0) { PORTA = 0b111000; PORTB = 0b00000111; PORTD = 0b10101010; PORTC = 0b01010101; PORTE = 0b001; break; } else { PORTA = 0b111000; PORTB = 0b00000000; PORTD = 0b11111111; PORTC = 0b11111111; PORTE = 0b001; break; } } } void ioport(void) { TRISA = 0; TRISB = 0b00000111; TRISC = 0; TRISD = 0; TRISE = 0; }

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

>ちなみにif(RB0 == 0)からif(RB0 == 1)に変更したところ、if(RB1 == 0)の結果が表示されました。 >よって、RB0はスイッチの状態に関係なくRB0==0と認識されている?ようです。 でしたら…回路の方が間違っていたりはしませんか? あとは……volatile装飾子でしょうかねぇ。 http://www.kumikomi.net/archives/2003/05/10kumi.php?page=13 http://proger.blog10.fc2.com/blog-entry-20.html など。

GIN222
質問者

お礼

2度も回答ありがとうございます。 回路は質問前に調べたんですけど、もう一度確認したいと思います。 volatile装飾子は初めて聞く言葉なので、貼っていただいたURLで調べてやってみたいと思います。

GIN222
質問者

補足

解決しました。2度も回答していただき本当にありがとうございました。 あの後いろいろ調べたところAD入力になっていました。 #include<PIC.h> void ioport(void); void main() { ANSEL = 0; ANSELH = 0; ioport(); while(1) のように ANSEL = 0; ANSELH = 0; を加えることによってスイッチできちんと切り替わるようになりました。

その他の回答 (1)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

残念ながら…千里眼のスキルは持ち合わせていませんので…… >うまく動作できません。 と書かれても、どう動作するのが正しい(期待している)のか判りません。 とりあえずコードを眺めた限りでは…… while(1)で作っている無限ループは『1回走っただけで抜けてしまいます』が、それは期待した動作ですか? # breakは要らないんじゃないですか? 組み込み系でmain()関数を終了した場合ってどうなるんでしょう???? RB0/RB1/RB2はループ実行中でもスイッチを押したら正しく変化する…んですよね? # チャタリングとかしそうですが…まぁ、今はどうでもいいですかねぇ。

GIN222
質問者

補足

回答ありがとうございます。 >>うまく動作できません。 >と書かれても、どう動作するのが正しい(期待している)のか判りません。 わかりにくくて申し訳ないのですが、わたしは単純にスイッチを押したらLEDが反応するようにしたいです。ifのRB0 == 0の状態で初めからLEDが点灯しています。 RB0スイッチを押(RB0=0を入力)してもRB1・RB2を押してもLEDが切り替わってくれません。 ちなみにif(RB0 == 0)からif(RB0 == 1)に変更したところ、if(RB1 == 0)の結果が表示されました。 よって、RB0はスイッチの状態に関係なくRB0==0と認識されている?ようです。 >while(1)で作っている無限ループは『1回走っただけで抜けてしまいます』が、それは期待した動作ですか? while(1)を使って無限ループを作り、動作を続けさせたいです。 ># breakは要らないんじゃないですか? breakを消しても変わりませんでした。

関連するQ&A

  • PICマイコンのI/Oについて教えてください。

    PIC16F1936を使っています。 各ポートをデジタル出力にしLEDを順に点灯させていますが RB0に接続したLEDのみうっすらとしか光りません。 (プログラムで意図したとおり点滅はします。) テスターで電流を計測したところRB0のみほとんど流れていませんでした。 また電源投入時にRB0に接続したLEDだけ一瞬光ります。 PICは初期状態でI/Oは入力になっているので光らないと思うんですが・・・ MPLABX+XC8で開発しています。 以下の切り分けを行いました。 ・LED単体での点灯:正常点灯 ・他のLEDをRB0に接続:現象再現 ・他のブレットボードで作動:現象再現 データシートとかなり睨めっこしたんですがそれっぽい部分がみつかりません ご教示いただけると助かります。 ソースは以下のとおりです。 #include <xc.h> #pragma config CLKOUTEN = OFF,\ WDTE = OFF,\ PWRTE = ON,\ CP = OFF,\ BOREN = OFF,\ FCMEN = OFF,\ MCLRE = ON,\ CPD = OFF,\ IESO = OFF,\ FOSC = INTOSC,\ STVREN = OFF,\ BORV = LO,\ LVP = OFF,\ VCAPEN = OFF,\ WRT = OFF,\ PLLEN = ON #define uchar unsigned char #define uint unsigned int void init(void){ //ポート初期化 PORTA = 0b00000000; PORTB = 0b00000000; PORTC = 0b00000000; PORTE = 0b00000000; TRISA = 0b00000000; TRISB = 0b00000000; TRISC = 0b00000000; TRISE = 0b00000000; //全てデジタル ANSELA = 0b00000000; ANSELB = 0b00000000; //8mhz OSCCON = 0b11110000; OPTION_REG = 0b00000000; APFCON = 0; WPUE = 0; } void Wait(unsigned int num){ for (int i=0 ; i<num ; ++i) { for( int j = 0; j < 100; ++j){ NOP(); } } } void main(void){ init(); while(1){ PORTC = 0b00000100; Wait(1000); PORTC = 0b00000000; PORTB = 0b00001000; Wait(1000); PORTB = 0b00100000; Wait(1000); PORTB = 0b00000001; Wait(1000); PORTB = 0b00000000; } }

  • RB0が電圧落ちる

    以前RB6と投稿していましたがRB0でした ダイナミック点灯で4x4のLEDを制御するのですが PORTBの0~3はアノード 4~7はカソードに接続 なぜか PORTBの0につながるLEDだけ暗くなるんです MPLABIDEでXC8コンパイラを使用しております #include <stdio.h> #include <stdlib.h> #include <xc.h> // PIC16F886 Configuration Bit Settings // CONFIG1 #pragma config FOSC = XT #pragma config WDTE = OFF #pragma config PWRTE = ON #pragma config MCLRE = ON #pragma config CP = OFF #pragma config CPD = OFF #pragma config BOREN = OFF #pragma config IESO = OFF #pragma config FCMEN = OFF #pragma config LVP = OFF // CONFIG2 #pragma config BOR4V = BOR40V #pragma config WRT = OFF void delay(int a); int main(int argc, char** argv) { int i; ANSEL=0x00; ANSELH=0x00; ADCON0=0x83; ADCON1=0x00; TRISA=0x3F; TRISB=0x00; TRISC=0xFF; PORTA=0x00; PORTB=0x00; PORTC=0x00; while(1){  delay(1000);      PORTB=0b00000001;  delay(1000);  PORTB=0b00000010;  delay(1000);  PORTB=0b00000100;  delay(1000);  PORTB=0b00001000;  delay(1000);  PORTB=0b00000000;  delay(1000); } return (EXIT_SUCCESS); } void delay(int a){     //crystal frequency =20MHz //if x=1;(a)msec_Delay //if x=1000;(a)sec_Delay #define x 1 #define p 246/5*2 int t;int u;int v;v=a*x; for(t=1;t<=v;t++){ for(u=1;u<=p;u++){ ; } } }; あと 投稿時にtabキーを使用するには どうしたらいいでしょう

  • PICでダイナミック点灯 なぜかLEDがOFF

    8×8のLEDマトリクスをダイナミック点灯制御するのに PIC16F1938を使用し PORTAをX軸 PORTBをY軸 として、以下のようなコードを書きましたが、 なぜか、1秒ぐらいで全て消灯してしまいます トラブルシューティングが終わりません 分かる方、教えて頂けませんか? XC8を使用しています // PIC16F1938 #include <stdio.h> #include <stdlib.h> #include <xc.h> #include<math.h> #include<stdbool.h> #define _XTAL_FREQ 32000000 // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. // CONFIG1 #pragma config FOSC = INTOSC #pragma config WDTE = OFF #pragma config PWRTE = OFF #pragma config MCLRE = OFF #pragma config CP = OFF #pragma config CPD = OFF #pragma config BOREN = OFF #pragma config CLKOUTEN = OFF #pragma config IESO = OFF #pragma config FCMEN = OFF // CONFIG2 #pragma config WRT = OFF #pragma config VCAPEN = OFF #pragma config PLLEN = ON #pragma config STVREN = OFF #pragma config BORV = LO #pragma config LVP = OFF #define true 1 #define false 0 void main(){ OSCCON = 0b11110000; TRISA = 0x00; TRISB = 0x00; TRISC = 0x00; ANSELA = 0x00; ADCON0 = 0x00; ADCON1 = 0x00; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; unsigned char i; LATA=0b11111110; LATB=0b10000000; unsigned char b; bool a; b=0b11111110; while (true) { for(i=1;i<=8;i++){ __delay_ms(1); a=b>>7; b=b<<1; b=b|a; LATA=b; } a=LATB>>7; LATB=LATB<<1; LATB=LATB|a; } }

  • PIC18F2550・コンパイルできない(再掲)

    初めて投稿します。 技術職(機械系)の会社員です。 マイコンプログラム作成歴:約3ヶ月のほぼド素人です。 現在、会社の技術研修でPIC18F2550を使ったライントレーサの動作プログラムを作成しています。先日までPIC16F84A&88でのプログラミングを行なっており、基本は理解できているつもりです。 …が、これまで見た事のないエラーコードが出てしまい、理由がわからず困っています。 エラーコードは、[1101]lvalue required と[1105]symbol '○○○' has not been defined というもので、コンパイラのユーザーガイドを見ると、変数(GIE,LATA0等)の認識ができない?エラーのようです。ヘッダーファイルのインクルードもしており、これまでの84A&88では出なかったエラーです。 webも調べましたが、わかりませんでした。 作成環境はMPLAB V8.36、MPLAB C18コンパイラV3.33 です。 エラーメッセージ画面添付、ソースコード掲載しますので、PICプログラムに精通されている方、間違い部分をご教授頂けないでしょうか? 何卒ご協力のほどよろしくお願いします。 --【以下、コード抜粋】-- //●使用マイコン:PIC18F2550 //===《初期設定》=== //---<ヘッダーファイル>--- #include<p18f2550.h> #include"delays.h" //---<コンフィグレーション>--- #pragma config PLLDIV = 5 #pragma config CPUDIV = OSC1_PLL2 #pragma config USBDIV = 2 #pragma config FOSC = HSPLL_HS #pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config PWRT = ON #pragma config BOR = OFF #pragma config BORV = 3 #pragma config VREGEN = OFF #pragma config WDT = OFF #pragma config WDTPS = 1 #pragma config MCLRE = ON #pragma config LPT1OSC = OFF #pragma config PBADEN = OFF #pragma config CCP2MX = ON #pragma config STVREN = OFF #pragma config LVP = OFF #pragma config XINST = OFF #pragma config DEBUG = OFF #pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF #pragma config CPB = OFF, CPD = OFF #pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF #pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF #pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF #pragma config EBTRB = OFF //---<関数宣言>--- void ioport(void); void interr(void); void pwm_settei(void); void move_A(void); void move_B(void); void delay_ms(long); //---<変数宣言>--- int c_flg = 0; //変数「c_flg」を宣言 //------------------------------------------------------------ //===《動作プログラム》=== //---<メイン関数>--- void main() { ioport(); interr(); pwm_settei(); while(1) { move_A(); } } //---<サブルーチン>--- void ioport(void) //[入出力ポート初期設定] { ADCON1 = 0b00001111; //A/D設定:全ポートデジタル TRISA = 0b00000000; //ポートA・I/O設定 TRISB = 0b11111111; //ポートB・I/O設定 TRISC = 0b00110000; //ポートC・I/O設定 } void interr(void) //[割り込み初期設定] { GIE = 1; //グローバル割り込み設定:許可 TMR2IE = 1; //タイマ2割り込み設定:許可 } --【途中省略】-- void move_A(void) //[動作A(直線&曲線走行モード)] { switch(PORTB) { case 0b01000000 : //センサB(内左)認識 CCPR1L = 100; //CCP1 Duty値設定 CCPR2L = 30; //CCP2 Duty値設定 LATC7 = 1; //モータR1:正転 LATA0 = 1; //モータL1:正転 LATC6 = 1; //モータR2:ON LATA1 = 1; //モータL2:ON break; --【以下続く】--

  • LCDを用いたカウントダウンプログラムについて

    今、PIC16F84AとLCDを用いて255からカウントダウンするところをLCDに表示するプログラムを作っています。 開発環境は ・MPLAB X IDE ・XC8コンパイラー ・PIC Kit3 を使っています。 プログラムはコンパイル、ビルドおよび書き込みは正常にできます。 しかし、いざ動かしてみるとカウントが「255」から「254」にならず「52」になってしまいます。 プログラムのどこがおかしいか全くわかりません。 また、プログラムにおいてLCDの表示ルーチンは、「Hi-Tech C」のサンプルを使用していて (Delay関数の個所をXC8用に書き換えています。)パスコンは、つけたほうが良いのですが、今回はつけていません。 参考のため回路図とプログラムを掲載しますので解決策がありましたら教えてください。 よろしくお願いいたします。 ////////////////以下ソースコード//////////////////// /* * File: main.c * * Created on 2015/12/24, 16:37 */ //#define _LEGACY_HEADERS #include <pic.h> #include <stdlib.h> #include "lcd.h" #define _XTAL_FREQ 4000000 #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (Power-up Timer is disabled) #pragma config CP = OFF // Code Protection bit (Code protection disabled) void ioport(void); void main(void) { unsigned char data; char str[2]; ioport(); lcd_init(); data=255; while(1){ lcd_clear(); lcd_goto(0x00); itoa(str,data,10); lcd_puts(str); if(data<0){ data=255; } __delay_ms(250); __delay_ms(250); data--; } } void ioport(void) { TRISA=0x00; PORTA=0x00; TRISB=0x00; PORTB=0x00; } //////////////////////////////////

  • マイコンを使ったダイオード点滅(PIC18F)

    こんばんは。 まだマイコンを使い始めて数週間のひよっこです。 ただいま,PIC18F2550をつかってダイオードの点滅(スイッチによる操作)をおこなっています。 以下にソースを示します。 /*RA0のスイッチによってRC0を点滅させるプログラム*/ ~condigは省略~ void ioport(){ //1->input,0-> output TRISC = 0; //RC => all out put TRISA = 0xFF; //PORTA all input LATC=0x00; } void high(){ PORTCbits.RC0 = 1; } void low(){ PORTCbits.RC0 = 0; } void main(void) { ioport(); while(1){ if(PORTAbits.RA0){ low(); } else{ high(); } } } RA0のON,OFFによってダイオードのON,OFFを行いたいのですが,入力ポートがうまく設定できてないせいか、常にON(high)になってしまいます。 すごく初歩的な質問でしょうが、 アドバイスをお願いいたします。

  • switch文かif文か?

    スイッチ(SW50~SW80)を押したら、それに対応したコマンドを送る。というものを作っています。 スイッチはスライドスイッチなので、 1)ON(0)の間だけコマンドを出して、OFF(1)は止める。 2)ONしている間に別のスイッチが入ったら止める。 という風に組みたいのですが、中々上手くいきません。 8ピンのスライドスイッチなのですが、1~4はIDとして、5~8をコマンドとして使います。 なので、1~4は絶対にONになります。とすると、2)にしたいとき、defaultが使えなくて…if文を入れたらややこしくなりました。 もっと簡潔に、かつ解りやすく書くにはどうしたらいいでしょうか? #define SW1 input(PIN_C0) // ID #define SW2 input(PIN_C1) // ID #define SW3 input(PIN_C2) // ID #define SW4 input(PIN_C3) // ID #define SW50 PIN_C4 #define SW60 PIN_C5 #define SW70 PIN_C6 #define SW80 PIN_C7 uchar LED_ON(void){ uchar DATA; DATA=0x50; DATA+=0x4F; DATA+=0x4E; return(DATA); } uchar LED_OFF(void){ uchar DATA; DATA=0x50; DATA+=0x4F; DATA+=0x46; return(DATA); } void LED(void){ ulong n; uchar DATA; while(1){ WriteFSKbyte(DATA); switch(n){ case SW50:DATA=LED_ON(); if((SW50||SW60||SW80)==0){ DATA=LED_OFF(); } break; case SW60:while(SW60==0){ DATA=LED_ON(); DelayMs(1000); DATA=LED_OFF(); DelayMs(1000); if((SW50||SW70||SW80)==0) break; } break; case SW70:while(SW70==0){ DATA=LED_ON(); DelayMs(500); DATA=LED_OFF(); DelayMs(500); if((SW50||SW60||SW80)==0) break; } break; case SW80:DATA=LED_OFF(); if((SW50||SW60||SW80)==0){ DATA=LED_OFF(); } break; } } }

  • PIC18F2550の割り込み処理について

    PIC18F2550を使って、外部入力割り込みがちゃんと入るかどうかをチェックするため非常に簡単なサンプルコードを書いてみたのですが割り込みが発生しないのでどなたかご助力お願いします。(コンパイラ : MPLAB C18) とりあえずスイッチを押せばINT2ピンに5Vが入力され、割り込みでLEDを点滅させるという主旨で以下のコードを書きこんで動作させました。 #include <p18f2550.h> #include <delays.h> #include <portb.h> #pragma config FOSC = INTOSCIO_EC, FCMEN = ON, IESO = OFF #pragma config PWRT = OFF, BOR = OFF, VREGEN = OFF #pragma config WDT = OFF, CCP2MX = OFF #pragma config PBADEN = ON, LPT1OSC = ON, MCLRE = OFF #pragma config STVREN = ON, LVP = OFF, XINST = OFF #pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF #pragma config CPB = OFF, CPD = OFF, WRT0 = OFF, WRT1 = OFF #pragma config WRT2 = OFF, WRT3 = OFF, WRTC = OFF #pragma config WRTD = OFF, EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF #pragma config EBTR3 = OFF, EBTRB = OFF int i; void isr(void); #pragma code isrcode = 0x0000008 void isr_direct(void) {_asm GOTO isr _endasm} #pragma code #pragma interrupt isr void isr(void) { //外部入力割り込みの処理はここに記述 INTCON3bits.INT2IF = 0; for(i=0; i<10; i++) { LATCbits.LATC1 = 1; Delay10KTCYx(255); LATCbits.LATC1 = 0; Delay10KTCYx(255); } } void main() { OSCCON = 0b01110000; //システムクロックを8MHZに設定 TRISA = 0b1111111; //ポートAをすべて入力に設定 TRISB = 0b11111111; //ポートBをすべて TRISC = 0; //ポートCをすべて出力に設定 //ポートRB2の外部割込みON, 立上がりエッジでON, Bポートの抵抗プルアップOFF OpenRB2INT(PORTB_CHANGE_INT_ON & RISING_EDGE_INT & PORTB_PULLUPS_OFF); RCONbits.IPEN = 0; //割り込み優先制御OFF INTCON3bits.INT2IE = 1; INTCONbits.GIE = 1; //全割り込み許可 while(1); } しかし、スイッチを押しても割り込み処理に移行せず無反応のままです。 スイッチを押した時にINT2ピンに5V入力があることはテスターで確認したので、ソースコードの方に問題があるかと思います。 よろしくお願いします。

  • C言語(PIC関連ですが・・・)

    センサーが接続されたPICマイコンでDCモータを制御する際に、前のセンサーと次のセンサーの間隔が長く、DCモータが停止してしまうので、前のセンサーの信号を次のセンサーの信号が入力されるまで保持されるようなプログラムを作りたいのですが、どのようなプログラムにしたらよいでしょうか・・・ ちなみに、下が試作プログラムの一部です。 if(b== 0x39) //センサ1が入力されたとき { PORTA = 0b00000010; Delay_ms(1); PORTC = 0b00000000; Delay_ms(1); PORTD = 0b00000001; Delay_us(350); PORTD = 0b00000000; Delay_us(300); } if(b== 0x3d) //センサ2が入力されたとき { PORTA = 0b00000001; Delay_ms(1); PORTC = 0b00000000; Delay_ms(1); PORTD = 0b00000001; Delay_us(325); PORTD = 0b00000000; Delay_us(300); }

  • PIC16F88の使い方?に関する質問(アセンブラ)

    現在PICの16F88に書きこむプログラムをアセンブラで書いてます。4番ピンのMCLRをRA5として使いたいのですが、MPLABのWATCHの機能を使って、ポートAの動きを見てみると、ポートAが出力になっているはずなのに、何をしてもポートAの0~4がHにならず、ポートAのRA5はBSF,BCFの命令が利きません。コンフィグの設定が怪しいと思うのですが、自分には理由が分からないので、誰か教えてください。お願いします。(下に書いたプログラムはテスト用に書いたプログラムなので特に目的はありません) ;外部発振,セラロック20MHz使用 LIST P=PIC16F88 INCLUDE P16F88.INC __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF BSF STATUS,RP0 MOVLW B'000000' MOVWF TRISA MOVLW B'00000000' MOVWF TRISB BCF STATUS,RP0 MAIN CLRF PORTA MOVLW B'11111111' MOVWF PORTA MOVWF PORTB BSF PORTA,0 BCF PORTA,0 BSF PORTA,1 BCF PORTA,1 BSF PORTA,2 BCF PORTA,2 BSF PORTA,3 BCF PORTA,3 BSF PORTA,4 BCF PORTA,4 BSF PORTA,5 BCF PORTA,5 GOTO MAIN END

専門家に質問してみよう