目次
前
次
方式設計
ハードウエア、ファームウエア構成がわかれば
マイコンでのPLC実現方式を検討します。
マイコンで実現するPLCは、次の2つのモードで動作
できるとシステム構築する場合に便利です。
ラダー図で記述された回路情報を、マイコンのもつ
不揮発性メモリ(ROM)に転送して設定します。
実動作は、ROMに格納した回路情報を基づき、入力
情報から、出力状態を定めていきます。
回路情報設定
最近のマイコンは、大容量のEEPROMを内蔵しています。
内蔵EEPROMを持たない場合は、外付けになりますが
安価で大容量のEEPROMが各種市販されているので、
部品選択には不自由しません。
このEEPROMに、回路情報をシリアル転送できるよう
マイコンのファームウエアを組上げます。
スキャン処理で利用するラダー図の回路情報は、1行
あたり16ビットとします。
回路情報を設定する場合のイメージは、以下。
実動作
PLCが実動作する場合は、次のシーケンスを
繰り返します。
- 入力データを入力メモリに保存
- 回路動作スキャン
- スキャン結果を出力メモリに保存
1msか10msごとに、1〜3の動作実行します。
周期的に実行するので、タイマー割込みでフラグを
セットしてもらい、フラグの状態を見てシーケンス
を実行します。
回路動作スキャンは、ROMに保存してある情報を
取出し、解釈してからメモリに結果を保存します。
ROMに保存してある情報のフォーマットに従い
プログラムを記述します。
実動作のイメージは、以下。
ファームウエアの雛形
回路情報設定と実動作のだいたいの内容を決めたので
ファームウエアの雛形を作成します。
マイコンのファームウエアは、C言語で記述します。
制御を扱うファームウエアは、停止できないので
次のように、無限ループを構成します。
#define OFF 0
#define ON OFF+1
while (ON) {
}
回路情報設定か実動作のいずれかのモードで動作する
ので変数modeを用意し動作を切り替えます。
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
UBYTE mode ;
#define IDLE 0
#define RUN IDLE+1
while (ON) {
if ( mode == RUN ) {
}
if ( mode == IDLE ) {
}
}
実動作では、タイマー割込みで時間経過したことを
示すフラグTFLAGを用意し、このフラグをトリガーに
使います。
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
UBYTE mode ;
#define IDLE 0
#define RUN IDLE+1
while (ON) {
if ( mode == RUN ) {
if ( TFLAG == ON ) {
TFLAG = OFF ;
get_input_information();
perform_scanning();
update_output();
}
}
if ( mode == IDLE ) {
}
}
関数get_input_information、perform_scanning、update_output
は、別途定義します。
回路情報設定では、通信バッファにデータが設定
されたことを示すフラグSFLAGを利用します。
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
UBYTE mode ;
typedef unsigned short UWORD ;
UWORD cadr ;
UWORD cdat ;
#define IDLE 0
#define RUN IDLE+1
while (ON) {
if ( mode == RUN ) {
if ( TFLAG == ON ) {
TFLAG = OFF ;
get_input_information();
perform_scanning();
update_output();
}
}
if ( mode == IDLE ) {
if ( SFLAG == ON ) {
SFLAG = OFF ;
cadr = get_adr();
cdat = get_dat();
put_dat_eeprom( cadr , cdat );
}
}
}
関数get_adr、get_dat、put_dat_eepromは、別途定義します。
PLCを実現するファームウエアの雛形は、この程度です。
この雛形に、必要な内容を付加すると、PLCになります。
C言語を少しでも学習した技術者であれば、充分内容を
理解できるレベルです。
変数modeは、マイコンにトグルスイッチをつけてONか
OFFの状態を、無限ループの中で設定します。
チャタリング除去が必要なので、タイマー割込みが
設定するMFLAGの状態とシフトレジスタで、モードを
決定します。
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
UBYTE mode ;
UWORD cadr ;
UWORD cdat ;
UWORD mshift;
#define IDLE 0
#define RUN IDLE+1
while (ON) {
if ( MFLAG == ON ) {
MFLAG = OFF ;
mshift <<= 1 ;
mshift &= 0xfe ;
mshift |= MODE_SWITCH ;
mode = IDLE ;
if ( mshift == 0x00 ) { mode = RUN ; }
}
if ( mode == RUN ) {
if ( TFLAG == ON ) {
TFLAG = OFF ;
get_input_information();
perform_scanning();
update_output();
}
}
if ( mode == IDLE ) {
if ( SFLAG == ON ) {
SFLAG = OFF ;
cadr = get_adr();
cdat = get_dat();
put_dat_eeprom( cadr , cdat );
}
}
}
どちらのモードかは、LEDをつけて表示すると
よりわかりやすいでしょう。
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
UBYTE mode ;
UWORD cadr ;
UWORD cdat ;
UWORD mshift;
#define IDLE 0
#define RUN IDLE+1
while (ON) {
if ( MFLAG == ON ) {
MFLAG = OFF ;
mshift <<= 1 ;
mshift &= 0xfe ;
mshift |= MODE_SWITCH ;
mode = IDLE ;
if ( mshift == 0x00 ) { mode = RUN ; }
ILED = LED_OFF ;
if ( mode == RUN ) { ILED = LED_ON ; }
}
if ( mode == RUN ) {
if ( TFLAG == ON ) {
TFLAG = OFF ;
get_input_information();
perform_scanning();
update_output();
}
}
if ( mode == IDLE ) {
if ( SFLAG == ON ) {
SFLAG = OFF ;
cadr = get_adr();
cdat = get_dat();
put_dat_eeprom( cadr , cdat );
}
}
}
C言語のmain関数で記述すると、次のようになります。
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
UBYTE mode ;
UWORD cadr ;
UWORD cdat ;
UWORD mshift;
#define IDLE 0
#define RUN IDLE+1
int main(void )
{
di(); /* disable interrupt */
initialize();
ei(); /* enable interrupt */
/* endless loop */
while (ON) {
/* judge mode */
if ( MFLAG == ON ) {
MFLAG = OFF ;
mshift <<= 1 ;
mshift &= 0xfe ;
mshift |= MODE_SWITCH ;
mode = IDLE ;
if ( mshift == 0x00 ) { mode = RUN ; }
ILED = LED_OFF ;
if ( mode == RUN ) { ILED = LED_ON ; }
}
/* sequence control */
if ( mode == RUN ) {
if ( TFLAG == ON ) {
TFLAG = OFF ;
get_input_information();
perform_scanning();
update_output();
}
}
/* set ladder diagram infomation */
if ( mode == IDLE ) {
if ( SFLAG == ON ) {
SFLAG = OFF ;
cadr = get_adr();
cdat = get_dat();
put_dat_eeprom( cadr , cdat );
}
}
}
}
目次
前
次