(57)【特許請求の範囲】
【請求項１】
多気筒エンジンの各気筒毎の１サイクルを、吸気行程後半、吸気行程前半、排気行程後半、排気行程前半、燃焼行程後半、燃焼行程前半、圧縮行程後半、圧縮行程前半に区分し、
噴射制御を行わない上記吸気行程後半を除く各区間を、噴射開始区間として定義し、
「上記噴射開始区間の数＋１」個のビットからなり、気筒数分の、各ビットが各噴射区間を表す噴射開始区間設定フラグを用い、
噴射開始セット時間に基づき上記各噴射開始区間の中から少なくとも１つの噴射開始区間を上記噴射開始区間設定フラグにより指定し、
複数の噴射開始区間を指定した場合、指定した最終の噴射開始区間より前の噴射開始区間での噴射すべき有効噴射幅を、１サイクル中の要求噴射幅を指定した噴射開始区間の数により分割した値で設定し、また最終の噴射開始区間での噴射すべき最終有効噴射幅を１サイクル中に必要とする要求噴射幅と上記最終より前の噴射開始区間で噴射した有効噴射幅の合計との差分に応じて設定し、
上記最終より前の噴射開始区間での燃料噴射を当該噴射開始区間の始まりから開始し、また最終の噴射開始区間での燃料噴射開始時期を、上記噴射開始セット時間から噴射開始区間の間隔時間の正数倍を減算してゼロ或いは負の値を示したときの２の補数に基づき上記最終の噴射開始区間の始まりから起算して設定することを特徴とする多気筒エンジンの燃料噴射制御方法。
【発明の詳細な説明】
【０００１】
【産業上の利用分野】
本発明は、噴射開始区間毎の有効噴射幅の噴射開始時期を適正に設定する多気筒エンジンの燃料噴射制御方法に関する。
【０００２】
【従来の技術】
近年、自動車などの車輛にマイクロコンピュータが導入され、エンジン、パワートレイン等を高精度に制御することが可能になった。これにより、車輛制御システムの開発においては、マイクロコンピュータのソフトウエア開発が大きな比重を占めるようになり、制御アルゴリズム上の処理の効率化が重要な課題となっている。特に、最近のエンジン制御系では制御内容が複雑化しており、ＣＰＵの効率的な活用はエンジン制御性の向上を図る上でも重要である。
【０００３】
従来、上記マイクロコンピュータによるエンジン制御システムにおける燃料の噴射開始時期は、例えば特開昭６１−１６０５４５号公報に開示されているように、一定クランク角毎に入力するクランクパルスをカウントしてエンジンの回転角位置を検出し、その検出値に基づいて設定するもの（いわゆる角度制御）、あるいは所定クランク角度間で計時した間隔時間に基づき噴射開始時期を設定するもの（いわゆる時間制御）などがある。
【０００４】
【発明が解決しようとする課題】
ところで、従来の多気筒エンジンにおけるシーケンシャル燃料噴射制御は各気筒１サイクル当り１回噴射が一般的で、各気筒１サイクル中に必要とする燃料噴射幅が設定されれば、例えば噴射エンド制御（噴射終了時期を一定にする制御）では、上記燃料噴射幅に基づき噴射エンドクランク角からどのくらい前のクランク角で燃料噴射を開始すれば良いかを一義的に求めることになる。
【０００５】
しかし、例えば低負荷運転時等では、燃料噴射幅が短いため噴射エンド制御により１回噴射を実行すると、燃料が充分に気化されないまま燃焼室に供給されることになり、燃焼効率が悪くエンジン回転の不安定化を招く。
【０００６】
本発明は上記事情に鑑みてなされたもので、各気筒１サイクル当りの噴射回数を１回あるいは複数回設定できるとともに、各噴射開始区間における有効噴射幅、噴射開始時期及び１サイクルにおける噴射エンド等を適正に設定することができて燃焼効率及び空燃比制御性の良い多気筒エンジンの燃料噴射制御定方法を提供することを目的としている。
【０００７】
【課題を解決するための手段】
上記目的を達成するため本発明による多気筒エンジンの燃料噴射制御方法は、多気筒エンジンの各気筒毎の１サイクルを、吸気行程後半、吸気行程前半、排気行程後半、排気行程前半、燃焼行程後半、燃焼行程前半、圧縮行程後半、圧縮行程前半に区分し、噴射制御を行わない上記吸気行程後半を除く各区間を、噴射開始区間として定義し、「上記噴射開始区間の数＋１」個のビットからなり、気筒数分の、各ビットが各噴射区間を表す噴射開始区間設定フラグを用い、噴射開始セット時間に基づき上記各噴射開始区間の中から少なくとも１つの噴射開始区間を上記噴射開始区間設定フラグにより指定し、複数の噴射開始区間を指定した場合、指定した最終の噴射開始区間より前の噴射開始区間での噴射すべき有効噴射幅を、１サイクル中の要求噴射幅を指定した噴射開始区間の数により分割した値で設定し、また最終の噴射開始区間での噴射すべき最終有効噴射幅を１サイクル中に必要とする要求噴射幅と上記最終より前の噴射開始区間で噴射した有効噴射幅の合計との差分に応じて設定し、上記最終より前の噴射開始区間での燃料噴射を当該噴射開始区間の始まりから開始し、また最終の噴射開始区間での燃料噴射開始時期を、上記噴射開始セット時間から噴射開始区間の間隔時間の正数倍を減算してゼロ或いは負の値を示したときの２の補数に基づき上記最終の噴射開始区間の始まりから起算して設定することを特徴とする。
【０００８】
【作用】
本発明は、多気筒エンジンの各気筒毎の１サイクルを、吸気行程後半、吸気行程前半、排気行程後半、排気行程前半、燃焼行程後半、燃焼行程前半、圧縮行程後半、圧縮行程前半の各噴射開始区間に区分する。そして、噴射制御を行わない吸気行程後半を除く各区間を、噴射開始区間として定義し、「上記噴射開始区間の数＋１」個のビットからなり、気筒数分の、各ビットが各噴射区間を表す噴射開始区間設定フラグを用い、噴射開始セット時間に基づき上記各噴射開始区間の中から少なくとも１つの噴射開始区間を上記噴射開始区間設定フラグにより指定する。
【０００９】
そして、複数の噴射開始区間を指定した場合は、指定した最終の噴射開始区間より前の噴射開始区間での噴射すべき有効噴射幅を、１サイクル中の要求噴射幅を指定した噴射開始区間の数により分割した値で設定する。また最終の噴射開始区間での噴射すべき最終有効噴射幅を１サイクル中に必要とする要求噴射幅と上記最終より前の噴射開始区間で噴射した有効噴射幅の合計との差分に応じて設定する。
【００１０】
そして、最終より前の噴射開始区間での燃料噴射を当該噴射開始区間の始まりから開始し、また最終の噴射開始区間における燃料噴射開始時期を、上記噴射開始セット時間から噴射開始区間の間隔時間の正数倍を減算してゼロ或いは負の値を示したときの２の補数に基づき上記最終の噴射開始区間の始まりから起算して設定する。
【００１１】
【実施例】
以下、図面に基づいて本発明の実施例を説明する。
【００１２】
図面は本発明の一実施例に係り、図１は０．５ｍｓ毎の定期割込み処理を示すフローチャート、図２はクラセン割込み処理を示すフローチャート、図３はジョブ優先処理を示すフローチャート、図４〜図７はジョブ実行サブルーチンを示すフローチャート、図８はクランク位置算出サブルーチンを示すフローチャート、図９はＣＣＡＳ・ＲＣＡＳ判別サブルーチンを示すフローチャート、図１０、図１１は燃料噴射開始時期の算出ルーチンを示すフローチャート、図１２は噴射タイマセットサブルーチンを示すフローチャート、図１３、図１４は噴射タイマセットマクロ１ルーチンを示すフローチャート、図１５、図１６は噴射タイマセットマクロ２ルーチンを示すフローチャート、図１７はジョブの実行状態を示す説明図、図１８はジョブフラグの説明図、図１９はジョブ実行中フラグとオーバーラップカウンタの変化を示す説明図、図２０はシステムシフトバッファの説明図、図２１はクラセン間隔テーブルの説明図、図２２は気筒・クランク位置状態マップの説明図、図２３はクランク位置、カム位置とクランク位置変数、噴射開始区間テーブル及び気筒別行程順のタイムチャート、図２４は噴射開始区間、及び噴射開始区間設定フラグの説明図、図２５は噴射タイマコントロールを示すタイムチャート、図２６はエンジン系の概略構成図、図２７はクランクロータとクランク角センサの正面図、図２８はカムロータとカム角センサの正面図、図２９は電子制御系の回路構成図である。
【００１３】
本実施例のエンジン制御システムでは、図２９に示すマイクロコンピュータを中核とした電子制御装置（ＥＣＵ）５０によって図２６に示すエンジン系が制御され、燃料噴射制御、点火時期制御などが行われる。このＥＣＵ５０のマイクロコンピュータには、新しい概念に基づくオペレーティングシステム（ＯＳ）が搭載されており、このＯＳの管理下で、各制御ストラテジーに基づく各ジョブが、それぞれの優先レベルに従って実行される。
【００１４】
まず、エンジン系の機器構成について説明する。
【００１５】
図２６において符号１はエンジン（本実施例においては水平対向４気筒エンジン）であり、右バンクＲ側に＃１，＃３気筒を、左バンクＬ側に＃２，＃４気筒を備える。そして、シリンダブロック１ａの左右両バンクに併設するシリンダヘッド２の吸気ポート２ａにインテークマニホルド３が連通され、このインテークマニホルド３の上流にエアチャンバ４を介してスロットル通路５が連通されている。このスロットル通路５の上流側には、吸気管６を介してエアクリーナ７が取付けられ、このエアクリーナ７が吸入空気の取入れ口であるエアインテークチャンバ８に連通されている。
【００１６】
また、上記排気ポート２ｂにエキゾーストマニホルド９を介して排気管１０が連通され、この排気管１０に触媒コンバータ１１が介装されてマフラ１２に連通されている。一方、上記スロットル通路５にスロットルバルブ５ａが設けられ、このスロットル通路５の直上流の上記吸気管６にインタークーラ１３が介装され、さらに、上記吸気管６の上記エアクリーナ７の下流側にレゾネータチャンバ１４が介装されている。
【００１７】
また、上記レゾネータチャンバ１４と上記インテークマニホルド３とを連通して上記スロットルバルブ５ａの上流側と下流側とをバイパスするバイパス通路１５に、アイドルスピードコントロールバルブ（ＩＳＣＶ）１６が介装されている。さらに、このＩＳＣＶ１６の直下流側に、吸気圧が負圧のとき開弁し、またターボチャージャ１８によって過給されて吸気圧が正圧になったとき閉弁するチェックバルブ１７が介装されている。
【００１８】
上記ターボチャージャ１８は、上記吸気管６の上記レゾネータチャンバ１４の下流側にコンプレッサが介装され、タービンが上記排気管１０に介装されている。さらに、上記ターボチャージャ１８のタービンハウジング流入口には、ウエストゲート弁１９が介装され、このウエストゲート弁１９には、ウエストゲート弁作動用アクチュエータ２０が連設されている。
【００１９】
上記ウエストゲート弁作動用アクチュエータ２０は、ダイヤフラムにより２室に仕切られ、一方がウエストゲート弁制御用デューティソレノイド弁２１に連通される圧力室を形成し、他方が上記ウエストゲート弁１９を閉方向に付勢するスプリングを収納したスプリング室を形成している。
【００２０】
上記ウエストゲート弁制御用デューティソレノイド弁２１は、上記レゾネータチャンバ１４と上記吸気管６の上記ターボチャージャ１８のコンプレッサ下流とを連通する通路に介装されており、ＥＣＵ５０から出力される制御信号のデューティ比に応じて、上記レゾネータチャンバ１４側の圧力と上記コンプレッサ下流側の圧力とを調圧し、上記ウエストゲート弁作動用アクチュエータ２０の圧力室に供給する。
【００２１】
すなわち、上記ＥＣＵ５０によって上記ウエストゲート弁制御用デューティソレノイド弁２１を制御し、上記ウエストゲート弁作動用アクチュエータ２０を作動させて上記ウエストゲート弁１９による排気ガスリリーフを調整することにより、上記ターボチャージャ１８による過給圧を制御するようになっている。
【００２２】
また、上記インテークマニホルド３に絶対圧センサ２２が通路２３を介して連通され、この通路２３に、上記絶対圧センサ２２と上記インテークマニホルド３或は大気とを選択的に連通する吸気管圧力／大気圧切換ソレノイド弁２４が介装されている。
【００２３】
さらに、上記インテークマニホルド３の各気筒の各吸気ポート２ａの直上流側にインジェクタ２５が臨まされ、また、上記シリンダヘッド２の各気筒毎に、その先端を燃焼室に露呈する点火プラグ２６ａが取付けられ、この点火プラグ２６ａに連設された点火コイル２６ｂにイグナイタ２７が接続されている。
【００２４】
上記インジェクタ２５には、燃料タンク２８内に設けたインタンク式の燃料ポンプ２９から燃料フィルタ３０を経て燃料が圧送され、プレッシャレギュレータ３１にて調圧される。
【００２５】
また、上記吸気管６の上記エアークリーナ７の直下流に吸入空気量センサ３２が介装され、上記スロットルバルブ５ａに、スロットル開度センサ３３ａとアイドルスイッチ３３ｂとを内蔵したスロットルセンサ３３が連設されている。
【００２６】
さらに、上記エンジン１のシリンダブロック１ａにノックセンサ３４が取付けられるとともに、このシリンダブロック１ａの左右両バンクを連通する冷却水通路３５に冷却水温センサ３６が臨まされ、上記排気管１０の上記エキゾーストマニホルド９の集合部にＯ２  センサ３７が臨まされている。
【００２７】
また、上記シリンダブロック１ａに支承されたクランクシャフト１ｂにクランクロータ３８が軸着され、このクランクロータ３８の外周に、電磁ピックアップなどからなるクランク角センサ３９が対設されている。さらに、上記エンジン１のカムシャフト１ｃに連設するカムロータ４０に、電磁ピックアップなどからなる気筒判別用のカム角センサ４１が対設されている。尚、上記クランク角センサ３９及び上記カム角センサ４１は、電磁ピックアップなどの磁気センサに限らず、光センサなどでも良い。
【００２８】
上記クランクロータ３８は、図２７に示すように、その外周に突起３８ａ，３８ｂ，３８ｃが形成され、これらの各突起３８ａ，３８ｂ，３８ｃが、各気筒（＃１，＃２と＃３，＃４）の圧縮上死点前（ＢＴＤＣ）θ１，θ２，θ３  の位置に形成されている。尚、本実施例においては、θ１  ＝９７°ＣＡ、θ２  ＝６５°ＣＡ、θ３  ＝１０°ＣＡである。
【００２９】
上記クランクロータ３８の各突起は、上記クランク角センサ３９によって検出され、図２３に示すようにＢＴＤＣ９７°，６５°，１０°ＣＡのクランク角信号（クラセン信号）がエンジン１／２回転毎（１８０°ＣＡ毎）に出力される。そして、各信号の入力間隔時間がタイマによって計時され、エンジン回転数が算出される。上記突起３８ｂは、点火時期設定の際の基準クランク角となり、また、突起３８ｃは、始動時噴射開始時期の基準クランク角となるとともに始動時の固定点火時期を示すクランク角となる。
【００３０】
また、図２８に示すように、上記カムロータ４０の外周には、気筒判別用の突起４０ａ，４０ｂ，４０ｃが形成され、突起４０ａが＃３，＃４気筒の圧縮上死点後（ＡＴＤＣ）θ４  の位置に形成され、突起４０ｂが３個の突起で構成されて最初の突起が＃１気筒のＡＴＤＣθ５  の位置に形成されている。さらに、突起４０ｃが２個の突起で形成され、最初の突起が＃２気筒のＡＴＣＤθ６  の位置に形成されている。尚、本実施例においては、θ４  ＝２０°ＣＡ、θ５  ＝５°ＣＡ、θ６  ＝２０°ＣＡである。
【００３１】
そして、上記カムロータ４０の各突起が上記カム角センサ４１によって検出され、各気筒の燃焼行程順を＃１→＃３→＃２→＃４とした場合、この燃焼行程順と、上記カム角センサ４１の検出信号をカウンタによって計数した値とのパターン（図２３のタイムチャート参照）に基づいて、気筒判別がなされる。
【００３２】
一方、図２９に示すように、ＥＣＵ５０は、燃料噴射制御、点火時期制御などを行なうメインコンピュータ５１と、ノック検出処理を行なう専用のサブコンピュータ５２との２つのコンピュータを中心として構成され、各部に所定の安定化電源を供給する定電圧回路５３や各種の周辺回路が組込まれている。
【００３３】
上記定電圧回路５３は、ＥＣＵリレー５４のリレー接点を介してバッテリ５５に接続され、このバッテリ５５に、上記ＥＣＵリレー５４のリレーコイルがイグニッションスイッチ５６を介して接続されている。また、上記バッテリ５５には、上記定電圧回路５３が直接接続され、さらに、燃料ポンプリレー５７のリレー接点を介して燃料ポンプ２９が接続されている。
【００３４】
すなわち、上記定電圧回路５３は、上記イグニッションスイッチ５６がＯＮされ、上記ＥＣＵリレー５４のリレー接点が閉となったとき、制御用電源を供給し、また、上記イグニッションスイッチ５６がＯＦＦされたとき、バックアップ用の電源を供給する。
【００３５】
上記メインコンピュータ５１は、ＣＰＵ５８（以下、メインＣＰＵ５８と称する）、ＲＯＭ５９、ＲＡＭ６０、上記イグニッションスイッチ５６がＯＦＦされたときにも上記定電圧回路５３からバックアップ電源が供給されてデータを保持するバックアップＲＡＭ６１、カウンタ・タイマ群６２、シリアル通信インターフェースであるＳＣＩ６３、及び、Ｉ／Ｏインターフェース６４がバスライン６５を介して接続されたマイクロコンピュータである。
【００３６】
尚、上記カウンタ・タイマ群６２は、フリーランニングカウンタ、カム角センサ（以下、適宜、カムセンと略記する）信号の入力計数用カムセンカウンタなどの各種カウンタ、噴射タイマ、点火タイマ、後述する０．５ｍｓ毎の定期割込みを発生させるための定期割込みタイマ、クランク角センサ（以下、適宜、クラセンと略記する）信号の入力間隔計時用クラセンタイマ、及び、システム異常監視用のウオッチドッグタイマなどの各種タイマを便宜上総称するものであり、上記メインコンピュータ５１においては、その他、各種のソフトウエアカウンタ・タイマが用いられる。
【００３７】
また、上記サブコンピュータ５２も、上記メインコンピュータ５１と同様、ＣＰＵ７１（以下、サブＣＰＵ７１と称する）、ＲＯＭ７２、ＲＡＭ７３、カウンタ・タイマ群７４、ＳＣＩ７５、及び、Ｉ／Ｏインターフェース７６がバスライン７７を介して接続されたマイクロコンピュータであり、上記メインコンピュータ５１とサブコンピュータ５２とは、上記ＳＣＩ６３，７５を介してシリアル通信ラインにより互いに接続されている。
【００３８】
上記メインコンピュータ５１のＩ／Ｏインターフェース６４には、入力ポートに、吸入空気量センサ３２、スロットル開度センサ３３ａ、水温センサ３６、Ｏ２  センサ３７、絶対圧センサ２２、車速センサ４２、及び、バッテリ５５が、８チャンネル入力のＡ／Ｄ変換器６６を介して接続されるとともに、アイドルスイッチ３３ｂ、クランク角センサ３９、カム角センサ４１が接続されており、さらに、始動状態を検出するためにスタータスイッチ４３が接続されている。
【００３９】
尚、本実施例においては、上記Ａ／Ｄ変換器６６は、７チャンネル分の入力が使用され、残りの１チャンネルは予備となっている。
【００４０】
また、上記Ｉ／Ｏインターフェース６４の出力ポートには、イグナイタ２７が接続され、さらに、駆動回路６７を介して、ＩＳＣＶ１６、インジェクタ２５、燃料ポンプリレー５７のリレーコイル、および、ウエストゲート弁制御用デューティソレノイド弁２１、吸気管圧力／大気圧切換ソレノイド弁２４が接続されている。
【００４１】
一方、上記サブコンピュータ５２のＩ／Ｏインターフェース７６は、入力ポートに、クランク角センサ３９、カム角センサ４１が接続されるとともに、Ａ／Ｄ変換器７８、周波数フィルタ７９、アンプ８０を介してノックセンサ３４が接続されており、上記ノックセンサ３４からのノック検出信号が上記アンプ８０で所定のレベルに増幅された後に上記周波数フィルタ７９により必要な周波数成分が抽出され、上記Ａ／Ｄ変換器７８にてデジタル信号に変換されて入力されるようになっている。
【００４２】
上記メインコンピュータ５１では、各センサ類からの検出信号を処理し、燃料噴射パルス幅、点火時期などを演算する。すなわち、吸入空気量センサ３２の出力信号から吸入空気量を算出し、ＲＡＭ６０及びバックアップＲＡＭ６１に記憶されている各種データに基づき、吸入空気量に見合った燃料噴射量を演算し、また、点火時期などを算出する。
【００４３】
そして、上記燃料噴射量に相応する駆動パルス幅信号を、駆動回路６７を介して所定のタイミングで該当気筒のインジェクタ２５に出力して燃料を噴射し、また、所定のタイミングでイグナイタ２７に点火信号を出力し、該当気筒の点火プラグ２６ａを点火する。
【００４４】
その結果、該当気筒に供給された混合気が爆発燃焼し、エキゾーストマニホルド９の集合部に臨まされたＯ２  センサ３７により排気ガス中の酸素濃度が検出され、この検出信号が波形整形された後、上記メインＣＰＵ５８で基準値（スライスレベル）と比較され、エンジンの空燃比状態が目標空燃比に対し、リッチ側にあるか、リーン側にあるかが判別され、空燃比が目標空燃比となるようフィードバック制御される。
【００４５】
一方、上記サブコンピュータ５２では、エンジン回転数とエンジン負荷とに基づいてノックセンサ３４からの信号のサンプル区間を設定し、このサンプル区間でノックセンサ３４からの信号を高速にＡ／Ｄ変換して振動波形を忠実にデジタルデータに変換し、ノック発生の有無を判定する。
【００４６】
上記サブコンピュータ５２のＩ／Ｏインターフェース７６の出力ポートは、上記メインコンピュータ５１のＩ／Ｏインターフェース６４の入力ポートに接続されており、上記サブコンピュータ５２でのノック判定結果がＩ／Ｏインターフェース７６に出力される。そして、上記メインコンピュータ５１では、上記サブコンピュータ５２からノック発生有りの判定結果が出力されると、ＳＣＩ６３を介してシリアル通信ラインよりノックデータを読込み、このノックデータに基づいて直ちに該当気筒の点火時期を遅らせ、ノックを回避する。
【００４７】
このようなエンジン制御において、上記メインコンピュータ５１では、各センサ類からの信号入力処理、エンジン回転数算出、吸入空気量算出、燃料噴射量算出、点火時期算出といった各項目毎の各種プログラムが、一つのＯＳの管理下で効率的に実行される。このＯＳは、車輌制御のための各種マネジメント機能、及び、このマネジメント機能に密着した内部ストラテジーを有し、各種ジョブを体系的に結合する。
【００４８】
上記ＯＳのマネジメント機能としては、
（１−１）ジョブの優先処理
（１ー２）セクション定義による各ジョブの分割ファイル対応
（１−３）スタックの使用状況モニタ機能
（１−４）異常割込み動作のモニタ機能
（１−５）ジョブ毎に固有の制約を作らない標準マップ・標準ワークメモリ設定
などの機能があり、制御ストラテジーの開発環境を向上させるとともに、限られたＣＰＵ能力を最大限に発揮させ、デジタル制御理論の基本である等時間間隔処理を可能な限り達成することができる。
【００４９】
等時間間隔処理としては、０．５ｍｓ毎の定期割込みを基本として、２，４，１０，５０，２５０ｍｓ毎の５種類の等間隔割込みジョブが用意されており、また、エンジン回転に同期した処理として、クランク角信号入力により即割込み実行される高優先クラセンジョブ（以下、単にクラセンジョブと称する）と、より優先順位が高い他のジョブがないときにクランク角信号入力により割込み実行される比較的緊急度の低い低優先クラセンジョブとが用意されている。
【００５０】
これらの各ジョブには、クラセンジョブ＞２ｍｓジョブ＞４ｍｓジョブ＞１０ｍｓジョブ＞低優先クラセンジョブ＞５０ｍｓジョブ＞２５０ｍｓジョブの順で、７〜１の優先レベルが高位側から低位側に向かって付けられており、図１７に示すように、高速ジョブに対し低速ジョブが分割して処理されるとともに、各ジョブの多重待ち処理が行なわれる。
【００５１】
また、上記ＯＳの下で働く各プログラムは、機能別の領域毎に順番に配列されており、各機能毎にセクション宣言によって名前が付けられている。上記ＯＳ下で働く数々のストラテジーファイル（ユーザ側ファイル）は、各機能毎にＯＳと同じ名前のセクション宣言を用いることにより、開発段階において、例えば、初期値設定処理、１０ｍｓ毎の処理、バックグランド処理等を別々のファイルに記述しても、各ファイルがリンクされたとき、同じ処理は連続した１つの領域に集められ、ＯＳと融合し一体となって動作する。
【００５２】
各ストラテジーファイル側で使用する主なセクション領域は、
○変数宣言領域
○自己ファイル名、ファイル制作時の自動記録領域
○セッティングデータ領域
○クラセンジョブ領域
○２ｍｓジョブ領域
○４ｍｓジョブ領域
○１０ｍｓジョブ領域
○低優先クラセンジョブ領域
○５０ｍｓジョブ領域
○２５０ｍｓジョブ領域
○リセット時初期化ジョブ領域
○エンスト時初期化ジョブ領域
○バックグランドジョブ領域
○プログラム本体の領域
であり、機能毎にファイルを分割してプログラム開発が可能になるとともに、プログラムの構造化記述を可能にする。
【００５３】
また、上記ＯＳには、以上のマネジメント機能に密着した内部ストラテジーとして、
（２−１）Ａ／Ｄ変換処理
（２−２）クランク位置に係る各種情報の算出
（２−３）デバッグ用シミュレーション機能（エンジン回転及びＡ／Ｄ変換）
（２−４）点火タイマのセット
（２−５）噴射タイマのセット
などの機能を備えており、さらに、これらの機能に係る各種サービスルーチンが各ジョブ中に用意されている。
【００５４】
従来、このような機能は各ジョブレベルで達成するようになっていたが、本システムにおいては、すべてＯＳ側に用意され、ＯＳ側で処理したＡ／Ｄ変換結果、クランク位置情報、エンジン回転数などに基づいて、ユーザ側の各ジョブで、燃料噴射量、点火時期などを設定すると、これらの指示値がＯＳによって噴射タイマ、点火タイマにセットされるようになっている。
【００５５】
次に、上記メインコンピュータ５１における燃料噴射制御の機能を、ジョブ処理の説明を基本として図１〜図１６に示すフローチャートに従って説明する。尚、サブコンピュータ５２はノック検出処理専用のコンピュータであるため、その動作説明を省略する。
【００５６】
まず、イグニッションスイッチ５６がＯＮされてシステムに電源が投入されると、リセットに伴うリセット割込みが起動し、各種イニシャライズが行なわれるとともに、０．５ｍｓ毎に定期割込みを起動するための定期割込みタイマが起動され、クランク角センサ３９からの信号入力毎（ＢＴＤＣ９７°，６５°，１０°ＣＡ毎のエンジン１回転に６回）に起動されるクラセン割込みが許可され、その後、バックグランドジョブの実行状態となる。
【００５７】
そして、このバックグランドジョブの上で、０．５ｍｓ毎の定期割込みと、エンジン１回転に６回のクラセン割込みとにより、７レベルのジョブが優先処理される。この２つの割込みにおいては、各自の処理を実行後、共通のアドレスにジャンプし、ジョブ優先処理を実行する。
【００５８】
尚、上記リセット割込みは、内部演算において０による除算を実行した場合や、無限ループが発生した場合など、正常時には発生しない要因によっても、起動される。
【００５９】
まず、図１に示す０．５ｍｓ毎の定期割込みについて説明する。この定期割込みでは、ステップＳ１００で、ＯＳ用ワークエリアを設定し、ステップＳ１０１で、ウオッチドッグタイマを初期化すると、ステップＳ１０２へ進んで、Ｐ−ＲＵＮフラグを２０回に１回すなわち１０ｍｓ毎に反転する。このＰ−ＲＵＮフラグは、図示しない保護回路によってシステムが自動的にリセットされないようにするためのフラグであり、システムが正常に動作して一定時間毎（１０ｍｓ毎）に反転される限り、上記保護回路の作動が阻止される。
【００６０】
次いで、ステップＳ１０３へ進み、スイッチ出力の転写を行なう。このスイッチ出力は、各ジョブ中でメモリに書き込んだビットのＯＮ，ＯＦＦ値であり、各ジョブからは直接Ｉ／Ｏインターフェース６４の出力ポートに出力せず、ＯＳ側で０．５ｍｓ毎にメモリの値を出力ポートに転写する。
【００６１】
次に、ステップＳ１０４へ進むと、Ａ／Ｄ変換サブルーチンを実行してＡ／Ｄ変換に係る各種設定を行ない、ステップＳ１０５で、ジョブフラグ作成サブルーチンを実行して、２，４，１０，５０，２５０ｍｓ毎の各ジョブ割込み要求を示すジョブフラグＪＢ＿ＦＬＧを作成した後、ステップＳ１０６で、Ａ／Ｄ変換をスタートする。
【００６２】
上記Ａ／Ｄ変換は、基本的に、Ａ／Ｄ変換器６６の８チャンネル入力が０．５ｍｓ毎に所定の変換順番毎に処理され、４ｍｓ周期で全入力の変換が行なわれる。但し、特定の１つのチャンネルは、回転脈動が発生する吸入管圧力などをＡ／Ｄ変換するためクランク角９０°毎に（０．５ｍｓの時間精度で）同期し、変換順番に対して割込んだ形で処理が行なわれ、その後の入力の順番を１つ遅れにする。
【００６３】
尚、エンジン回転数３７５０ｒｐｍ以上では、Ａ／Ｄ変換の最後の順番の入力が完全に停止し、７５００ｒｐｍ以上では、最後から２番目の入力も停止するが、Ａ／Ｄ変換の順番は、スロットル開度、吸入空気量など変化の速いものを先として、冷却水温、電圧など比較的変化の遅いものが後になるように設定してあり、且つ、最後のＡ／Ｄ変換順番をクランク同期入力に設定してあるため、特に支障は生じない。
【００６４】
また、図１８に示すように、上記ジョブフラグＪＢ＿ＦＬＧは、１バイト変数の各ビットを各ジョブに対応するフラグとして割当てたものであり、複数のジョブ要求が同時に可能なようになっている。この１バイト変数のビット１〜ビット７は優先レベル１〜７に対応し、それぞれ、２５０ｍｓジョブ、５０ｍｓジョブ、低優先クラセンジョブ、１０ｍｓジョブ、４ｍｓジョブ、２ｍｓジョブ、クラセンジョブのフラグに割当てられている。そして、所定のビットが立てられたとき、対応する優先レベルのジョブ割込み要求がなされる。尚、ビット０はバックグランドジョブのフラグに割当てられて通常は参照されない。
【００６５】
そして、上記ステップＳ１０５でジョブフラグ作成サブルーチンによりジョブフラグＪＢ＿ＦＬＧを作成し、上記ステップＳ１０６でＡ／Ｄ変換をスタートした後は、ステップＳ１０７へ進み、ジョブフラグＪＢ＿ＦＬＧのいずれかのジョブに対応するビットが立っているか否かを調べる。
【００６６】
その結果、ジョブフラグＪＢ＿ＦＬＧのビットが一つも立っていないときには、どのジョブからも要求がないため割込みを終了し、ジョブフラグＪＢ＿ＦＬＧのいずれかのビットが立っているときには、ステップＳ１０８へ進んで、現状レベル（この定期割込みが実行される時点で所定の優先レベルのジョブが実行されていた状態）以下のフラグがないか否かを調べる。
【００６７】
上記ステップＳ１０８で、現状レベル以下のフラグがないときには、ラベルＷＡＲ＿ＪＢで示される図３のジョブ優先処理にジャンプし、現状レベル以下のフラグがあるときには、ステップＳ１０９で、現状レベル以下のレベルのオーバーラップカウンタＯＬＣを１増加させる。
【００６８】
上記オーバーラップカウンタＯＬＣは、ジョブ要求を記憶するためのカウンタであり、各優先レベル毎に１バイト割当てられ、上記ジョブフラグＪＢ＿ＦＬＧによるジョブ要求時にインクリメント、ジョブ終了時にデクリメントされる。すなわち、カウンタによってジョブ要求を記憶することによりジョブの多重要求に対応することができるのである。
【００６９】
次いで、上記ステップＳ１０９からステップＳ１１０へ進み、現状レベルより高いフラグがないか否かを調べ、現状レベルより高いフラグがないときには、ルーチンを抜けて割込みを終了し、現状レベルより高いフラグがあるときには、ラベルＷＡＲ＿ＪＢのジョブ優先処理へジャンプする。
【００７０】
一方、この０．５ｍｓ毎の定期割込みに対し、図２のクラセンによる割込みでは、ステップＳ２００で、ＯＳ用ワークエリアを設定すると、ステップＳ２０１で、後述するクランク位置算出のサブルーチンを実行し、現在のクランク位置を判別するためのクランク位置変数、及び、最新の３つのクラセン間隔の和であるエンジン半回転の経過時間すなわち半回転時間を算出する。
【００７１】
上記クランク位置変数は、ＯＳ中で用意されるシステム変数であり、図２３に示すように、＃１〜＃４気筒に対するクランク位置を、クランク角センサ３９からの信号入力によるＢＴＤＣ９７°，６５°，１０°ＣＡによって１２の状態に区分し、現在のクランク位置を表わす。
【００７２】
すなわち、各気筒毎に、０，１，２の数値でクラセン入力順を示すクランク位置情報変数Ｓ＿ＣＣＡＳ、＃１気筒を０、＃３気筒を１、＃２気筒を２、＃４気筒を３として気筒の燃焼順を示す気筒情報変数Ｓ＿ＲＣＡＳ、及び、０〜１１の数値でクラセン順序及び気筒順序を総合的に表わす総合位置変数Ｓ＿ＡＣＡＳの３変数によって現在のクランク位置を表わし、さらに、クランク位置が確証をもって正常に判別されたときを０、判別結果がつじつまが合わず不安の残る推定状態を１、不明な状態を２とするエラーレベルＳ＿ＥＣＡＳにより、クランク位置の判別状況を表わすようになっている。尚、図２３においては、システム変数であることを示すＳ＿を省略している。
【００７３】
次いで、上記ステップＳ２０１からステップＳ２０２へ進むと、クランク位置算出のサブルーチンにおいてクランク位置判定が正常に終了したか或は判定不能であったかを、アキュムレータＡにストアされているコードを読み出すことにより調べる（エラーコード１、正常終了コード０）。
【００７４】
そして、上記ステップＳ２０２で、アキュムレータＡの値が１であり、クランク位置が判定不能であったときには、割込みを終了し、アキュムレータＡの値が０であり、クランク位置が正常に判定されているときには、ステップＳ２０３へ進み、エンストフラグを解除する。
【００７５】
尚、上記エンストフラグは、エンジンがエンスト状態であることを示すフラグであり、クラセン間隔が０．５ｓｅｃ以上の時間（約３０ｒｐｍ以下）のとき、５０ｍｓジョブに用意されているエンスト処理ルーチンによりセットされ、このクラセン割込みによりクリアされてエンスト状態が解除される。
【００７６】
次に、ステップＳ２０４へ進むと、点火タイマセットのサブルーチンを実行し、ユーザジョブ側で設定した点火時期の指示値に基づいて作成された点火スケジュールに従って点火タイマをセットする。この点火スケジュールは、ドエル開始時期、ドエルオン待ち時間、ドエルオフ待ち時間などをメンバーとする構造体変数であり、１０ｍｓジョブ中に作成ルーチンが用意され、この点火スケジュールに従って点火シーケンスが決定される。
【００７７】
次いで、ステップＳ２０５で、後述する噴射タイマセットサブルーチンを実行し、ユーザジョブ側で設定した気筒毎の要求燃料噴射幅に対応する噴射時間を、１回噴射或は複数回噴射に応じた１回当りの有効噴射幅として算出し、噴射タイマにセットしてステップＳ２０６へ進む。
【００７８】
ステップＳ２０６では、このクラセンが実行された現状のジョブレベルが自身のジョブレベルであるか否かを判別し、現状がクラセンジョブ自身のレベルであるときには、ステップＳ２０７、ステップＳ２０８で、クラセンジョブ、低優先クラセンジョブのオーバーラップカウンタＯＬＣを、それぞれ１増加させて割込みを終了し、現状のジョブレベルがクラセンジョブのレベルでないときには、ステップＳ２０９で、現状のジョブレベルが低優先クラセンジョブのレベル以上であるか否かを調べる。
【００７９】
そして、現状のジョブレベルが低優先クラセンジョブ以上であるときには、上記ステップＳ２０９からステップＳ２１０へ進んで、低優先クラセンジョブのオーバーラップカウンタＯＬＣを１増加させると、ステップＳ２１１で、クラセンジョブのジョブフラグをセットし、ラベルＷＡＲ＿ＪＢのジョブ優先処理へジャンプする。
【００８０】
一方、上記ステップＳ２０９で、現状のジョブレベルが低優先クラセンジョブ以上でないときには、上記ステップＳ２０９からステップＳ２１２へ進み、クラセンジョブのジョブフラグをセットすると、ステップＳ２１３で、低優先クラセンジョブのジョブフラグをセットし、ラベルＷＡＲ＿ＪＢのジョブ優先処理へジャンプする。
【００８１】
図３に示すジョブ優先処理では、ステップＳ３００で、ジョブの優先レベルを示す１バイト変数であるジョブレベルＪＢ＿ＬＥＶを１つ上げると、ステップＳ３０１へ進んで、この優先レベルに対応するジョブフラグが立っていないか調べる。そして、ジョブフラグが立っていないときには、ステップＳ３００へ戻ってさらにジョブレベルＪＢ＿ＬＥＶを１つ上げ、ジョブフラグが立っているときには、ステップＳ３０２へ進み、ジョブフラグの立っているジョブのオーバーラップカウンタＯＬＣを初期値の０から１にし、ステップＳ３０３へ進む。
【００８２】
ステップＳ３０３では、より上のジョブフラグがあるか否かを調べ、より上のジョブがあるときには、ステップＳ３００へ戻って前述の処理を繰り返し、より上のジョブがないときには、ステップＳ３０４へ進んで、ジョブ実行中フラグＪＢ＿ＲＵＮをセットすると、ステップＳ３０５で、後述するジョブ実行サブルーチンにより最上位のジョブを実行する。
【００８３】
上記ジョブ実行中フラグＪＢ＿ＲＵＮは、ジョブの実行開始時にセットされ、終了時にクリアされるフラグであり、このフラグにより、処理の途中で、より優先度の高いジョブによって割込まれたジョブを識別することができる。
【００８４】
例えば、図１９に示すように、ＪＢ＿ＬＥＶ＝４の１０ｍｓジョブを実行中、ＪＢ＿ＬＥＶ＝６の２ｍｓジョブの割込み要求がなされると、１０ｍｓジョブの処理が中断され、より優先度の高い２ｍｓジョブが、ＪＢ＿ＲＵＮ＝１、ＯＬＣ＝１にセットされ、実行される。そして、この２ｍｓジョブの処理中に、ＪＢ＿ＬＥＶ＝５の４ｍｓジョブの割込み要求が発生すると、この４ｍｓジョブは、ＪＢ＿ＲＵＮ＝０、ＯＬＣ＝１とされて割込みが受付けられるが、実行はされず待機状態となる。
【００８５】
その後、ジョブ実行サブルーチンによるジョブの実行が終了すると、上記ステップＳ３０５からステップＳ３０６へ進んでオーバーラップカウンタＯＬＣを１減らし、ステップＳ３０７で、オーバーラップカウンタＯＬＣがゼロになったか否かを調べる。その結果、オーバラップカウンタＯＬＣがゼロになっておらず、同じ優先レベルでジョブ割込み要求が複数回あるときには、ステップＳ３０５へ戻ってジョブを繰返し実行し、オーバラップカウンタＯＬＣがゼロになったとき、ステップＳ３０７からステップＳ３０８へ進んで、ジョブ実行中フラグＪＢ＿ＲＵＮをクリアする。
【００８６】
次に、ステップＳ３０９へ進み、ジョブレベルＪＢ＿ＬＥＶを１つ下げて次のジョブレベルに移ると、ステップＳ３１０で、このジョブレベルＪＢ＿ＬＥＶがゼロになったか否かを調べる。そして、ジョブレベルＪＢ＿ＬＥＶがゼロのときには、この割込みを終了し、ジョブレベルＪＢ＿ＬＥＶがゼロでないときには、ステップＳ３１１へ進んで、オーバーラップカウンタＯＬＣがゼロか否かを調べる。
【００８７】
上記ステップＳ３１１で、オーバーラップカウンタＯＬＣがゼロのときには、このレベルではジョブ要求はないため、上記ステップＳ３１１からステップＳ３０９へ戻って、ジョブレベルＪＢ＿ＬＥＶをさらに１つ下げて同様の処理を繰返し、オーバーラップカウンタＯＬＣがゼロでないときには、ステップＳ３１２へ進んで、このジョブレベルにおいて、ジョブ実行中フラグＪＢ＿ＲＵＮがセットされているか否かを調べる。
【００８８】
上記ステップＳ３１２で、ジョブ実行中フラグＪＢ＿ＲＵＮがセットされているときには、割込み前にジョブを実行中であったため、割込みを終了して割込み前のジョブへ戻り、ジョブ実行中フラグＪＢ＿ＲＵＮがセットされていなければ、ステップＳ３０４へ戻って、このレベルのジョブを実行し、同様の処理を繰返す。
【００８９】
すなわち、図１９において、ＪＢ＿ＬＥＶ＝６の２ｍｓジョブが終了し、ＯＬＣ＝０、ＪＢ＿ＲＵＮ＝０になると、ジョブレベルが１つ下げられ、ＪＢ＿ＬＥＶ＝５の４ｍｓジョブが、ＪＢ＿ＲＵＮ＝０、ＯＬＣ＝１の待機状態からＪＢ＿ＲＵＮ＝１にセットされ、実行される。さらに、４ｍｓジョブが終了すると、ＪＢ＿ＬＥＶ＝４に移り、ＪＢ＿ＲＵＮ＝１（ジョブ実行中）の状態から、２ｍｓジョブ及び４ｍｓジョブによって中断されていた１０ｍｓジョブの処理が再開される。
【００９０】
このように、０．５ｍｓ毎の定期割込み、クラセン割込みを基本タイミングとして、各ジョブの優先レベル及び実行タイミングを知らせるジョブフラグＪＢ＿ＦＬＧを作成するため、可能な限り正確に、等時間間隔処理、エンジン回転同期処理を実現し、各ジョブを効率良く処理することができる。さらに、基本タイミングとなる各割込み毎に更新されるジョブフラグＪＢ＿ＦＬＧによらず、オーバーラップカウンタＯＬＣによってジョブの多重要求を記憶するため、あるジョブの処理時間が長引き、再度、同じジョブを実行すべきタイミングとなった場合においても、処理を途中で放棄することなく、可能な限り最後まで処理を継続することができる。
【００９１】
次に、図４〜図７のジョブ実行サブルーチンについて説明する。
【００９２】
まず、ステップＳ５００で、ジョブフラグＪＢ＿ＦＬＧを参照して実行すべきジョブがクラセンジョブでないか否かを調べ、クラセンジョブでないときには、ラベルＡＬＪ１０へ分岐し、クラセンジョブのときには、ステップＳ５０１へ進んで、気筒判別がついているか否かを調べる。
【００９３】
そして、気筒判別がついていないときには、そのままルーチンを抜けてジョブを実行せず、気筒判別がついているとき、上記ステップＳ５０１からステップＳ５０２へ進んで、オーバーラップカウンタＯＬＣの値を参照して多重待ち状態であるか否かを調べる。
【００９４】
上記ステップＳ５０２では、多重待ち状態でないとき、ステップＳ５０３へ進んで、クラセン割込み毎に算出されるシステム変数Ｓ＿ＡＣＡＳ（クランク総合位置変数）をユーザ変数ＡＣＡＳとし、一方、多重待ち状態のときには、ステップＳ５０４へ分岐し、ユーザ変数ＡＣＡＳを一つ増やして１２で割った剰余をとって新たなユーザ変数ＡＣＡＳとし、このユーザ変数ＡＣＡＳを０，１，２，…１１，０，１，…とソフトウエア的に更新してゆく。
【００９５】
すなわち、クラセンジョブ及び低優先クラセンジョブは、自身または優先度の高いジョブに邪魔されて遅れることがあるが、クラセン割込みは正確にクランク角センサ信号に同期して実行され、システム変数Ｓ＿ＡＣＡＳはジョブの遅れに関係なく更新される。
【００９６】
従って、ジョブ中でシステム変数Ｓ＿ＡＣＡＳを参照して気筒及びクランク位置に係る情報を知り、この情報に応じた仕事を行なおうとしても、自身が他のジョブに邪魔されて遅れた場合には、自身の仕事に対応した気筒及びクランク位置に係る情報を知ることができなくなる。このため、クラセンジョブ及び低優先クラセンジョブ中では、多重待ち状態でないときにＯＳ用のシステム変数Ｓ＿ＡＣＡＳをユーザ用変数ＡＣＡＳとして取込み、このユーザ変数ＡＣＡＳをジョブ実行毎に更新して多重要求の場合にも、自身に対応した気筒及びクランク位置に係る情報を得て適正な処理がなされるようにするのである。
【００９７】
その後、上記ステップＳ５０３或は上記ステップＳ５０４からステップＳ５０５へ進み、ジョブのワークエリアを設定すると、ステップＳ５０６で、レベルゼロの割込みを許可し、ステップＳ５０７で、クラセンジョブのセクションに移る。そして、このクラセンジョブセクションにリンクされた処理を実行し、ステップＳ５０８で、割込みを禁止してルーチンを抜ける。
【００９８】
次に、ステップＳ５００で、これから実行すべきジョブがクラセンジョブでないときには、ラベルＡＬＪ１０のステップＳ５１０で、２ｍｓジョブでないか否か調べ、２ｍｓジョブのとき、ステップＳ５１１で、ジョブのワークエリアを設定すると、ステップＳ５１２で、レベルゼロの割込みを許可し、ステップＳ５１３で、２ｍｓジョブのセクションに移る。そして、このセクションにリンクされているジョブ本体（ユーザ側の制御ストラテジーに基づくルーチン、或は、ＯＳ側で用意したサービスルーチン）を実行し、ステップＳ５１４で、割込みを禁止してルーチンを抜ける。
【００９９】
一方、上記ステップＳ５１０で、実行すべきジョブが２ｍｓジョブでないときには、ステップＳ５１０からステップＳ５２０へ分岐し、実行すべきジョブが４ｍｓジョブか否かを調べる。そして、４ｍｓジョブでないときには、ラベルＡＬＪ３０へ分岐し、４ｍｓジョブのときには、ステップＳ５２１で、ジョブのワークエリアを設定すると、ステップＳ５２２へ進む。尚、この４ｍｓジョブは、Ａ／Ｄ変換利用ジョブであり、後述するシステムシフトバッファＳＳＨＢを介してＡ／Ｄ変換データを利用する。
【０１００】
ステップＳ５２２では、レベルゼロの割込みを許可し、次いで、ステップＳ５２３へ進むと、スイッチ入力を読込み、ステップＳ５２４で、４ｍｓジョブのセクションに移って、リンクされているジョブ本体を実行する。その後、４ｍｓジョブのセクションから抜けると、ステップＳ５２５で、割込みを禁止し、ステップＳ５２６へ進んで、システムシフトバッファＳＳＨＢをシフトしてルーチンを抜ける。
【０１０１】
上記システムシフトバッファＳＳＨＢは、図２０に示すように、８チャンネルの各Ａ／Ｄ変換結果がストアされる先頭オフセットアドレス０，＋８，＋１６，＋２４，＋３２，＋３４，＋３６，＋３８番の各メモリ、及び、４ｍｓ毎のクランク同期のＡ／Ｄ変換結果がストアされる先頭オフセットアドレス−２番地の１ワードのメモリからなり、０．５ｍｓ毎に実行される１回のＡ／Ｄ変換結果が１ワード（２バイト）でストアされる。
【０１０２】
先頭オフセットアドレス０番地からは、４段のシフトメモリとなっており、９０°ＣＡ毎のＡ／Ｄ変換結果がストアされ、最新４データ（１回転分）をジョブから参照することができる。また、先頭オフセットアドレス＋３２，＋３４，＋３６，＋３８番地は、各１ワードのメモリであり、なまし処理機能が選択されたとき、Ａ／Ｄ変換結果を加重平均した値がストアされてノイズ除去と精度向上を図ることができるようになっており、これらのメモリのデータは、低速ジョブで利用できる。
【０１０３】
また、各先頭オフセットアドレス＋８，＋１６，＋２４番地からは、各４ワードのメモリであり、４ｍｓジョブで利用するようになっている。これらの各メモリは、最新のＡ／Ｄ変換結果が先頭から数えて、４ｍｓジョブのオーバーラップカウンタＯＬＣの値だけ後のワードにストアされ、４ｍｓジョブ実行に際し、先頭方向からデータが読出され、ジョブの終了に伴って、後の各ワードのデータが順に先頭方向にシフトされるので、先にストアしたデータから読出されるＦＩＦＯバッファとなっている。
【０１０４】
すなわち、Ａ／Ｄ変換は、０．５ｍｓ毎の定期割込みにより４ｍｓ周期で正確に行なわれるが、４ｍｓジョブは優先度の高いジョブに邪魔されて遅れることがある。従って、Ａ／Ｄ変換の受渡しにＦＩＦＯバッファを用い、４ｍｓジョブで＋８〜，＋１６〜，＋２４〜番地の各ＦＩＦＯバッファのデータを参照後、上記ステップＳ５２６で、各ＦＩＦＯバッファのデータを順にシフトするのである。
【０１０５】
一方、上記ステップＳ５２０で、実行すべきジョブが４ｍｓジョブでなく、ラベルＡＬＪ３０へ分岐したときには、ステップＳ５３０で、実行すべきジョブが１０ｍｓジョブか否かを調べ、１０ｍｓジョブのとき、ステップＳ５３１で、ジョブのワークエリアを設定し、ステップＳ５３２で、レベルゼロの割込みを許可すると、ステップＳ５３３で、１０ｍｓジョブのセクションに移って、ジョブ本体を実行し、ステップＳ５３４で割込みを禁止してルーチンを抜ける。
【０１０６】
尚、上記１０ｍｓジョブのセクションには、半回転時間からエンジン回転数を算出するサービスルーチン、前述した点火スケジュールを作成するサービスルーチンなどがＯＳ側で用意されている。
【０１０７】
また、上記ステップＳ５３０で、実行すべきジョブが１０ｍｓジョブでないときにはステップＳ５４０へ分岐し、実行すべきジョブが低優先クラセンジョブであるか否かを調べる。そして、低優先クラセンジョブでないときには、上記ステップＳ５４０からラベルＡＬＪ５０へ分岐し、実行すべきジョブが低優先クラセンジョブのときは、上記ステップＳ５４０からステップＳ５４１へ進んで、現在の状態が多重待ち状態であるか否かを調べる。
【０１０８】
そして、現在の状態が多重待ち状態でないときには、上記ステップＳ５４１からステップＳ５４２へ進んで、システム変数Ｓ＿ＡＣＡＳ（クランク総合位置変数）をユーザ変数ＡＣＡＳとしてステップＳ５４４へ進み、多重待ち状態のときには、上記ステップＳ５４１からステップＳ５４３へ分岐し、ユーザ変数ＡＣＡＳを一つ増やして１２で割った剰余をとった後、ステップＳ５４４へ進む。
【０１０９】
ステップＳ５４４では、ジョブのワークエリアを設定し、ステップＳ５４５で、レベルゼロの割込みを許可すると、ステップＳ５４６で、低優先クラセンジョブのセクションに移り、ジョブ本体を実行した後、ステップＳ５４７で割込みを禁止し、ルーチンを抜ける。
【０１１０】
さらに、ラベルＡＬＪ５０では、ステップＳ５５０で、実行すべきジョブが５０ｍｓジョブであるか否かを調べ、５０ｍｓジョブのときには、ステップＳ５５１へ進んでジョブのワークエリアを設定し、ステップＳ５５２へ進む。
【０１１１】
ステップＳ５５２では、レベルゼロの割込みを許可すると、ステップＳ５５３で、５０ｍｓジョブのセクションに移り、ＯＳ側で用意したエンスト処理ルーチン、気筒別の点火時期リタードルーチン、燃料噴射開始時期算出ルーチンなどを実行し、また、ユーザ側の制御ストラテジーに基づくルーチンを実行する。そして、ジョブの終了後、ステップＳ５５４で割込みを禁止し、ルーチンを抜ける。
【０１１２】
一方、上記ステップＳ５５０で実行すべきジョブが５０ｍｓジョブではないときにはステップＳ５６０へ分岐し、ジョブのワークエリアを設定し、ステップＳ５６１でレベルゼロの割込みを許可し、ステップＳ５６２へ進んで、２５０ｍｓジョブのセクション領域へ移行し、ジョブ本体を実行後、ステップＳ５６３で割込みを禁止してルーチンを抜ける。
【０１１３】
以上のジョブ優先処理においては、クランク位置を常に的確に把握しておく必要があり、クラセン割込み毎に、図８に示すクランク位置算出サブルーチンが実行されて前述したクランク位置変数Ｓ＿ＣＣＡＳ，Ｓ＿ＲＣＡＳ，Ｓ＿ＡＣＡＳ，Ｓ＿ＥＣＡＳが算出される。尚、以下の説明においては、システム変数であることを示すＳ＿をクランク位置変数から省略する。
【０１１４】
このクランク位置算出サブルーチンでは、まず、ステップＳ６００で、クラセンタイマの下２バイトをソフトタイマの下２バイトにストアする。このクラセンタイマはＥＣＵ５０に備えられたハードウエアタイマであり、本実施例においては、１６ビットタイマで最大２５５ｍｓまで計数が可能であるが、メモリ上に３バイトの連続した領域を確保して下２バイトにクラセンタイマの２バイトを転写し、クラセンタイマのオーバーフローにより発生する割込みで３バイト目をカウントアップすることによりソフトタイマとして使用する。これにより、クランク角センサ３９からの信号入力間隔時間（以下、「クラセン間隔」と略記する）を最大６４ｓｅｃ（２５５ｍｓ×２５６）まで計数することが可能となり、１６ビット以上の特別なハードウエアタイマを使用することなく、クランキング時などクラセン間隔が極めて長い場合にも容易に対応することができる。
【０１１５】
次いで、ステップＳ６０１へ進むと、クラセン間隔が設定時間以下か否かを調べる。この設定時間は、最大エンジン回転数に対応するクラセン間隔としての時間、例えば０．３ｍｓであり、上記ステップＳ６０１でクラセン間隔が設定時間以下のときには、ノイズの混入などによるクラセンタイマの計数エラーとしてステップＳ６０２でアキュムレータＡにエラーコード１を格納してルーチンを抜け、また、上記ステップＳ６０１で、クラセン間隔が設定時間より長いときには、クラセンタイマの計数が正常であるとしてステップＳ６０３へ進む。
【０１１６】
ステップＳ６０３では、後述するＣＣＡＳ・ＲＣＡＳ判別サブルーチンを実行してクランク位置を判別し、ステップＳ６０４で、エラーレベルＥＣＡＳが２であるか否か、すなわち、クランキング時などのように気筒判別がなされていない状態であるか否かを調べ、ＥＣＡＳ＝２のときには、ステップＳ６０５へ分岐してアキュムレータＡにエラーコード１を格納し、ルーチンを抜ける。
【０１１７】
一方、上記ステップＳ６０４で、ＥＣＡＳ≠２のときには、ステップＳ６０６へ進み、ソフトタイマの３バイト目を０とする。そしてステップＳ６０７へ進み、クランク位置情報変数ＣＣＡＳが１であるか否か、すなわち、現在のクランク位置がＢＴＤＣ６５°ＣＡ〜１０°ＣＡの間（図２３参照）であるか否かを調べ、ＣＣＡＳ＝１のときには、ステップＳ６０７からステップＳ６０９へジャンプし、ＣＣＡＳ≠１のときには、ステップＳ６０７からステップＳ６０８へ進んで、Ａ／Ｄ変換リクエストを１増加させ、ステップＳ６０９へ進む。
【０１１８】
このＡ／Ｄ変換リクエストは、クランク角９０°ＣＡ毎にクランク同期Ａ／Ｄ変換を指示するためのフラグ的な変数であり、０、１の値をとり、値が１のときクランク同期Ａ／Ｄ変換を指示する。すなわち、前述したように、８チャンネルのＡ／Ｄ変換のうち１チャンネルのＡ／Ｄ変換はクランク角９０°ＣＡ毎に行なわれるが、ＣＣＡＳが０になったとき（ＢＴＤＣ９７°ＣＡ）と、ＣＣＡＳが２になったとき（ＢＴＤＣ１０°ＣＡ）、クランク同期のＡ／Ｄ変換リクエストをセットし、０．５ｍｓ毎のＡ／Ｄ変換順番に対してクランク角９０°毎（正確には８７゜，９３゜毎）のＡ／Ｄ変換を割込ませるのである。
【０１１９】
その後、ステップＳ６０９では、気筒情報変数ＲＣＡＳを３倍してクランク位置情報変数ＣＣＡＳを加算することにより総合位置変数ＡＣＡＳを算出すると（ＡＣＡＳ＝ＲＣＡＳ×３＋ＣＣＡＳ）、ステップＳ６１０で、ソフトタイマを２バイトでリミットし、クラセンタイマがオーバーフローしている場合には下２バイトをＦＦＦＦ（２５５ｍｓ）としてステップＳ６１１へ進む。
【０１２０】
ステップＳ６１１では、総合位置変数ＡＣＡＳ＝０，１，２，…１１を添字とする配列ＴＣＡＳ［ＡＣＡＳ］（配列の要素）にクラセン間隔データをストアし、ステップＳ６１２で、クランク位置情報変数ＣＣＡＳ＝０，１，２を添字とする配列ＭＴＣＳＸ［ＣＣＡＳ］（配列の要素）にクラセン間隔データをストアする。
【０１２１】
配列ＴＣＡＳは、図２１（ａ）に示すように、ＡＣＡＳ＝０，１，２，…１１に対応するエンジン２回転分のクラセン間隔データがストアされた１２ワードのクラセン間隔テーブルであり、配列ＭＴＣＳＸは、同図（ｂ）に示すように、ＣＣＡＳ＝０，１，２に対応する３ヶのクラセン間隔データがストアされた３ワードのクラセン間隔テーブルである。
【０１２２】
すなわち、上記ステップＳ６０３のＣＣＡＳ・ＲＣＡＳ判別サブルーチン（詳細は後述する）、及びステップＳ６０９により各情報変数ＣＣＡＳ，ＲＣＡＳ，ＡＣＡＳが更新され、例えば、ＣＣＡＳ＝１、ＲＣＡＳ＝１、ＡＣＡＳ＝４に更新されて、現在、クランク位置が＃３気筒のＢＴＤＣ６５゜〜１０゜ＣＡのとき、クラセンタイマによって計時された＃３気筒のＢＴＤＣ９７゜ＣＡにおけるクラセン信号入力から＃３気筒のＢＴＤＣ６５゜ＣＡにおけるクラセン信号入力までの時間（クラセン間隔データ）を、ステップＳ６１１で総合位置変数ＡＣＡＳをパラメータとして配列ＴＣＡＳのＡＣＡＳ＝３のアドレスにストアすると共に、ステップＳ６１２でクランク位置情報変数ＣＣＡＳをパラメータとして配列ＭＴＣＳＸのＣＣＡＳ＝０のアドレスにストアする。
【０１２３】
従って、クラセン入力によるクラセン割込み毎に総合位置変数ＡＣＡＳ、クランク位置情報変数ＣＣＡＳが更新される都度、配列ＴＣＡＳ，ＭＴＣＳＸ内のデータが順次更新されるので、配列ＴＣＡＳを参照することにより、各気筒の各クランク位置におけるクラセン間隔の変化（回転速度の変化）を知ることができ、各気筒の失火の有無、燃焼状態などを判断することができ、全気筒の運転状況を把握することができる。また、配列ＭＴＣＳＸを参照することにより、常に最新のクラセン間隔を得ることができ、現在の運転状況を迅速に把握することができる。
【０１２４】
次いで、ステップＳ６１３へ進むと、再び、エラーレベルＥＣＡＳの値を調べる。ここでは、前述のステップＳ６０４においてＥＣＡＳ≠２であることを既に確認してあるため、エラーレベルＥＣＡＳが１か否か、すなわち、クランク位置の判別が不安の残る推定状態であるか否かを調べる。
【０１２５】
上記ステップＳ６１３でＥＣＡＳ≠１（すなわちＥＣＡＳ＝０）であり、クランク位置が確証をもって判別されているときには、上記ステップＳ６１３からステップＳ６１４へ進んで、最新３ヶのクラセン間隔データの和（配列ＭＴＣＳＸにストアされているクラセン間隔データの和）を、３バイトの半回転時間ＭＴＣＳ１８として算出する（ＭＴＣＳ１８＝ΣＭＴＣＳＸ）。すなわち、半回転時間ＭＴＣＳ１８は、クラセン割込み毎にクランク位置情報変数ＣＣＡＳが更新されて配列ＭＴＣＳＸ内のデータが更新される毎に算出され、ＢＴＤＣ９７°，６５°，１０°ＣＡの各位置毎にクラセン間隔の移動和を取ることにより常に最新のデータが得られるようになっている。
【０１２６】
一方、上記ステップＳ６１３で、ＥＣＡＳ＝１であり、クランク位置の判別が不安の残る推定状態であるときには、配列ＭＴＣＳＸから半回転時間ＭＴＣＳ１８を算出せず、ステップＳ６１５で半回転時間推定のサブルーチンを実行して半回転時間ＭＴＣＳ１８を推定する。
【０１２７】
この半回転時間ＭＴＣＳ１８の推定は、前回のクラセン間隔時間から今回の半回転時間を推定するものである。すなわち、図２３に示すように、現在のクランク位置情報変数ＣＣＡＳが１であれば、前回のクランク角間角度は３２゜ＣＡ（ＢＴＤＣ９７゜〜６５゜ＣＡ間の角度）であり、このクランク角間角度と前回のクラセン間隔データとから、次式に基づき半回転時間ＭＴＣＳ１８を算出する。
ＭＴＣＳ１８＝前回のクラセン間隔×１８０／３２
また、ＣＣＡＳ＝２のときには、ＢＴＤＣ６５゜〜１０゜ＣＡ間の角度５５゜ＣＡと前回のクラセン間隔データから、前回のクラセン間隔×１８０／５５により半回転時間ＭＴＣＳ１８を算出し、さらに、ＣＣＡＳ＝０のときには、ＢＴＤＣ１０゜ＣＡ〜ＡＴＤＣ８３゜ＣＡ（次の気筒のＢＴＤＣ９７゜ＣＡ）間の角度９３゜ＣＡと前回のクラセン間隔データとから、前回のクラセン間隔×１８０／９３により半回転時間ＭＴＣＳ１８を算出する。
【０１２８】
そして、上記ステップＳ６１４で半回転時間ＭＴＣＳ１８を算出した後、或は、上記ステップＳ６１５で半回転時間ＭＴＣＳ１８を推定した後は、ステップＳ６１６へ進み、３バイトの半回転時間ＭＴＣＳ１８を２バイトにリミットして所定の変数ＭＴＣＳＫにストアすると、ステップＳ６１７で、この変数ＭＴＣＳＫを２倍して変数ＭＴＣＳＫ４にストアし、ステップＳ６１８で、正常終了コード０をアキュムレータＡに格納してルーチンを抜ける。
【０１２９】
そして、前述のジョブ実行サブルーチンにおいて１０ｍｓ毎にエンジン回転数が算出され、このエンジン回転数は、３バイトの半回転時間ＭＴＣＳ１８を２バイトにリミットした変数ＭＴＣＳＫの逆数から算出される。
【０１３０】
詳述すると、毎分回転数ｒｐｍの単位時間（１ｍｉｎ）の半分の時間３０ｓｅｃを半回転時間ＭＴＣＳＫで割算することにより、１ｒｐｍを単位とする２バイト単位の変数ＮＲＰＭ、すなわち、エンジン回転数が算出され（ＮＲＰＭ＝３０ｓｅｃ／ＭＴＣＳＫ）、このエンジン回転数が基本パラメータの１つとして各種の制御量演算処理に用いられるのである。
【０１３１】
次に、図９に示すフローチャートに従って、上記クランク位置算出サブルーチンのステップＳ６０３で実行されるＣＣＡＳ・ＲＣＡＳ判別サブルーチンについて説明する。
【０１３２】
このサブルーチンでは、まず最初に、ステップＳ８００で、カムセンカウンタを０〜４にリミットする。このカムセンカウンタで計数されるカム角センサ４１からのカムパルスの数（クラセン信号入力間のカムパルス数）は、図２３に示すように、正常状態の場合０〜３であるが、ノイズなどの影響により４以上の異常な計数値となるおそれがあるため、カムセンカウンタを０〜４にリミットして異常な状態を４で代表するのである。
【０１３３】
次に、ステップＳ８０１へ進み、カムセンカウンタ（の計数値）、気筒情報変数ＲＣＡＳ、クランク位置情報変数ＣＣＡＳから、５×４×２の組合わせ（カムセンカウンタが０〜４の５種類、気筒情報変数ＲＣＡＳが０〜３の４種類、クランク位置情報変数ＣＣＡＳが０，１と２の場合の２種類）に対する状態データがストアされている気筒・クランク位置状態マップＣＣＨＭＡＰを読む。
【０１３４】
この気筒・クランク位置状態マップＣＣＨＭＡＰは、図２２（ａ）及び（ｂ）に示すように、クランク位置情報変数ＣＣＡＳが０或は１の場合と、気筒情報変数ＲＣＡＳの変化点であるクランク位置情報変数ＣＣＡＳが２の場合とに分け、カムセンカウンタと気筒情報変数ＲＣＡＳとの各組合わせの起こり得る全ての状態に対し、正常か異常か、確定して良いか推定すべきかを示す状態データがストアされており、現在の状態を評価し、次にとるべき状態を知ることができる。
【０１３５】
この状態データは２ビットのデータであり、ビット０の値により確定か推定かを表わし、ビット１の値により正常か異常かを表わす。ビット０の値は、０のとき確定、１のとき推定を示し、図２２からわかるように、カムセンカウンタが２，３の場合にのみ確定であって（図２３に示すカムセン信号パターン参照）、それ以外は推定せざるを得ない状態である。また、ビット１の値は、０のとき正常、１のとき異常を示し、カムセンカウンタが３以下で、且つ、図２３によるクランク位置変数の組合せに合致する場合のみ正常であって、それ以外は異常な状態である。
【０１３６】
例えば、ＣＣＡＳ＝０或は１、すなわち、ある気筒のＢＴＤＣ９７°〜１０°ＣＡに対し、カムセンカウンタが０で気筒情報変数ＲＣＡＳが０となる組合せは、図２３からもわかるように、クランク位置を正常に推定すれば良い状態であるため、図２２に示す気筒・クランク位置状態マップＣＣＨＭＡＰの該当領域に２進数で０１（正常推定）の状態データがストアされており、さらに、カムセンカウンタが１で気筒情報変数ＲＣＡＳが０となる組合せは、明らかに異常であって推定するしかない状態であるため、気筒・クランク位置状態マップＣＣＨＭＡＰの該当領域に２進数で１１（異常推定）の状態データがストアされている。
【０１３７】
また、ＣＣＡＳ＝２、すなわち、ある気筒のＢＴＤＣ１０°ＣＡ〜ＡＴＤＣ８３°ＣＡに対し、カムセンカウンタが３で気筒情報変数ＲＣＡＳが０となる組合せは、＃１気筒のＴＤＣを挟んだクランク位置と正常に確定できるため、気筒・クランク位置状態マップＣＣＨＭＡＰの該当領域に２進数で００（正常確定）の状態データがストアされており、さらに、カムセンカウンタが２で気筒情報変数ＲＣＡＳが０となる組合せは、明らかに異常ではあるがカムセン入力が２ヶある以上確定せざるを得ない状態であるため、気筒・クランク位置状態マップＣＣＨＭＡＰの該当領域に２進数で１０（異常確定）の状態データがストアされている。
【０１３８】
そして、上記ステップＳ８０１で気筒・クランク位置状態マップＣＣＨＭＡＰから状態データを読込むと、ステップＳ８０２へ進み、エラーレベルＥＣＡＳが２でないか否か、すなわち、現在の状態が気筒判別のなされていない不明な状態であるか否かを調べ、ＥＣＡＳ＝２のときには、ステップＳ８０３で気筒・クランク位置状態マップＣＣＨＭＡＰから読込んだ状態データのビット０が０か否か、すなわち確定状態か否かを調べ、確定状態のときにはステップＳ８０４へ進み、確定状態でなく推定状態であるときにはルーチンを抜けて確定状態となるまで待つ。
【０１３９】
一方、上記ステップＳ８０２でＥＣＡＳ≠２のときにはステップＳ８０４へ進んで、推定状態か否かを調べ、確定状態、推定状態に応じてステップＳ８０５以降の処理或はステップＳ８１２以降の処理へ進む。また、上記ステップＳ８０３において確定状態でステップＳ８０４へ進んだときには、ステップＳ８０５以降の処理へ進む。
【０１４０】
まず、ステップＳ８０５以降の処理について説明すると、このステップＳ８０５へ進んだときには、正常、異常に拘らず気筒判別がなされた確定状態であるため、図２３のタイムチャートからもわかるように、今回のクラセン割込みはカムパルスが３ヶ或は２ヶ入力された後のＢＴＤＣ９７°ＣＡの割込みであるため、クランク位置情報変数ＣＣＡＳを０にする。
【０１４１】
次いで、ステップＳ８０６へ進んでカムセンカウンタが３でないか否かを調べ、カムセンカウンタが３でないとき、すなわちカムセンカウンタが２のときには、＃２気筒の点火後であるため、ステップＳ８０７で気筒情報変数ＲＣＡＳを３にしてステップＳ８０９へ進み、カムセンカウンタが３のときには、＃１気筒の点火後であるため、ステップＳ８０８で気筒情報変数ＲＣＡＳを１にしてステップＳ８０９へ進む。
【０１４２】
ステップＳ８０９では、更新したクランク位置情報変数ＣＣＡＳ、気筒情報変数ＲＣＡＳ、及び、カムセンカウンタをパラメータとして再び気筒・クランク位置状態マップＣＣＨＭＡＰから状態データを読込み、この状態データのビット１が１であるか、すなわち異常状態であるか否かを調べる。
【０１４３】
その結果、上記ステップＳ８０９において、状態データのビット１が１で異常状態と判定されるときには、クランク位置情報変数ＣＣＡＳ、気筒情報変数ＲＣＡＳの更新結果は不安の残る推定であるとしてステップＳ８１０でエラーレベルＥＣＡＳを１にしてルーチンを抜け、状態データのビット１が０であり正常状態であるときには、ステップＳ８１１でエラーレベルＥＣＡＳを０としてルーチンを抜ける。
【０１４４】
一方、ステップＳ８１２以降の処理では、ステップＳ８１２で、現在のクランク位置情報変数ＣＣＡＳ（前回のクラセン割込みで算出されたクランク位置情報変数ＣＣＡＳ）が２、すなわち、気筒情報変数ＲＣＡＳの変化点であるか否かを調べ、ＣＣＡＳ＝２のときには、ステップＳ８１２からステップＳ８１３へ進んで、気筒情報変数ＲＣＡＳを１増加させ、ステップＳ８１４でクランク位置情報変数ＣＣＡＳを０にしてステップＳ８１７へ進む。
【０１４５】
一方、上記ステップＳ８１２で、ＣＣＡＳ≠２のときには、上記ステップＳ８１２からステップＳ８１５へ進んでカムセンカウンタが０でないか否かを調べ、カムセンカウンタが０でないときには、前述のステップＳ８１３へ分岐し、カムセンカウンタが０のときには、ステップＳ８１６でクランク位置情報変数ＣＣＡＳを１増加させ、ステップＳ８１７へ進む。
【０１４６】
ステップＳ８１７では、更新したクランク位置情報変数ＣＣＡＳ、気筒情報変数ＲＣＡＳ、及び、カムセンカウンタをパラメータとして再び気筒・クランク位置状態マップＣＣＨＭＡＰから状態データを読込んで異常状態であるか否かを調べ、状態データのビット１が０であり、正常状態であるときには、そのまま（現在のエラーレベルＥＣＡＳ＝０のまま）ルーチンを抜ける。また、上記ステップＳ８１７で、状態データのビット１が１で異常状態のときには、ステップＳ８１８へ進み、クランク位置情報変数ＣＣＡＳ、気筒情報変数ＲＣＡＳの更新結果は不安の残る推定であるとしてエラーレベルＥＣＡＳを１にし、ルーチンを抜ける。
【０１４７】
以上のように、クランク位置変数ＣＣＡＳ，ＲＣＡＳ，ＡＣＡＳ，ＥＣＡＳにより刻々と変化するクランク位置の状態を把握し、さらに、気筒・クランク位置状態マップＣＣＨＭＡＰを用いて、現在の状態を評価し、次にとるべき状態を知ることができるため、通常の条件判断による処理に比較して大幅にプログラムを簡略化することができ、メモリ容量の節約、処理速度の向上を図ることができるとともに、プログラムの可撓性を向上して仕様変更に対しても柔軟に対処することができる。
【０１４８】
次に、図１０、図１１に示す燃料噴射開始時期算出ルーチンについて説明する。この燃料噴射開始時期算出ルーチンは、前述したジョブ実行サブルーチンのステップＳ５５３で実行される５０ｍｓジョブのうちの一つで、噴射開始区間、噴射回数、及び１回当りの噴射幅を全気筒について設定する。すなわち、噴射エンドを固定した場合の連続噴射の開始時期が遅い場合、噴射回数を２回に設定し、一方連続噴射の開始時期が早い場合には噴射回数を１回にするものである。
【０１４９】
まず、ステップＳ１０００で始動時かを判断し、始動時の場合にはステップＳ１００１へ進み、噴射開始遅れ時間ＩＪＤＥＬＹを０とし、ステップＳ１００２で１回当りの噴射すべき有効噴射幅を１サイクル当りの総噴射量である要求噴射幅ＩＪＳＥＩｎ（ｎ＝＃１，＃２，＃３，＃４）の１／２に設定し、ステップＳ１００３で噴射開始区間設定フラグＩＪＴＭＧＦを例えば１２８＋２の複数回噴射にセットしてルーチンを抜ける。
【０１５０】
上記噴射開始遅れ時間ＩＪＤＥＬＹは後述する噴射タイマセットマクロ２で設定するタイマ待ち時間に組込まれるもので、噴射開始区間の始り（ＢＴＤＣ９７°ＣＡクラセン信号入力（以下、「９７゜ＣＡクラセン」と略記する）、或はＢＴＤＣ１０°ＣＡクラセン信号入力（以下、「１０゜ＣＡクラセン」と略記する）から何ｍｓ後に、１回噴射であれば最初の噴射を、２回噴射であれば２回目の噴射を開始するのかを決定する。
【０１５１】
また、上記噴射開始区間設定フラグＩＪＴＭＧＦにより、＃１〜＃４気筒の噴射開始区間が特定される。すなわち、この噴射開始区間は、＃１〜＃４気筒毎の噴射開始区間テーブルＩＪｎＴＢＬ（ｎ＝＃１，＃２，＃３，＃４）に予め格納されている。
【０１５２】
図２３に示すように、この各噴射開始区間テーブルＩＪｎＴＢＬ（ｎ＝＃１，＃２，＃３，＃４）では、＃１〜＃４気筒の１サイクルを前述のクランク総合位置変数ＡＣＡＳに対応して９７°ＣＡクラセンと１０°ＣＡクラセンとで８区間に区分し、各区間をビット７〜ビット０に対応させた１バイトの変数として上記噴射開始区間設定フラグＩＪＴＭＧＦにて噴射開始区間を設定する。すなわち、本実施例では、噴射開始区間テーブルＩＪｎＴＢＬの各噴射開始区間を、吸気行程の後半を０、前半を１、排気行程の後半を２、前半を３、燃焼行程の後半を４、前半を５、さらに、圧縮行程の後半を６、前半すなわち吸気行程終了直後を７と定義している。但し、噴射開始区間０では噴射処理を行わない。
【０１５３】
従って、上記ステップＳ１００３において、ＩＪＴＭＧＦ＝１２８＋２は、８ビットの変数で表せば１０００００１０であり、まず、１回目の噴射が噴射開始区間７（１０°ＣＡのクラセン）から開始され、次いで２回目の噴射が噴射開始区間１（１０°ＣＡのクラセン）から待ち時間無しで開始される。
【０１５４】
一方、上記ステップＳ１０００で始動時ではないと判断されてステップＳ１００４へ分岐すると、噴射開始セット時間ＩＪＴＩＭＥがゼロかを判断し、ＩＪＴＩＭＥ＝０の場合、上記ステップＳ１００１へ戻りステップＳ１００１，ステップＳ１００２，ステップＳ１００３を経てルーチンを抜ける。
【０１５５】
この噴射開始セット時間ＩＪＴＩＭＥはユーザ側の制御ストラテジーで設定するもので、例えば、この噴射開始セット時間ＩＪＴＩＭＥに要求噴射幅ＩＪＳＥＩｎ（ｎ＝＃１，＃２，＃３，＃４）を代入すれば、噴射エンドを吸気行程直前のＢＴＤＣ１０°ＣＡにほぼ固定することができる。また、この噴射開始セット時間ＩＪＴＩＭＥを任意に設定することで噴射エンド制御を行うことができる。従って、ユーザ側の制御ストラテジーにおいてＩＪＴＩＭＥ＝０と設定することも考えられ、この場合には上記ステップＳ１００４から、上記ステップＳ１００１へ戻り、上述したステップＳ１００２で要求噴射幅に対する１回当りの噴射幅を設定し、ステップＳ１００３で複数の噴射開始区間を設定してルーチンを抜ける。
【０１５６】
また、ステップＳ１００４でＩＪＴＩＭＥ≠０と判断されてステップＳ１００５へ進むと、このステップＳ１００５以下において、噴射開始セット時間ＩＪＴＩＭＥに基づく噴射開始区間及び噴射開始遅れ時間ＩＪＤＥＬＹを算出する。
【０１５７】
すなわち、上記噴射開始セット時間ＩＪＴＩＭＥを噴射開始区間毎のクラセン間隔（ＢＴＤＣ９７°〜１０°ＣＡ或はＢＴＤＣ１０°〜ＡＴＤＣ８３°ＣＡ間の間隔時間）で順次、ゼロ或は負になるまで減算して複数回噴射の各噴射開始区間を特定するとともに、最後の噴射開始区間の始め（９７°ＣＡクラセン或は１０°ＣＡクラセン）から何ｍｓ後に燃料噴射を開始すれば良いかを噴射開始遅れ時間ＩＪＤＥＬＹにより設定する。
【０１５８】
まず、ステップＳ１００５では、上記噴射開始セット時間ＩＪＴＩＭＥからクラセン間隔を減算し、その値をアキュムレータＡに格納し、ステップＳ１００６でこのアキュムレータＡの値が正か、ゼロあるいは負かを判断し、Ａ≦０場合、ステップＳ１００７へ進み、噴射開始遅れ時間ＩＪＤＥＬＹを上記アキュムレータＡに格納した値の２の補数で設定し（ＩＪＤＥＬＹ＝−Ａ）、ステップＳ１００８で１回当りの噴射すべき有効噴射幅を要求噴射幅ＩＪＳＥＩｎ（ｎ＝＃１，＃２，＃３，＃４）の１／２に設定し、ステップＳ１００９で噴射開始区間設定フラグＩＪＴＭＧＦを例えば１２８＋４の複数回噴射にセットしてルーチンを抜ける。ＩＪＴＭＧＦ＝１２８＋４を８ビットの変数で表せば、１００００１００であり、従って、噴射開始区間は７と２であり、１回目の噴射が噴射開始区間７から待ち時間無しで開始され、後の噴射が噴射開始区間２の９７°ＣＡクラセンから噴射開始遅れ時間ＩＪＤＥＬＹ後に開始される。
【０１５９】
一方、上記ステップＳ１００６で、Ａ＞０と判断されると、ステップＳ１０１０へ分岐し、上記アキュムレータＡの値を、このアキュムレータＡに格納した値からクラセン間隔を減算した値とし（Ａ＝Ａ−クラセン間隔）、ステップＳ１０１１でこのアキュムレータＡの値を参照し、Ａ≦０の場合、ステップＳ１０１２へ進み、噴射開始遅れ時間ＩＪＤＥＬＹを上記アキュムレータＡに格納した値の２の補数で設定し（ＩＪＤＥＬＹ＝−Ａ）、ステップＳ１０１３で１回当りの噴射すべき有効噴射幅を要求噴射幅ＩＪＳＥＩｎの１／２に設定し、ステップＳ１０１４で噴射開始区間設定フラグＩＪＴＭＧＦを例えば１２８＋８の複数回噴射にセットしてルーチンを抜ける。ＩＪＴＭＧＦ＝１２８＋８を８ビットの変数で表せば、１０００１０００であり、従って、噴射開始区間は７と３であり、１回目の噴射が噴射開始区間７から待ち時間無しで開始され、後の噴射が噴射開始区間３の１０°ＣＡクラセンから噴射開始遅れ時間ＩＪＤＥＬＹ後に開始される。
【０１６０】
一方、ステップＳ１０１１で、Ａ＞０と判断されると、ステップＳ１０１５へ分岐し、上記アキュムレータＡの値を、このアキュムレータＡに格納した値からクラセン間隔を減算した値とし（Ａ＝Ａ−クラセン間隔）、ステップＳ１０１６でこのアキュムレータＡの値を参照し、Ａ≦０の場合、ステップＳ１０１７へ進み、噴射開始遅れ時間ＩＪＤＥＬＹを上記アキュムレータＡの値の２の補数で設定し（ＩＪＤＥＬＹ＝−Ａ）、ステップＳ１０１８で１回当りの噴射すべき有効噴射幅を要求噴射幅ＩＪＳＥＩｎの１／２に設定し、ステップＳ１０１９で噴射開始区間設定フラグＩＪＴＭＧＦを例えば１２８＋１６の複数回噴射にセットしてルーチンを抜ける。ＩＪＴＭＧＦ＝１２８＋１６を８ビットの変数で表せば、１００１００００であり、従って、噴射開始区間は７と４であり、１回目の噴射が噴射開始区間７から待ち時間無しで開始され、後の噴射が噴射開始区間４の９７°ＣＡクラセンから噴射開始遅れ時間ＩＪＤＥＬＹ後に開始される。
【０１６１】
一方、ステップＳ１０１６で、Ａ＞０と判断されると、ステップＳ１０２０へ分岐し、上記アキュムレータＡの値を、このアキュムレータＡに格納した値からクラセン間隔を減算した値とし（Ａ＝Ａ−クラセン間隔）、ステップＳ１０２１でこのアキュムレータＡに格納した値を参照し、Ａ≦０の場合、ステップＳ１０２２へ進み、噴射開始遅れ時間ＩＪＤＥＬＹを上記アキュムレータＡの値の２の補数で設定し（ＩＪＤＥＬＹ＝−Ａ）、ステップＳ１０２３で１回当りの噴射すべき有効噴射幅を要求噴射幅ＩＪＳＥＩｎの１／２に設定し、ステップＳ１０２４で噴射開始区間設定フラグＩＪＴＭＧＦを例えば１２８＋３２の複数回噴射にセットしてルーチンを抜ける。ＩＪＴＭＧＦ＝１２８＋３２を８ビットの変数で表せば、１０１０００００であり、従って、噴射開始区間は７と５であり、１回目の噴射が噴射開始区間７から待ち時間無しで開始され、後の噴射が噴射開始区間５の１０°ＣＡクラセンから噴射開始遅れ時間ＩＪＤＥＬＹ後に開始される。
【０１６２】
一方、ステップＳ１０２１で、Ａ＞０と判断されると、ステップＳ１０２５へ分岐し、上記アキュムレータＡの値を、このアキュムレータＡに格納した値からクラセン間隔を減算した値とし（Ａ＝Ａ−クラセン間隔）、ステップＳ１０２６でこのアキュムレータＡに格納した値を参照し、Ａ≦０の場合、ステップＳ１０２７へ進み、噴射開始遅れ時間ＩＪＤＥＬＹを上記アキュムレータＡの値の２の補数で設定し（ＩＪＤＥＬＹ＝−Ａ）、ステップＳ１０２８で１回に全部噴射することを設定し、ステップＳ１０２９で噴射開始区間設定フラグＩＪＴＭＧＦを例えば６４の１回噴射にセットしてルーチンを抜ける。ＩＪＴＭＧＦ＝６４を８ビットの変数で表せば、０１００００００であり、噴射開始区間６の９７°ＣＡクラセンから噴射開始遅れ時間ＩＪＤＥＬＹ後に燃料噴射が開始される。
一方、ステップＳ１０２６で、Ａ＞０と判断されると、ステップＳ１０３０へ分岐し、上記アキュムレータＡの値を、このアキュムレータＡに格納した値からクラセン間隔を減算した値とし（Ａ＝Ａ−クラセン間隔）、ステップＳ１０３１でこのアキュムレータＡに格納した値を参照し、Ａ≦０の場合、ステップＳ１０３２へ進み、噴射開始遅れ時間ＩＪＤＥＬＹを上記アキュムレータＡに格納した値の２の補数で設定し（ＩＪＤＥＬＹ＝−Ａ）、ステップＳ１０３３で１回で全部噴射することを設定し、噴射開始区間設定フラグＩＪＴＭＧＦを１２８としてルーチンを抜ける。ＩＪＴＭＧＦ＝１２８を８ビットの変数で表せば、１０００００００であり、噴射開始区間７の１０°ＣＡクラセンから噴射開始遅れ時間ＩＪＤＥＬＹ後に燃料噴射が開始される。
【０１６３】
一方、ステップＳ１０３１で、Ａ＞０と判断されると、ステップＳ１０３５へ分岐し、噴射開始遅れ時間ＩＪＤＥＬＹを０とし、ステップＳ１０３６  で１回で全部噴射することを設定し、ステップＳ１０３７で噴射開始区間設定フラグＩＪＴＭＧＦを１２８としてルーチンを抜ける。ＩＪＴＭＧＦ＝１２８を８ビットの変数で表せば、１０００００００であり、噴射開始区間７の１０°ＣＡクラセンから待ち時間無しで燃料噴射が開始される。従って、このステップでの噴射が１サイクル中の最大噴射量となる。
【０１６４】
図２４に上記フローチャートに基づく燃料噴射開始時期の設定例のタイムチャートを示す。
【０１６５】
同図（ａ）に示すように、連続噴射の場合に噴射開始時期を遅くしても１サイクル中で噴射を完了させることが出来る場合には２回噴射とし、最初の噴射で燃料の気化の促進を図り、後の噴射で空燃比をトータル的に調整する。例えば、噴射開始区間設定フラグＩＪＴＭＧＦが１２８＋８に設定され、噴射開始遅れ時間ＩＪＤＥＬＹが時間ｔに設定された場合、まず、噴射開始区間７の１０°ＣＡクラセンから待ち時間無しで、総噴射量の１／２を噴射し、次いで噴射開始区間３の１０°ＣＡクラセンから時間ｔ後に残りの１／２が噴射される。
【０１６６】
また同図（ｂ）に示すように、連続噴射の場合に噴射を早く開始しなければ１サイクル中で噴射を完了させることが出来ない場合には１回噴射とする。例えば、噴射開始区間設定フラグＩＪＴＭＧＦが６４に設定され、噴射開始遅れ時間ＩＪＤＥＬＹが時間ｔに設定された場合、まず、噴射開始区間６の９７°ＣＡクラセンから時間ｔ後に全部噴射する。
【０１６７】
尚、上記フローチャートでは噴射開始区間設定フラグＩＪＴＭＧＦのビット指定を１気筒当り１カ所あるいは２カ所としているが、噴射開始区間設定フラグＩＪＴＭＧＦで３カ所以上のビットを指定するようにしても良い。複数回噴射とすることで、最後の噴射で空燃比をトータル的に調整し、結果として加速増量等の過渡時の空燃比変動に対しても後の噴射量を調整することで柔軟に対応することができる。
【０１６８】
また、本フローチャートでは、噴射開始区間を５０ｍｓｅｃ毎に設定しているため、エンジン回転数が９０００〜１００００ｒｐｍ等の高回転数に達してもメインＣＰＵ５８の負担が増加することはなく、高回転数域でも噴射エンド制御が可能になる。
【０１６９】
図１２は噴射タイマセットサブルーチンで、図２に示すクラセンによる割込み処理ルーチンのステップＳ２０５で実行されるもので、噴射開始区間毎に噴射タイマをセットする。
【０１７０】
まず、ステップＳ１１００でエラーレベルＥＣＡＳが２かを判断し、ＥＣＡＳ＝２の場合、クランク位置の判別が不明な状態であるため、以降の処理をせずサブルーチンを抜け、また、ＥＣＡＳ≠２の場合ステップＳ１１０１へ進み、クランク位置情報変数ＣＣＡＳが１かを判断し、ＣＣＡＳ＝１の場合、演算不要と判断してルーチンを抜ける。図２３に示すように、ＣＣＡＳ＝１の場合は６５°ＣＡクラセンの割込みであり、既に現噴射開始区間における噴射タイマのセットが終了しているため直ちにサブルーチンを抜け、処理負担を軽減する。一方、ＣＣＡＳ≠１の場合は、９７°ＣＡクラセンの割込みか、１０°ＣＡクラセンの割込みの何れかであり、噴射開始区間の始りであるため、ステップＳ１１０２以下において現噴射開始区間での噴射幅及び噴射開始時期を設定する。
【０１７１】
まず、ステップＳ１１０２〜ステップＳ１１０５では、後述する噴射タイマセットマクロ１を全気筒について実行し、現噴射開始区間における噴射幅（以下「有効噴射幅」とする）ＴＥＩＪＡｎ（ｎ＝＃１，＃２，＃３，＃４）を全気筒について設定する。
【０１７２】
そして、ステップＳ１１０６で、上記各ステップＳ１１０２〜ステップＳ１１０５で各々設定した有効噴射幅ＴＥＩＪＡｎが全てゼロかを判断し、全てゼロの場合、噴射タイマを再セットする必要がないためサブルーチンを抜ける。また、少なくとも一つの気筒がＴＥＩＪＡｎ≠０の場合には、ステップＳ１１０７へ進み、全ての噴射タイマを停止状態とし、その間、以下のステップＳ１１０８〜ステップＳ１１１１の処理を行う。
【０１７３】
このステップＳ１１０８〜ステップＳ１１１１では、後述する噴射タイマセットマクロ２を全気筒について実行し、上記噴射タイマセットマクロ１で設定した有効噴射幅ＴＥＩＪＡｎに基づく噴射時間を全気筒分設定する。
【０１７４】
そして、ステップＳ１１１２で全ての噴射タイマを再スタートさせてサブルーチンを抜ける。
【０１７５】
なお、上記ステップＳ１１０７で、全ての噴射タイマが停止されると、噴射時間が計時されないため燃料噴射中の気筒では燃料噴射が続行され、また噴射停止中の気筒では噴射停止状態が続行される。また、上記ステップＳ１１０８〜ステップＳ１１１２で設定した噴射時間には噴射タイマを停止した時間に相当する処理時間が考慮されている。
【０１７６】
上記噴射タイマセットサブルーチンにおけるステップＳ１１０２〜ステップＳ１１０５で実行される気筒毎の噴射タイマセットマクロ１は図１３，図１４に示す噴射タイマセットマクロ１を示すフローチャートにて実行される。尚、この噴射タイマセットマクロ１のプログラムは＃１気筒の噴射タイマセットルーチンを基本プログラムとし、これを＃２〜＃４気筒にも応用できるようにマクロ化したものである。
【０１７７】
まず、ステップＳ１２００で当該＃ｎ（ｎ＝１，２，３或は４）気筒の現在の噴射開始区間番号を、クランク総合位置変数ＡＣＡＳに基づき当該＃ｎ気筒の噴射開始区間テーブルＩＪｎＴＢＬ（図２３）を参照して調査し、ステップＳ１２０１で噴射開始区間番号がゼロかを判断する。そして、噴射開始区間がゼロの場合、ステップＳ１２０２へ進み、噴射開始区間がゼロでない場合ステップＳ１２１０へ進む。
【０１７８】
噴射開始区間０の時は  吸気行程後半であり噴射処理を行わない為、ステップＳ１２０２ないしステップＳ１２０９で次回の燃料噴射に備え燃料噴射の初期化処理を実行する。まず、ステップＳ１２０２では、当該＃ｎ気筒の累積噴射幅ＴＥＩＪＢｎをゼロとし、ステップＳ１２０３でユーザ側ジョブから燃料カット要求があるかを判断し、燃料カット要求がない場合ステップＳ１２０４へ進み、燃料カット要求がある場合にはステップＳ１２０８へ進む。
【０１７９】
燃料カット要求なしと判断してステップＳ１２０４へ進むと、燃料カット状態フラグＰＲＣＵＴの値を参照して当該＃ｎ気筒が燃料カット状態かを判断し、燃料カット状態ではない場合ステップＳ１２０５へ進み、また燃料カット状態の場合ステップＳ１２０６へ進む。
【０１８０】
この燃料カット状態フラグＰＲＣＵＴは＃１〜＃４気筒をビット０〜ビット３の４ビットに対応させて表したもので、ユーザ側ジョブにおいて燃料カットが要求された時の最初のルーチンでセットされ、また燃料カット要求解除後の最初のルーチンでクリアされる。
【０１８１】
上述したように、この燃料カット状態フラグＰＲＣＵＴは、噴射開始区間０において当該＃ｎ気筒に対応するビットがセットされているかを判断し、ユーザ側ジョブから燃料カット要求がなく、しかも、この燃料カット状態フラグＰＲＣＵＴがセットされている気筒は次のサイクルで燃料が噴射されない。
【０１８２】
そして、燃料カット状態ではないと判断されてステップＳ１２０５へ進むと、噴射開始区間０では噴射処理を行わないため当該＃ｎ気筒の有効噴射幅ＴＥＩＪＡｎをゼロにして当該＃ｎ気筒の噴射タイマセットマクロ１を終了する。
【０１８３】
また、上記ステップＳ１２０４から燃料カット状態と判断されてステップＳ１２０６へ進むと、ユーザ側ジョブから燃料カット要求がなく、燃料カット状態フラグＰＲＣＵＴはセットされているので、復帰後、第１回目のルーチンであり、次のサイクルにおける燃料カットリカバリに備え当該＃ｎ気筒の噴射開始区間ゼロで付着補正量分に相当する燃料を１回噴射する為、ユーザ側ジョブで設定した燃料付着補正量ＴＥＦＵＣＨで当該＃ｎ気筒の有効噴射幅ＴＥＩＪＡｎを更新し、ステップＳ１２０７で燃料カット状態フラグＰＲＣＵＴの当該＃ｎ気筒に対応するビットをクリアした後、当該＃ｎ気筒の噴射タイマセットマクロ１を終了する。
【０１８４】
その結果、燃料カット及び燃料カットリカバリに備える付着補正を気筒毎に設定することができる。
【０１８５】
また、上記ステップＳ１２０３で、ユーザ側ジョブから燃料カット要求ありと判断した場合には、噴射処理を行わない噴射開始区間０で、しかも燃料カットが要求されているため、ステップＳ１２０８で有効噴射幅ＴＥＩＪＡｎをクリアし、ステップＳ１２０９で燃料カット状態フラグＰＲＣＵＴの当該＃ｎ気筒に対応するビットをセットして、当該＃ｎ気筒の噴射タイマセットマクロ１を終了する。
【０１８６】
また、上記ステップＳ１２０１で現在の噴射開始区間がゼロ以外、すなわち、噴射処理領域の区間であると判断された場合には、ステップＳ１２１０以下で通常の噴射処理を行う。まず、ステップＳ１２１０では、燃料カット状態フラグＰＲＣＵＴの当該＃ｎ気筒のビットの値を参照し、当該＃ｎ気筒が燃料カット状態かを判断し、燃料カット状態の場合ステップＳ１２１１へ進み、有効噴射幅ＴＥＩＪＡｎをゼロにして当該＃ｎ気筒の噴射タイマセットマクロ１を終了する。
【０１８７】
一方、上記ステップＳ１２１０で燃料カット状態ではないと判断されるとステップＳ１２１２で今より後の区間では噴射しないかを、噴射開始区間設定フラグＩＪＴＭＧＦの値を参照して判断し、今より後の区間においても噴射すると判断した場合、ステップＳ１２１３へ進み、また、今より後の区間では噴射しないと判断した場合、ステップＳ１２１８へ進む。
【０１８８】
上記ステップＳ１２１２は１サイクル中における複数回噴射に対応したステップで、上記噴射開始区間設定フラグＩＪＴＭＧＦのビット０〜ビット７で指定した区間が２箇所以上ある場合、例えば、図２４（ａ）に示すように、ＩＪＴＭＧＦ＝１２８＋８であれば、区間７と３が噴射開始区間であり、噴射開始区間７においては今より後の区間で噴射されるためステップＳ１２１３へ進み、一方、噴射開始区間３では今より後の区間で噴射を開始しないためステップＳ１２１８へ進む。
【０１８９】
そして、ステップＳ１２１３へ進むと、現在の区間で噴射するかを、上記噴射開始区間設定フラグＩＪＴＭＧＦの値を参照してその指示値が前記ステップＳ１２００で検索した現在の区間番号と一致するかにより判断し、現在の区間で噴射しない場合、ステップＳ１２１４へ進み有効噴射幅ＴＥＩＪＡｎをゼロにして当該＃ｎ気筒の噴射タイマセットマクロ１を終了する。
【０１９０】
一方、上記ステップＳ１２１３で現在の区間で噴射すると判断された場合には、ステップＳ１２１５へ進み、ユーザ側ジョブで１０ｍｓ毎に設定される気筒別要求噴射幅ＩＪＳＥＩｎを２のｎ乗で除算して１回当りの噴射量を求め、その値をアキュムレータＡに格納し、ステップＳ１２１６でこのアキュムレータＡに格納した値で当該＃ｎ気筒の有効噴射幅ＴＥＩＪＡｎを設定し、ステップＳ１２１７で、上記アキュムレータＡの値に累積噴射幅ＴＥＩＪＢｎを足し込み、噴射タイマセットマクロ１を終了する。
【０１９１】
上記次数ｎは、前述した燃料噴射開始時期の算出ルーチンのステップＳ１００２，Ｓ１００８，Ｓ１０１３，Ｓ１０１８，Ｓ１０２３，Ｓ１０２８，Ｓ１０３３あるいはＳ１０３６で設定した噴射回数に基づいて設定されるもので、１／２噴射に設定されている場合には  ｎ＝１、全部噴射に設定されている場合には  ｎ＝０に設定される。その結果、２回噴射では、最後の噴射開始区間において、最新の気筒別要求噴射幅ＩＪＳＥＩｎの１／２に相当する有効噴射幅が設定される。
【０１９２】
また、上記ステップＳ１２１２からステップＳ１２１８へ進むと、現在の区間で噴射するかを上記ステップＳ１２１３と同様、上記噴射開始区間設定フラグＩＪＴＭＧＦの値を参照して判断し、現在の区間で噴射する場合、ステップＳ１２１９へ進み、また現在の区間で噴射しない場合、ステップＳ１２２３へ進む。
【０１９３】
そして、ステップＳ１２１９では、気筒別要求噴射幅ＩＪＳＥＩｎから上記累積噴射幅ＴＥＩＪＢｎを減算した値をアキュムレータＡに格納し、ステップＳ１２２０で、このアキュムレータＡの値で有効噴射幅ＴＥＩＪＡｎを設定する。
【０１９４】
次いで、ステップＳ１２２１で累積噴射幅ＴＥＩＪＢｎを要求噴射幅ＩＪＳＥＩｎとして、ステップＳ１２２２へ進む。すなわち、現在の区間が噴射終了区間であり、これより後の区間では噴射しないため、このルーチンにおいては累積噴射幅ＴＥＩＪＢｎを要求噴射幅ＩＪＳＥＩｎと同一の値にする。その結果、例えば、１サイクル中１回噴射の場合には，ＴＥＩＪＢｎ＝０であるためＴＥＩＪＡｎ＝ＩＪＳＥＩｎとなる。そして、次回の噴射開始区間でのルーチン実行時には、ＴＥＩＪＢｎ＝ＩＪＳＥＩｎ＝０となる。
【０１９５】
そして、ステップＳ１２２２で噴射待ち設定フラグＦＬＧ＿ＩＪをセットして噴射タイマセットマクロ１を終了する。すなわち、このルーチンでは当該＃ｎ気筒の１サイクル中における最後の噴射であり、噴射待ち設定フラグＦＬＧ＿ＩＪをセットすることで、後述する噴射タイマセットマクロ２で設定される噴射終了時期を例えば吸気行程直前の１０°ＣＡクラセンに合わせることができる。
【０１９６】
一方、上記ステップＳ１２１８からステップＳ１２２３へ進むと、気筒別要求噴射幅ＩＪＳＥＩｎから上記ステップＳ１２２１で設定した累積噴射幅ＴＥＩＪＢｎを減算した値をアキュムレータＡに格納する。
【０１９７】
そして、ステップＳ１２２４で上記アキュムレータＡの値を参照し、Ａ＜０、すなわち、運転条件が変化して要求噴射量ＩＪＳＥＩｎが減少した場合、ステップＳ１２２６へ進み、また、Ａ≧０、すなわち、要求噴射量ＩＪＳＥＩｎが増加したか或は変化していない場合、ステップＳ１２２５へ進む。燃料噴射幅がユーザ側ジョブにおいて１０ｍｓ毎に設定されるため、次のルーチン実行時に読込む要求噴射幅ＩＪＳＥＩｎが前回のルーチン実行時において読込んだ要求噴射幅ＩＪＳＥＩｎと相違している場合、その差分を増量、或は減量することで、常に最新の値で有効噴射幅ＴＥＩＪＡｎを設定することができるため運転条件の変化に対する追従性が良くなる。
【０１９８】
その後、上記ステップＳ１２２４からステップＳ１２２５へ進むと、上記アキュムレータＡの値と噴射幅の許容変動値、例えば０．５ｍｓとを比較し、Ａ＞０．５ｍｓの場合ステップＳ１２２６へ進み、Ａ≦０．５ｍｓの場合には前記ステップＳ１２１４へ進み、有効噴射幅ＴＥＩＪＡｎをゼロとして当該＃ｎ気筒の噴射タイマセットマクロ１を終了する。
【０１９９】
また、ステップＳ１２２４或はステップＳ１２２５からステップＳ１２２６へ進むと、有効噴射幅ＴＥＩＪＡｎを上記アキュムレータＡの値（ステップＳ１２２４からの場合は負の値）で設定し、ステップＳ１２２７で累積噴射幅ＴＥＩＪＢｎを上記要求噴射幅ＩＪＳＥＩｎとして、噴射タイマセットマクロ１を終了する。
【０２００】
上記噴射タイマセットサブルーチンにおけるステップＳ１１０８〜ステップＳ１１１１での噴射タイマセットマクロ２は図１５，図１６に示す噴射タイマセットマクロ２を示すフローチャートにて実行される。尚、この噴射タイマセットマクロ２のプログラムは上記噴射タイマセットマクロ１を示すフローチャートと同様に＃１気筒のタイマセットルーチンを基本プログラムとし、これを＃２〜＃４気筒にも応用できるようにマクロ化したものである。
【０２０１】
まず、ステップＳ１３００で噴射タイマの状態から前回の噴射開始区間で設定した燃料の噴射状況を判断し、今回の噴射開始区間においても継続して噴射中の場合ステップＳ１３０１へ進み、噴射待ち状態が継続されている場合ステップＳ１３０７へ進み、また、噴射が終了されている場合ステップＳ１３１２へ進む。
【０２０２】
継続して噴射中と判断されてステップＳ１３０１へ進むと、停止中の噴射タイマの現状のタイマ値に、当該＃ｎ気筒の前記噴射タイマセットマクロ１で設定した正或は負の値の有効噴射幅ＴＥＩＪＡｎ（ｍｓ）を加算し、その値をアキュムレータＡに格納する。従って、前回のルーチンで一旦設定した噴射タイマの値がその後の運転条件の変化に基づいて設定した最新の有効噴射幅ＴＥＩＪＡｎで修正されることになる。
【０２０３】
次いで、ステップＳ１３０２で、上記キュムレータＡの値から処理時間（噴射タイマ停止から再セットするまでの時間）を減算し、この減算した値をステップＳ１３０３で、ゼロから１サイクルの最大噴射量である２回転時間の間にリミットし（０≦Ａ＜２回転時間、従って、Ａが負の場合にはＡ＝０となる）、ステップＳ１３０４で、現在噴射中であるためタイマ待ち時間を０とし、ステップＳ１３０５で噴射タイマのリロード値を上記アキュムレータＡの値で設定し、ステップＳ１３０６で上記リロード値に対応する噴射パルスの出力パターンをタイマにセットして当該＃ｎ気筒の噴射タイマセットマクロ２を終了する。
【０２０４】
その結果、１回噴射ではその噴射区間が過ぎた後の区間で、複数回噴射では最後の噴射区間を過ぎた後の区間で、今回の区間で設定した有効噴射幅ＴＥＩＪＡｎが前回の区間で設定した値に比し、０．５ｍｓ以上増加している場合には噴射タイマが延長され、また有効噴射幅ＴＥＩＪＡｎが減少している場合には、最後の噴射区間の噴射タイマが短縮されて、１吸気行程中の気筒に供給する噴射量の合計が調整される。
【０２０５】
一方、上記ステップＳ１３００で噴射待ち状態が継続されていると判断されてステップＳ１３０７へ進むと、噴射タイマにセットされているタイマリロード値に、今回の区間で設定した正或は負の値の有効噴射幅ＴＥＩＪＡｎを加算して、その値をアキュムレータＡに格納し、ステップＳ１３０８で、上記アキュムレータＡの値を、ゼロから１サイクルの最大噴射量である２回転時間にリミットし（０≦Ａ＜２回転時間）、ステップＳ１３０９で直ちに噴射を行うべくタイマ待ち時間を０として、ステップＳ１３１０でタイマリロード値を上記アキュムレータＡに格納されている値で設定し、ステップＳ１３１１で上記タイマリロード値に対応する噴射パルスの出力パターンをタイマにセットして当該＃ｎ気筒の噴射タイマセットマクロ２を終了する。
【０２０６】
上記タイマ待ち時間は、噴射終了時期を調整するために、後述するステップＳ１３２５で設定されるものであるが、前回の噴射開始区間で設定された待ち時間が今回の噴射開始区間においても依然と計時されている場合には、タイマ待ち時間が異常に長いので、上記ステップＳ１３０９でゼロにし、今回の噴射開始区間で直ちに噴射を開始し、１吸気行程中に供給する噴射量を調整する。
【０２０７】
また、上記ステップＳ１３００で前回の噴射開始区間での噴射が既に終了していると判断して、ステップＳ１３１２へ進むとアキュムレータＡに有効噴射幅ＴＥＩＪＡｎを格納し、ステップＳ１３１３で、このアキュムレータＡの値が正か負あるいはゼロかを判断し、Ａ≦０場合ステップＳ１３１４へ進み、また、Ａ＞０の場合ステップＳ１３１８へ分岐する。
【０２０８】
ステップＳ１３１４では、有効噴射幅ＴＥＩＪＡｎが増加してしないので１サイクル中の噴射を終了させるため、噴射待ち設定フラグＦＬＧ＿ＩＪをクリアし、ステップＳ１３１５でタイマ待ち時間をゼロとし、ステップＳ１３１６で噴射タイマのリロード値をゼロとし、ステップＳ１３１７で出力パターンをゼロとして当該＃ｎ気筒の噴射タイマセットマクロ２を終了する。
【０２０９】
また、上記ステップＳ１３１３で有効噴射幅ＴＥＩＪＡｎが正の場合には、噴射量の増加分を補償するためステップＳ１３１８で、上記アキュムレータＡに、他の制御ストラテジーで設定した気筒別の無駄時間ＴＳＩＮＪｎ（ｎ＝＃１，＃２，＃３，＃４）を加算し、ステップＳ１３１９で上記アキュムレータＡに格納されている値が１サイクルの最大噴射量である２回転時間を越えている場合、２回転時間にリミットし（Ａ＜２回転時間）、ステップＳ１３２０で噴射待ち設定フラグＦＬＧ＿ＩＪの値を参照して噴射待ち状態ではないかを判断し、噴射待ち状態ではない場合、すなわち、噴射待ち設定フラグＦＬＧ＿ＩＪがクリアされている場合には、ステップＳ１３２１へ進み、増量分を直ちに噴射させるべくタイマ待ち時間を０として、ステップＳ１３２２でタイマリロード値を上記アキュムレータＡの値（ＴＥＩＪＡｎ＋ＴＳＩＮＪｎ）で設定し、ステップＳ１３２３で上記タイマリロード値に対応する噴射パルスの出力パターンを噴射タイマにセットして当該＃ｎ気筒の噴射タイマセットマクロ２を終了する。
【０２１０】
一方、上記ステップＳ１３２０で噴射待ち状態と判断されてステップＳ１３２４へ進むと、噴射待ち設定フラグＦＬＧ＿ＩＪをクリアした後、ステップＳ１３２５で、上記噴射開始時期算出ルーチンで設定した噴射開始遅れ時間ＩＪＤＥＬＹでタイマ待ち時間を設定し、ステップＳ１３２６でタイマリロード値を上記アキュムレータＡの値で設定し、  ステップＳ１３２７で上記タイマリロード値に対応する噴射パルスの出力パターンを噴射タイマにセットして当該＃ｎ気筒の噴射タイマセットマクロ２を終了する。その結果、この噴射開始区間の始りから所定タイマ待ち時間（ＩＪＤＥＬＹ）後に燃料噴射が開始される。
【０２１１】
以上の結果、図２５に示すように、燃料噴射開始時期の算出ルーチンで設定した噴射開始区間設定フラグＩＪＴＭＧＦによるビット指定で、１サイクル中の噴射回数を４回、３回、２回等、複数回に設定することができる。また、複数回噴射において最終回以外の有効噴射幅を、次数ｎの指定にて要求噴射幅の１／４，１／１等、任意に設定することができ、最終回噴射において１サイクル中の噴射幅の合計が最新の要求噴射幅になるように調整することができる。さらに、最終回噴射の噴射開始区間内で噴射が終了しない場合には、噴射タイマを延長し、また有効噴射幅が減少した場合には、噴射タイマを短縮して加速増量等過渡時の追従性を良くする。
【０２１２】
なお、図２５（ｂ）は、４回噴射（ＩＪＴＭＧＦ＝１２８＋３２＋８＋２）で、１噴射当りの有効噴射幅が要求噴射幅の１／４、同図（ｃ）は、３回噴射（ＩＪＴＭＧＦ＝３２＋８＋２に設定）で、１噴射当りの有効噴射幅が要求噴射幅の１／４、同図（ｄ）は、２回噴射（ＩＪＴＭＧＦ＝１６＋２に設定）で、１噴射当りの有効噴射幅が要求噴射幅の１／１、同図（ｅ）は、２回噴射（ＩＪＴＭＧＦ＝４＋２に設定）で、１噴射当りの有効噴射幅が要求噴射幅の１／１にそれぞれ設定した場合の例を示したものである。
【０２１３】
以上、本発明の一実施例について説明したが、これに限定されず、多気筒エンジンであればよく、また、水平対向エンジン以外のエンジンにも適用することができる。
【０２１４】
【発明の効果】
以上説明したように本発明によれば、多気筒エンジンの各気筒毎の１サイクルを、吸気行程後半、吸気行程前半、排気行程後半、排気行程前半、燃焼行程後半、燃焼行程前半、圧縮行程後半、圧縮行程前半の各噴射開始区間に区分する。そして、噴射制御を行わない吸気行程後半を除く各区間を、噴射開始区間として定義し、「上記噴射開始区間の数＋１」個のビットからなり、気筒数分の、各ビットが各噴射区間を表す噴射開始区間設定フラグを用い、噴射開始セット時間に基づき上記各噴射開始区間の中から少なくとも１つの噴射開始区間を上記噴射開始区間設定フラグにより指定する。そして、複数の噴射開始区間を指定した場合は、指定した最終の噴射開始区間より前の噴射開始区間での噴射すべき有効噴射幅を、１サイクル中の要求噴射幅を指定した噴射開始区間の数により分割した値で設定する。また最終の噴射開始区間での噴射すべき最終有効噴射幅を１サイクル中に必要とする要求噴射幅と上記最終より前の噴射開始区間で噴射した有効噴射幅の合計との差分に応じて設定するので、指定された噴射開始区間が２つの場合は勿論のこと、噴射開始区間が３以上指定された場合であっても、指定された各噴射開始区間における有効噴射幅を適正に設定することができて、空燃比性御性が向上する。
【０２１５】
また、最終の噴射開始区間での噴射すべき最終有効噴射幅を、１サイクル中に必要とする要求噴射幅と上記最終より前の噴射開始区間で噴射した有効噴射幅の合計との差分に応じて設定するので、１サイクル中で要求噴射幅が変動した場合でも、最終の噴射開始区間において対処することが可能となり、柔軟に対応することができ、空燃比制御性を一層向上できる。
【０２１６】
さらに、最終より前の噴射開始区間での燃料噴射を当該噴射開始区間の始まりから開始し、最終の噴射開始区間における燃料噴射開始時期を、上記噴射開始セット時間から噴射開始区間の間隔時間の正数倍を減算してゼロ或いは負の値を示したときの２の補数に基づき上記最終の噴射開始区間の始まりから起算して設定するので、複数回噴射を噴射開始セット時間および噴射開始区間により指定するのみで、噴射開始時期及び噴射エンドを適正に設定することができ、エンジンの燃焼効率の向上、及びエンジン回転の安定化を図ることができる。
【図面の簡単な説明】
【図１】０．５ｍｓ毎の定期割込み処理を示すフローチャート
【図２】クラセン割込み処理を示すフローチャート
【図３】ジョブ優先処理を示すフローチャート
【図４】ジョブ実行サブルーチンを示すフローチャート
【図５】同上
【図６】同上
【図７】同上
【図８】クランク位置算出サブルーチンを示すフローチャート
【図９】ＣＣＡＳ・ＲＣＡＳ判別サブルーチンを示すフローチャート
【図１０】燃料噴射開始時期算出ルーチンを示すフローチャート
【図１１】同上
【図１２】噴射タイマセットサブルーチンを示すフローチャート
【図１３】噴射タイマセットマクロ１ルーチンを示すフローチャート
【図１４】同上
【図１５】噴射タイマセットマクロ２ルーチンを示すフローチャート
【図１６】同上
【図１７】ジョブの実行状態を示す説明図
【図１８】ジョブフラグの説明図
【図１９】ジョブ実行中フラグとオーバーラップカウンタの変化を示す説明図
【図２０】システムシフトバッファの説明図
【図２１】クラセン間隔テーブルの説明図
【図２２】気筒・クランク位置状態マップの説明図
【図２３】クランク位置、カム位置とクランク位置変数、噴射開始区間テーブル及び気筒別行程順のタイムチャート
【図２４】噴射開始区間、及び噴射開始区間設定フラグの説明図
【図２５】噴射タイマコントロールを示すタイムチャート
【図２６】エンジン系の概略構成図
【図２７】クランクロータとクランク角センサの正面図
【図２８】カムロータとカム角センサの正面図
【図２９】電子制御系の回路構成図
【符号の説明】
１…エンジン
２５…インジェクタ
３９…クランク角センサ
４１…カム角センサ
５０…電子制御装置
ＩＪｎＴＢＬ…噴射開始区間テーブル
ＩＪＴＭＧＦ…噴射開始区間設定フラグ
ＩＪＴＩＭＥ…噴射開始セット時間
ＩＪＳＥＩｎ…要求噴射幅
ＴＥＩＪＡｎ…有効噴射幅
【図１】
0003555689.tif 000002
【図２】
0003555689.tif 000003
【図３】
0003555689.tif 000004
【図４】
0003555689.tif 000005
【図５】
0003555689.tif 000006
【図６】
0003555689.tif 000007
【図７】
0003555689.tif 000008
【図８】
0003555689.tif 000009
【図９】
0003555689.tif 000010
【図１０】
0003555689.tif 000011
【図１１】
0003555689.tif 000012
【図１２】
0003555689.tif 000013
【図１３】
0003555689.tif 000014
【図１４】
0003555689.tif 000015
【図１５】
0003555689.tif 000016
【図１６】
0003555689.tif 000017
【図１７】
0003555689.tif 000018
【図１８】
0003555689.tif 000019
【図１９】
0003555689.tif 000020
【図２０】
0003555689.tif 000021
【図２１】
0003555689.tif 000022
【図２２】
0003555689.tif 000023
【図２３】
0003555689.tif 000024
【図２４】
0003555689.tif 000025
【図２５】
0003555689.tif 000026
【図２６】
0003555689.tif 000027
【図２７】
0003555689.tif 000028
【図２８】
0003555689.tif 000029
【図２９】
0003555689.tif 000030