目次

安全確認装置

 高電圧を扱う装置から、規定電圧になっているのかを
 確認して、全部が準備できているのかを、1ビットで
 判断できるユニットを考えました。

 回路は、以下。



 動作は、単純で各装置が準備完了かを、論理値で出力して
 1バイトの各ビットにアサインして処理します。

 アナログコンパレータでは、高電圧装置の出力電圧を
 扱いやすい電圧まで分圧し、その電圧を規定値と比較
 して論理値に変換。

 アナログマルチプレクサは、最大8装置分の準備OK状態を
 入力するために使います。

 ピン数の多いマイコンは、プログラム容量も大きいので
 勿体無いと考えれば、アナログマルチプレクサを使って
 論理値を入力する方が得策でしょう。

 今回は、PIC12F1501を使っています。

 動作シーケンスは、次のように考えました。
  1. マルチプレクサを使い、各装置の準備状態を論理値で入力
  2. 取得した論理値で、OK、NGの信号を出力
  3. 時間待ち
  4. 1に戻る
 時間待ちがあるので、タイマー割込みを使ってmain処理の  中に入れればよいと判断。  次のように無限ループを構成して対応。 /* timer interrupt handling */ if ( TFLAG == ON ) { /* clear flag */ TFLAG = OFF ; /* initialize */ xstate = 0 ; /* get current state */ for ( ii = 0 ; ii < 8 ; ii++ ) { /* impress select */ PORTA = ii & 7 ; /* get state and store */ if ( PORTA.F4 == ON ) { /* get bit pattern */ tmp = bpat[ii] ; /* set target bit */ xstate |= tmp ; } } /* copy */ state = xstate ; }  イベント通知フラグを利用して、マルチプレクサを使っての  論理値入力とします。  1バイトの変数に、1ビットずつ、該当装置の準備OKかの  フラグをセットかリセット。  割込みハンドラでは、イベント通知フラグをセットする  だけにします。 void interrupt(void) { /* generate 500Hz */ if ( INTCON.T0IF == ON ) { /* clear flag */ INTCON.T0IF = OFF ; /* initialize (/250) */ TMR0 = CNTBEGIN ; /* set flag */ TFLAG = ON ; } }  タイマー0は、オーバーフローで割込みが発生するので  256−6=250となるように再初期化をしてます。  入出力設定やレジスタの初期化などを、ひとつの関数に  まとめて、わかりやすくします。 void init_usr(void) { /* 4MHz */ OSCCON = (0x0d << 3) | 0x03 ; /* disable D/A converter */ DACCON0.DACEN = OFF ; /* disable compare module */ CM1CON0.C1ON = OFF ; CM1CON0.C1OE = OFF ; /* initialize A/D converter */ ADCON0.ADON = OFF ; /* I/O state */ PORTA = 0x00 ; /* I/O directions */ TRISA = 0x18 ; /* bit0,1,2,5 as output , others as input */ /* initialize Timer 0 */ { /* 4MHz/4 = 1MHz -> 1MHz/8 = 125kHz prescaler = 1:8 */ OPTION_REG = 0x02 ; /* 256 - 6 = 250 => 125kHz / 250 = 500 Hz */ TMR0 = CNTBEGIN ; /* enable timer0 overflow interrupt */ INTCON.T0IE = ON ; } /* enable general interrupt */ INTCON.GIE = ON ; /* initialize flags */ xflags = 0 ; /* enable general interrupt */ INTCON.GIE = ON ; /* clear flag */ xflags = 0 ; /* others */ xstate = 0 ; state = 0 ; bpat[0] = 128 ; bpat[1] = 64 ; bpat[2] = 32 ; bpat[3] = 16 ; bpat[4] = 8 ; bpat[5] = 4 ; bpat[6] = 2 ; bpat[7] = 1 ; }  クロックは内部を使い、A/D変換器やコンパレータは  使わないようにしてあります。  また、グローバルの割込みを許可し、タイマー割込み  の周期を設定。  1バイトの変数の中の装置担当ビットをセットするため  予め配列の中に、1ビットだけをセットして格納して  わかりやすくしておきました。  まとめると、以下。 /* scon.c check unit stanby PIC12F1501 4MHz system clock PORTA_0 74HC4051 A PORTA_1 74HC4051 B PORTA_2 74HC4051 C PORTA_3 reset PORTA_4 input PORTA_5 ouput Author Kensuke Ooyu Date 14th September 2020 create */ /* redefine data type */ typedef unsigned char UBYTE ; #define OFF 0 #define ON OFF+1 #define CNTBEGIN 6 #define NOWSTATE PORTA.F5 volatile UBYTE xflags ; #define TFLAG xflags.F0 #define SBIT xflags.F1 volatile UBYTE tmp ; volatile UBYTE ii ; volatile UBYTE xstate ; volatile UBYTE state ; volatile UBYTE bpat[8] ; /* function prototype */ void init_usr(void); /* interrupt handler */ void interrupt(void) { /* generate 500Hz */ if ( INTCON.T0IF == ON ) { /* clear flag */ INTCON.T0IF = OFF ; /* initialize (/250) */ TMR0 = CNTBEGIN ; /* set flag */ TFLAG = ON ; } } void main(void) { /* user initialize */ init_usr(); /* endless loop */ while ( ON ) { /* timer interrupt handling */ if ( TFLAG == ON ) { /* clear flag */ TFLAG = OFF ; /* initialize */ xstate = 0 ; /* get current state */ for ( ii = 0 ; ii < 8 ; ii++ ) { /* impress select */ PORTA = ii & 7 ; /* get state and store */ if ( PORTA.F4 == ON ) { /* get bit pattern */ tmp = bpat[ii] ; /* set target bit */ xstate |= tmp ; } } /* copy */ state = xstate ; } /* judge and impress */ if ( state == 0xff ) { NOWSTATE = ON ; } else { NOWSTATE = OFF ; } } } /* define function body */ void init_usr(void) { /* 4MHz */ OSCCON = (0x0d << 3) | 0x03 ; /* disable D/A converter */ DACCON0.DACEN = OFF ; /* disable compare module */ CM1CON0.C1ON = OFF ; CM1CON0.C1OE = OFF ; /* initialize A/D converter */ ADCON0.ADON = OFF ; /* I/O state */ PORTA = 0x00 ; /* I/O directions */ TRISA = 0x18 ; /* bit0,1,2,5 as output , others as input */ /* initialize Timer 0 */ { /* 4MHz/4 = 1MHz -> 1MHz/8 = 125kHz prescaler = 1:8 */ OPTION_REG = 0x02 ; /* 256 - 6 = 250 => 125kHz / 250 = 500 Hz */ TMR0 = CNTBEGIN ; /* enable timer0 overflow interrupt */ INTCON.T0IE = ON ; } /* enable general interrupt */ INTCON.GIE = ON ; /* initialize flags */ xflags = 0 ; /* enable general interrupt */ INTCON.GIE = ON ; /* clear flag */ xflags = 0 ; /* others */ xstate = 0 ; state = 0 ; bpat[0] = 128 ; bpat[1] = 64 ; bpat[2] = 32 ; bpat[3] = 16 ; bpat[4] = 8 ; bpat[5] = 4 ; bpat[6] = 2 ; bpat[7] = 1 ; }
目次

inserted by FC2 system