マイコンを使ってダイオード点滅を行う方法

このQ&Aのポイント
  • マイコンを使ってダイオードの点滅を行う方法を解説します。
  • PIC18F2550を使用して、スイッチによってダイオードのON/OFFを制御するプログラムを紹介します。
  • 質問者は入力ポートの設定に問題があり、常にダイオードがONになってしまうと困っています。アドバイスをお願いします。
回答を見る
  • ベストアンサー

マイコンを使ったダイオード点滅(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)になってしまいます。 すごく初歩的な質問でしょうが、 アドバイスをお願いいたします。

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

  • ベストアンサー
noname#137556
noname#137556
回答No.1

RA0 はデフォルトでアナログ入力になっています。 ADCON1 でデジタル I/O に設定していますか? ↓p.111 参照 http://ww1.microchip.com/downloads/en/devicedoc/39632c.pdf

marumarumaaa
質問者

お礼

無事できました。 本当にありがとうございます。 まだまだわからない点が多々あると思いますのでよろしくお願いいたします。

関連するQ&A

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

    PIC初心者です。よろしくお願いします。 ※HI-TECH Cコンパイラを使用しています。 最近まで、PIC16F676を使用していましたが、 今回、PIC16F1823に変更することにしました。 プルグラムをPIC16F1823用に変更し、実行したところ思ったように動いてくれません。 いろいろ調べたところ割り込み処理がうまいこと出来ていないような気がします。 割り込みルーチンに飛んだ後、なぜか戻ってこないような気がします。 下記のコードは、簡単に書き直しました。 どなたか分かる方、お願いしますm(_ _)m --------------------------------------------- #include <htc.h> __CONFIG(FOSC_INTOSC & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_ON & CP_OFF); unsigned int i,Time; void main(void) { OSCCON = 0b01101010; //おそらく4MHz? //ポートA ANSELA = 0x00; //全てデジタル CM1CON0 = 0b00000111; //コンパレート無効化 CM1CON1 = 0b00000111; TRISA = 0b00111110; //ポートA入力出力設定 WPUA = 0b00110110; //ポートAプルアップビット指定 PORTA = 0b00000100; //各ピンデフォルト値 IOCAP = 0b00100000; //割り込みピン指定 //ポートC ANSELC = 0x00; //全てデジタル TRISC = 0b00000000; //ポートC入力出力設定 nWPUEN = 0; //プルアップ有効化 IOCIE = 1; IOCIF = 0; GIE = 1; i = 0; while(1){  if(i){   RC5 =1;   RC0 =0;  }else{   RC5 =0;   RC0 =1;  } } } void interrupt ISR(void){ //割込み if(IOCIF && !RA5){  if(i) i=0;else i=1; } IOCIF = 0; }

  • 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入力があることはテスターで確認したので、ソースコードの方に問題があるかと思います。 よろしくお願いします。

  • PIC 16F84A でLEDが点滅しない

    どんな事をしても、LEDが点滅しません何が原因なのかわかりません。何方か教えて頂けませんか。 環境は、Windowos8 MPLAB X IDE XC8 PICkit3  Pickit3対応ICSP書き込みアダブターです。 PICは PIC16F84A を使用しています。ソースコードは下記のようにしてあります。  #include <xc.h> // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. // CONFIG #pragma config FOSC = EXTRC // Oscillator Selection bits (RC oscillator) #pragma config WDTE = ON // Watchdog Timer (WDT enabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (Power-up Timer is disabled) #pragma config CP = OFF // Code Protection bit (Code protection disabled) #define_XTAL_FREQ 20000000 void main(void) { TRISA = 0x00; PORTA = 0x031; TRISB = 0x00; PORTB = 0x00; while (1) { PORTA = 0x02; Delay_ms(1000); PORTA = 0x01; Delay_(1000); } } ------------回路  PIC16F84A      ------------   18  RA1-----1Kオーム----- (K)LED(A)----←  5V      17  RA0----- 1Kオーム-----(K)LED(A)----←  5V     16  OSC1----             セラロック20MHZ -------- GND   15  OSC2----   14 VDD---------------← 5V    4  MCLR--------------← 5V 5 VSS----------------- GND   コンパイルも、書き込みもできましたが駄目でした。いろいろ試みましたが成功しません。 コンフィギレーションに決定的な間違いがあるのではないか?疑っております。 よろしくお願いいたします。

  • 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; }

  • 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; --【以下続く】--

  • 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; }

  • 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; } }

  • PIC 出力を持続したい

    鉄道模型のコントローラーを作っています。 マイコンはPIC16F886です。 以下のようなプログラムを作りました。 (ただし、mainよりも前の設定等は今回の質問に関係ないと思われますので、省略してあります) 質問箇所は(1)~(5)です。 while(RC3==0)のときその部分がループされるようになっていまして、ループから抜けた時に(1)(2)(3)で変更された内容は保持されているのですが、(4)(5)はループを抜けた瞬間に0になってしまいます。 たとえば、(1)と(4)の条件を満たしてRA1=1、RB6=1となり、relay1とrelay3がONになります。 しかしループを抜けると、relay1はONのままなのですがrelay3がOFFになってしまいます。 なぜでしょうか。 出力しているピンの問題なのですか? ご回答よろしくお願いします。 以下プログラム (省略) main() { PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; TRISA = 0b11111001; TRISB = 0b00111111; TRISC = 0b11111111; ANSEL = 0b00000001; ANSELH = 0b00111111; ADCON1 = 0b00000000; while(RC3==1); // マスコンを「非常」にしないと動作しない while(1) { if(RC3==0 && SPD==0) // マスコンが非常、かつ車両が停止している時 { while(RC3==0) // マスコンが非常のとき、無限ループ開始 { if(RC4==0) // 方向セレクトSWがRC4の時・・・(1) { RA2 = 0; // relay2をOFF DelayUs(20); RA1 = 1; // relay1をON } else if(RC5==0) // 方向セレクトSWがRC5の時・・・(2) { RA1 = 0; // relay1をOFF DelayUs(20); RA2 = 1; // relay2をON } else if(RC4==1 && RC5==1) // 方向セレクトSWが中立の時・・・(3) { RA1 = 0; // relay1をOFF DelayUs(20); RA2 = 0; // relay2をOFF } if(RC6==0) // 出力セレクトSWがRC6の時・・・(4) { RB6=1; // relay3をON } else if(RC7==0) // 出力セレクトSWがRC7の時・・・(5) { RB6=0; // relay3をOFF } } } ADCON0 = 0b10000001; // 最高速度をAN0から読み込む DelayUs(20); // ADCが安定するまで待つ GODONE=1; // ADC起動 while(GODONE); // ADC終了まで待つ MAX=ADRESH; // ADCの上位8ビットを最高速に代入 if(RA3==0) // マスコンが加速3の時 { ADCON0 = 0b10110101; // 加速度をAN13から読み込む } if(RA4==0) // マスコンが加速2の時 { ADCON0 = 0b10101101; // 加速度をAN11から読み込む } if(RA5==0) // マスコンが加速1の時 { ADCON0 = 0b10100101; // 加速度をAN9から読み込む } if(RC1==0) // マスコンが減速1の時 { ADCON0 = 0b10100001; // 加速度をAN8から読み込む } if(RC2==0) // マスコンが減速2の時 { ADCON0 = 0b10101001; // 加速度をAN10から読み込む } if(RC3==0) // マスコンが非常の時 { ADCON0 = 0b10110001; // 加速度をAN12から読み込む } DelayUs(20); // ADC安定するまで待つ GODONE=1; // ADC起動 while(GODONE); // ADC終了まで待つ ACC=ADRESH; // ADCの上位8ビットを加速度に代入 func01(); } }

  • PICマイコン16F84Aを使った入出力でつまづいてます。

    とても初心者な質問です。 色々調べましたがわかりませんでしたので質問させていただきます。 要するに、PORTAを書き換えてRA0~4につないだ任意のLEDを点灯させたいだけなんですが、うまいこといきません。 LEDの極性は間違いないようです。 以下がソースです。 このソースではb'11111'を転送する事で全てのポートAのLEDを点灯させたいつもりなのですが、実際のテストボードでは何故か RA0,RB3,RB5,RB7が点灯して、もうわけわかりません。どなたかご教授お願いします。 LIST P=PIC16F84A ; INCLUDE P16F84A.INC ; __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF ORG 0 INIT BSF STATUS,RP0     CLRF TRISA CLRF  TRISB BCF STATUS,RP0 ; <メイン> LOOP MOVLW b'11111' MOVWF PORTA GOTO LOOP END

  • PICでLEDを点滅させる

    16F628Aを使ってLEDが点滅するプログラム作ることはできたのですが、それを16F873A用に組み替えてみたのですが点滅せずに点灯したままになります。ハード的な問題なのかそれともプログラム問題なのかがわかりません。マイコンの勉強をはじめたばかりなのでお教えいただければたすかります。 ちなみにプログラムは以下のようになっています。クロックは10MHzです。 開発環境はMPLABをつかっていて秋月のキットを使って書き込んでいます。 ; ; ; list p=pic16f873a #include <P16F873A.INC> __CONFIG _WDT_OFF & _HS_OSC & _CP_OFF & _PWRTE_ON & _LVP_OFF COUNT EQU 20H COUNT1 EQU 21H ORG 0 MAIN BSF STATUS,RP0 CLRF TRISA CLRF TRISB CLRF TRISC BCF STATUS,RP0 MOVLW B'11111111' MOVWF PORTC CALL LA CLRF PORTC CALL LA GOTO MAIN LA MOVLW B'11111111' MOVWF COUNT LOOP2 MOVLW B'11111111' MOVWF COUNT1 LOOP NOP NOP NOP NOP NOP NOP NOP DECFSZ COUNT1,1 GOTO LOOP DECFSZ COUNT,1 GOTO LOOP2 RETURN END