LEDを点滅させるためのICとして、M34シリーズの三端子LEDフラッシャ-ICというものが有ります。
これは、トランジスタのように3本の端子が出ているパーツで、接続するだけで指定された周期でLEDを点滅させる事が出来ます。
点滅の周期は型番によって異なり、以下の通りとなっています。
M34-1L 1.0 秒周期 ON-OFF比率 = 1:8 M34-2L 0.5 秒周期 ON-OFF比率 = 1:8 M34-4L 0.25 秒周期 ON-OFF比率 = 1:8 M34-8L 0.125秒周期 ON-OFF比率 = 1:2 |
実際にどんな感じで点滅するか、YouTubeに動画があがってました。
M34シリーズの主な用途は、製造元のデータシートによると以下のものが想定されているようです。
点滅するバッチ イヤリング グリーティングカード ディスコライト 自転車のライト 車のアラーム 警告ライト クリスマス用のデコレーション おもちゃ等... |
このICは、1個50円くらいの安価なICですが仕様上1つで最大2~3つのLEDまでしかコントロールする事が出来ません。
そこで今回は、このフラッシャ-IC相当の機能をPIC(16F88)で再現してみます。
PICの16F88は、I/Oに最大16ピン割り当てることが出来るため、5倍以上のLEDをコントロールできます。
また、マイコンを使用するとLED毎に異なる点滅パターンを割り当てたり、すべてのLEDを正確に同じタイミングで点滅させる事も簡単です。
で、実際に作ってみた結果が以下の通りです。
4秒周期で、M34-1L, M34-2L, M34-8Lの機能を順に再現しています。
3つ目の0.125秒周期のパターンは動画だと綺麗に点滅できていなさそうですが、これは動画がフレームレートが15fpsしかないからで、実物を見るとちゃんと毎秒8回点滅しています。
また回路は、前回作ったPICライタの動作確認回路を流用しました。
プログラムは以下の通りです。
タイマ割込みを使用して点滅パターンを制御しています。
#include <stdio.h> #include <htc.h> #define TIMER_INTERVAL (0xffff - 20000) // TMRモジュールのカウント初期値 // 2000を指定すると 8MHz, 1/1プリスケーラで1msecになる __CONFIG ( FOSC_INTOSCIO & // 内部クロック WDTE_OFF & // watchdogオフ PWRTE_OFF & // Power-up Timer MCLRE_OFF & // MCLRピンを汎用I/Oとして使用 BOREN_OFF & // 電圧降下によるリセットオフ LVP_OFF & // Low-Voltage Programmingオフ CPD_OFF & // EEPROM プロテクトオフ WRT_OFF & // FrashROMプロテクトオフ DEBUG_ON & // ICDデバッグを有効にする CCPMX_RB0 & // RB0をCCPとして使用 CP_OFF ); // コードプロテクトオフ // プロトタイプ宣言 void SetLED( unsigned char data ); void HardwareSetup( void ); // グローバル変数 unsigned char GL_LedData; // LED表示パターン unsigned long int GL_SystemTimeSec = 0; // CPU起動からの経過時間 //**************************************************************************************** // Function : main // Description : メイン処理 //**************************************************************************************** void main( void ) { unsigned long int loop = 0; // ハードウェアの初期化 HardwareSetup() // 割り込みベースで動作するので、メイン処理は無し while( 1 ) { ; // nop } } //**************************************************************************************** // Function : intr // Description : 割り込み処理(10msec周期) //**************************************************************************************** static void interrupt intr( void ) { static int intr_counter; //------------------------------------ // Timer1割り込みが発生したときの処理 //------------------------------------ if ( PIR1bits.TMR1IF == 1 ) { TMR1 = TIMER_INTERVAL; // タイマーをリセット //---------------------------- // カウンタを加算(100で1秒) //---------------------------- intr_counter++; if ( intr_counter >= 100 ) { intr_counter = 0; GL_SystemTimeSec++; } //---------------------------------------------- // 点滅させるべきLEDを、1秒周期で切り替える //---------------------------------------------- if ( GL_SystemTimeSec % 2 == 0 ) { GL_LedData = 0b00111100; } else { GL_LedData = 0b11000011; } //---------------------------------------------- // 4秒周期で点滅パターンを切り替える //---------------------------------------------- switch ( ( GL_SystemTimeSec / 4 ) % 3 ) { case 0: // M34-1L相当点滅パターン : 1秒(ON-OFF比1:8) if ( intr_counter <= 12 ) { SetLED( GL_LedData ); } else { SetLED( 0x00 ); } break; case 1: // M34-2L 相当点滅パターン : 0.5秒(ON-OFF比1:8) if ( (intr_counter >= 0 && intr_counter <= 6) || (intr_counter >= 50 && intr_counter <= 56) ) { SetLED( GL_LedData ); } else { SetLED( 0x00 ); } break; case 2: // M34-8L 相当点滅パターン : 0.125秒(ON-OFF比1:2) if ( (intr_counter%12) <= 5 ) { SetLED( GL_LedData ); } else { SetLED( 0x00 ); } break; } PIR1bits.TMR1IF = 0; // 割り込みフラグを落とす } } //**************************************************************************************** // Function : HardwareSetup // Description : ハードウェア初期化処理 //**************************************************************************************** void HardwareSetup( void ) { //---------------------------------- // 内部クロックを8MHz駆動にする //---------------------------------- OSCCONbits.IRCF = 7; //---------------------------------- // ポートのモードを初期化する //---------------------------------- ANSEL = 0; T1CONbits.T1OSCEN = 0; TRISB = 0x00; TRISAbits.TRISA0 = 0; // RA0を出力にする TRISAbits.TRISA1 = 0; // RA1を出力にする //---------------------------------- // Timer1の初期化 //---------------------------------- PIR1bits.TMR1IF = 0; // Timer1割り込みフラグを落としておく PIE1bits.TMR1IE = 1; // Timer1割り込みを有効 T1CONbits.T1CKPS = 0; // プリスケーラを1/1にする TMR1 = TIMER_INTERVAL; // タイマー値をセットします T1CONbits.TMR1ON = 1; // Timer1を有効にする //---------------------------------- // 割り込みを有効にする //---------------------------------- INTCONbits.PEIE = 1; // 外部割込みを有効にする INTCONbits.GIE = 1; // Grobal interruptを有効にする } //**************************************************************************************** // Function : SetLED // Description : 指定されたビットに対応するLEDを点灯する //**************************************************************************************** void SetLED( unsigned char data ) { PORTBbits.RB0 = (data & 0x01) ? 1 : 0; PORTBbits.RB1 = (data & 0x02) ? 1 : 0; PORTBbits.RB2 = (data & 0x04) ? 1 : 0; PORTBbits.RB3 = (data & 0x08) ? 1 : 0; PORTBbits.RB4 = (data & 0x10) ? 1 : 0; PORTBbits.RB5 = (data & 0x20) ? 1 : 0; PORTAbits.RA0 = (data & 0x40) ? 1 : 0; PORTAbits.RA1 = (data & 0x80) ? 1 : 0; } |
関連記事
コメントを残す