目次

命令検討

 ラダー図で記述された回路情報を、PLCで実行するために
 命令を利用して入力します。

 ラダー図の情報を命令に変換するアプリケーションを作成
 すればよいのですが、それは後にします。

 基本となる命令は、論理演算(論理積、論理和、反転)と
 リレーコイルの出力に限定します。
 カウンタやタイマーも必要ですが、基本命令の動作確認が
 とれてからとします。

 PLCの入力には、A接点、B接点が接続されます。
 接点情報は、1か0の論理値で表現します。

 A接点は、通常0でボタンを押すと1になります。
 B接点は、通常1でボタンを押すと0になります。

 この2接点の状態を入力できるように命令を定義します。

 命令だけでは、どの接点であるとか出力の情報が不明です。
 そこで、マイコンの中にあるメモリの指定ビット番号で対応
 をとります。
 ANDB、ORB、ENDには、指定ビット番号の情報は不要です。
 フォーマットは、次のようにします。


ビット番号とメモリサイズ

 命令の中には、ビット番号とパラメータを  必要とするものがあります。  ビット番号を0〜255の256とします。  8ビットマイコンのレジスタ幅が、1バイトで  あっても扱える範囲とします。  256ビットは、バイトで換算すると32バイト  になるので、配列で次のように領域を確保します。 #define MSIZE 32 unsigned char memory[MSIZE] ;  マイコンによっては、32バイトを確保できない  場合もありえます。その時は、MSIZEの値を小さく  して調整します。  ビット番号は、0〜255の8ビットで指定するので  1命令は8ビットよりも大きくなります。  切りのよいところで、1命令を16ビットで表現します。

カウンタ番号とメモリ

 命令の中には、カウンタ番号とパラメータを  必要とするものがあります。  カウンタ番号は、0〜15とします。  カウンタには、カウンタとタイマーカウンタがあります。  カウンタのビットサイズは、8ビットとします。 #define CSIZE 16 unsigned char counter[CSIZE] ;  タイマーカウンタは、10msのものと100msの2種類  利用できるようにします。  0から7は10msタイマー、8から15は100msタイマー  とします。 #define CTSIZE 8 unsigned char t000cnt[CTSIZE] ; unsigned char t100cnt[CTSIZE] ;

命令フォーマット

 ラダー図で記述された回路情報は、命令としてEEPROMに  保存します。  1命令=16ビットとしたので、16ビットの内部フォーマット  を仕様としてまとめます。  16ビットの下位8ビットをビット番号指定に利用します。  上位8ビットは、命令を上位ニブルに格納します。  下位ニブルは、タイマー、カウンタ命令を拡張するために  残しておきます。  各命令と16ビットの内容は、次のようにします。  (bは、1か0を表わすことにします。)  EEPROMへの格納は、ビックエンディアンとします。  アドレスが小さい1バイトに、命令コードを含んだ8ビットを格納。  アドレスが大きい1バイトに、ビット番号かパラメータを格納。

ラダー行数とEEPROMサイズ

 ラダーの1行を、1命令=16ビットで表現する仕様  としたので、EEPROMサイズで格納可能できる行数が  決まります。  最近は、128kバイトの容量をもつシリアルEEPROMも、  ワンコイン¥500以内で入手できるので、64x1024行  程度まで対応できます。  人間が管理できる上限行数は、1000行程度でしょう。  1024行として、EEPROMのサイズは2048バイトです。  最大1024行まで、ラダー図で表現できるとします。

関数定義

 ラダーの1行を、1命令=16ビットで表現する仕様を  確定したので、関連する関数を定義します。  ファームウエアの雛形で、利用関数は別途定義とした  ので、EERPOMに関係する関数を定義します。 get_adr  シリアル受信バッファから、EEPROMアドレスを取得します。  EEPROMのアドレスは、0〜1023行まで指定できる仕様にした  ので、16ビットの値を返します。 typedef unsigned short UWORD ; UWORD get_adr(void) { return 0 ; }  受信バッファrbufが配列で確保されているとします。  受信バッファには、1文字コマンド、パラメータの順で  データが格納されているとします。  受信バッファに格納されている1文字は、英数字なので  数値に変換しなければなりません。  この変換関数が、get_hexで定義済みと仮定します。 typedef unsigned short UWORD ; UWORD get_adr(void) { UWORD result ; /* get first byte */ result = get_hex( *(rbuf+1) ); /* get second byte */ result = (result << 4) | get_hex( *(rbuf+2) ); /* get third byte */ result = (result << 4) | get_hex( *(rbuf+3) ); /* get fourth byte */ result = (result << 4) | get_hex( *(rbuf+4) ); return result ; } get_dat  シリアル受信バッファから、EEPROMデータを取得します。  EEPROMのデータは、2バイトとしたので、16ビットの値を  返します。 typedef unsigned short UWORD ; UWORD get_dat(void) { return 0 ; }  受信バッファrbufには、アドレス、データと続けて  確保されているとします。  受信バッファに格納されている1文字は、英数字  なので数値に変換します。 typedef unsigned short UWORD ; UWORD get_dat(void) { UWORD result ; /* get first byte */ result = get_hex( *(rbuf+5) ); /* get second byte */ result = (result << 4) | get_hex( *(rbuf+6) ); /* get third byte */ result = (result << 4) | get_hex( *(rbuf+7) ); /* get fourth byte */ result = (result << 4) | get_hex( *(rbuf+8) ); return result ; } put_dat_eeprom  アドレスとデータをパラメータとして、EEPROMに  2バイトのデータを保存します。  アドレス、データとも16ビットなので、次のように  定義します。 typedef unsigned char UBYTE ; typedef unsigned short UWORD ; void put_dat_eeprom(UWORD adr,UWORD dat) { }  指定アドレスには、16ビットの上位を  指定アドレス+1には、下位を格納します。  1バイトの格納用関数write_eepromは定義  済みと仮定します。 void put_dat_eeprom(UWORD adr,UWORD dat) { UBYTE dhl ; /* get upper byte */ dhl = (UBYTE)(dat >> 8) ; /* store upper byte */ write_eeprom( adr , dhl ) ; /* get lower byte */ dhl = (UBYTE)(dat & 0xff) ; /* store lowerr byte */ write_eeprom( adr+1 , dhl ) ; } get_hex  16進数字を16進数値に変換します。 typedef unsigned char UBYTE ; UBYTE get_hex(UBYTE x) { return 0 ; } '0'〜'9'、'A'〜'F'、'a'〜'f'を0〜9、10〜15、10〜15  に変換します。 typedef unsigned char UBYTE ; UBYTE get_hex(UBYTE x) { UBYTE result ; /* default */ result = 0 ; /* '0' -- '9' */ if ( '0' <= x && x <= '9' ) { result = x - '0' ; } /* 'A' -- 'F' */ if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10 ; } /* 'a' -- 'f' */ if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10 ; } return result ; }
目次

inserted by FC2 system