概要
dsPIC33Cシリーズの高分解能PWMモジュールは様々なスイッチングアプリケーションに対応できる構成となっています。
今回はPCI機能を試してみます。
PCIとはPWM Control Inputの頭文字を取った略語で、主にPCIブロックに入力された信号を条件付けしPWM出力信号をトリガ、ゲート、オーバーライドするために使われます。
主に電源アプリケーションでは過電流や過電圧時の保護動作やピーク電流モードなどの用途に使われると想定されますが、さまざまなアプリケーションに対応できるように非常に柔軟かつ複雑な構成となっています。
用途
PWMジェネレータは(fig.1)のブロックで構成されており、赤枠内に4系統のPCIブロックが内蔵されています。
・PCI Fault
・PCI Current Limit
・PCI Feed-Forward
・PCI Sync

4系統のPCIブロックの機能は基本的にほぼ同等ですが、PCI Syncはトリガ用に用いられ、残りの3ブロックはPWM出力を制御するために用いられます。またPCI機能が同時に発生した場合、PCI Faultが最優先で動作するように設計されています。
| PCI機能 | 優先度 | 用途 |
| PCI Fault | 高 | 主に異常状態を検出しスイッチング素子を安全な状態(通常はOFF)にするために使用 |
| PCI Current Limit | 中 | 主に保護用もしくはピーク電流制御用に使用 |
| PCI Feed-Forward | 低 | 主に制御ループのフィードフォワードとして、負荷の急激な変化を検出し即時に応答するようなシステムで使用 |
PCIブロック図
PCIのブロック図を(fig.3)に示します。
PCIブロックは大きく以下の5つに分類されます。
①PCIソース
②PCIソースクオリファイア
③ターミネータイベント
④ターミネータクオリファイア
⑤アクセプタンスロジック

①PCIソース
PCIソースはPCIをアクティブにするイベントを決定します。
| レジスタ.ビット | 機能 |
| PGxyPCILbits.PSS | PCIをアクティブにするイベント選択 |
| PGxyPCILbits.PPS | PGxyPCILbits.PPSで指定したイベントのロジックを反転・非反転する |
| PGxyPCILbits.PSYNC | PCIソースをEOC(End of cycle)に同期させる |

②PCIソースクオリファイア
PCIソースクオリファイアはPCIのアクティブ化を一時的に無効化する機能です。
| レジスタ.ビット | 機能 |
| PGxyPCILbits.AQSS | PCIのアクティブ化を一時的に無効化するイベントを選択 |
| PGxyPCILbits.AQPS | PGxyPCILbits.AQSSで指定したイベントのロジックを反転・非反転する |

使用目的ですが電源アプリケーションではスイッチングの過渡期の電流波形にスイッチングノイズが重畳する事が有ります。コンパレータの閾値まで到達した場合、望ましくない動作をする場合が有り、これを防ぐためにLEB(リーディングエッジブランキング)機能が搭載されています。
PCIソースにコンパレータ出力、PCIクオリファイアにLEBを指定するとLEB期間はPCI入力をブランキングさせます。

③ターミネータイベント
ターミネータイベントはPCIのアクティブ状態を終了させるイベントを決定します。
| レジスタ.ビット | 機能 |
| PGxyPCILbits.TERM | PCIのアクティブ状態を終了させるイベントの選択 |
| PGxyPCILbits.TSYNCDIS | PGxyPCILbits.AQSSで指定したイベントのロジックを反転・非反転する |

④ターミネータクオリファイア
ターミネータクオリファイアはターミネータイベントを無効化する機能です。
| レジスタ.ビット | 機能 |
| PGxyPCIHbits.TQSS | ターミネータイベントを一時的に無効化するイベントの選択 |
| PGxyPCIHbits.TQPS | PGxyPCIHbits.TQSSで指定したイベントのロジックを反転・非反転する |

⑤アクセプタンスロジック
アクセプタンスロジックは①~④の入力信号を受け、どのようにPCIをアクティブにするかを決定するブロックです。
| レジスタ.ビット | 機能 |
| PGxyPCIHbits.ACP | PCI アクセプタンスロジックのモード選択ビット |

0 = Level Sensitive
「PCIクオリファイアがアクティブ」かつ「PCI入力がアクティブ」の場合、PCIアクティブ信号がアサートされる。

1 = Rising Edge
「PCIクオリファイアがアクティブ」かつ「PCI入力の立ち上がりエッジ」で、PCIアクティブ信号がアサートされる。

2 = Any Edge
「PCIクオリファイアがアクティブ」かつ「PCI入力の両エッジ」で、PCIアクティブ信号がアサートされる。

3 = Latched
「PCIクオリファイアがアクティブ」かつ「PCI入力がアクティブ」で、PCIアクティブ信号がアサートされ、「クオリファイドターミネータが入力」されるまでラッチされる。

4 = Latched Rising Edge
「PCIクオリファイアがアクティブ」かつ「PCI入力の立ち上がり」で、PCIアクティブ信号がアサートされ、「クオリファイドターミネータが入力」されるまでラッチされる。

5 = Latched Any Edge
「PCIクオリファイアがアクティブ」かつ「PCI入力の両エッジ」で、PCIアクティブ信号がアサートされ、「クオリファイドターミネータが入力」されるまでラッチされる。

ハードウェア構成と制御ブロック
今回のプログラムは前回の記事で構成したスロープ生成ブロックにPCI機能を追加します。
PWM1に同期したポジティブスロープとポテンションの電圧をCMP1で比較し、PCIソースとして利用します。

レジスタ
関連レジスタに関しては非常に多いため、今回の動作に関係する部分だけ抜粋します。
| レジスタ名 | 機能 | 説明 |
| PCLKCON | PWM CLOCK CONTROL REGISTER | PWMクロックを制御 |
| PGxCONL | GENERATOR x CONTROL REGISTER LOW | PGxのクロックや動作モードの設定を行います |
| PGxIOCONH | PWM GENERATOR x I/O CONTROL REGISTER LOW | PGxの出力ピンに関する設定を行います |
| PGxPER | PWM GENERATOR x PERIOD REGISTER | PGxの周期を設定します |
| PGxPHASE | PWM GENERATOR x PHASE REGISTER | PGxの位相を設定します |
| PGxDC | PWM GENERATOR x DUTY CYCLE REGISTER | PGxのデューティを設定します |
| PGxDTH PGxDTL | PWM GENERATOR x DEAD-TIME REGISTER | PGxのデッドタイムを設定します |
| PGxEVTL PG1EVTH | PWM GENERATOR x Event REGISTER | PGxのイベントに関する設定を行います |
| PG1TRIGA PG1TRIGB PG1TRIGC | PWM GENERATOR x TRIGGER A REGISTER PWM GENERATOR x TRIGGER B REGISTER PWM GENERATOR x TRIGGER C REGISTER | PGxのトリガに関する設定を行います |
| PG1CLPCIL PG1CLPCIH | PWM GENERATOR x PCI LOW REGISTER PWM GENERATOR x PCI HIGH REGISTER | 過電流PCIの設定を行います |
| DACCTRL1L | DAC CONTROL 1 LOW REGISTER | DAC制御1Lレジスタの設定 |
| DACCTRL2H | DAC CONTROL 2 HIGH REGISTER | DAC制御2Hレジスタの設定 |
| DACCTRL2L | DAC CONTROL 2 LOW REGISTER | DAC制御2Lレジスタの設定 |
| DACxCONH | DACx CONTROL HIGH REGISTER | DACx制御Hレジスタの設定 |
| DACxCONL | DACx CONTROL LOW REGISTER | DACx制御Lレジスタの設定 |
| DAC1DATH DAC1DATL | DACx DATA HIGH REGISTER DACx DATA LOW REGISTER | DACx値レジスタの設定 |
| SLP1CONH | DACx SLOPE CONTROL HIGH REGISTER | スロープx制御レジスタHレジスタの設定 |
| SLP1CONL | DACx SLOPE CONTROL LOW REGISTER | スロープx制御レジスタLの設定 |
| SLP1DAT | DACx SLOPE CONTROL LOW REGISTER | スロープxデータレジスタの設定 |
ソースコード
下記にコードを示します。
コンフィグレーション設定についてはコンフィグレーション設定に記載しております。
コピーして下記のソースコードの「 //ここにコンフィグレーション設定を挿入する// 」の位置に挿入してください。
クロック設定用関数 vds_Main_Init_Clock_Register(); のソースコードはクロック設定のページに記載しております。
コピーして下記のソースコードの「 //ここにクロック設定ソースをコピペする// 」の位置に挿入してください。
/*----------------------------------------------------------------------------*/
/* <Chapter> CHAPTER_2_7_6_HRPWM_PCI */
/* <Function> PWM1_PCI動作 */
/* <Peripharal> PWM関連 */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* コンフィグレーション設定*/
/*----------------------------------------------------------------------------*/
//ここにコンフィグレーション設定を挿入する//
/*----------------------------------------------------------------------------*/
/* インクルードファイル*/
/*----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
/*----------------------------------------------------------------------------*/
/* 定数定義*/
/*----------------------------------------------------------------------------*/
#define PWM_DRV_PGXEVTL_ADTR1EN1_DISABLE ( 0u) //PGxTRIGAレジスタコンペアイベントをADCトリガ1向け信号源として無効にする
#define PWM_DRV_PGXEVTL_ADTR1EN1_ENABLE ( 1u) //PGxTRIGAレジスタコンペアイベントをADCトリガ1向け信号源として無効にする
#define PWM_DRV_PGXEVTL_ADTR1EN2_DISABLE ( 0u) //PGxTRIGBレジスタコンペアイベントをADCトリガ1向け信号源として無効にする
#define PWM_DRV_PGXEVTL_ADTR1EN2_ENABLE ( 1u) //PGxTRIGBレジスタコンペアイベントをADCトリガ1向け信号源として無効にする
#define PWM_DRV_PGXEVTL_ADTR1EN3_DISABLE ( 0u) //PGxTRIGCレジスタコンペアイベントをADCトリガ1向け信号源として無効にする
#define PWM_DRV_PGXEVTL_ADTR1EN3_ENABLE 1u) //PGxTRIGCレジスタコンペアイベントをADCトリガ1向け信号源として無効にする
#define PWM_DRV_PGXEVTL_UPDTRG_MANUAL ( 0u ) //ユーザが手動でUPDREQビット(PGxSTAT<3>)をセットする必要がある
#define PWM_DRV_PGXEVTL_UPDTRG_PGXDC ( 1u ) //PGxDCレジスタの書き込み時に自動的にUPDREQビットをセットする
#define PWM_DRV_PGXEVTL_UPDTRG_PGXPHASE ( 2u ) //PGxPHASEレジスタの書き込み時に自動的にUPDREQビットをセットする
#define PWM_DRV_PGXEVTL_UPDTRG_PGXTRIGA ( 3u ) //PGxTRIGAレジスタの書き込み時に自動的にUPDREQビットをセットする
#define PWM_DRV_PGXEVTL_PGTRGSEL_EOC ( 0u ) //EOCイベントがPWMジェネレータトリガ
#define PWM_DRV_PGXEVTL_PGTRGSEL_PGXTRIGA ( 1u ) //PGxTRIGAコンペアイベントがPWMジェネレータトリガ
#define PWM_DRV_PGXEVTL_PGTRGSEL_PGXTRIGB ( 2u ) //PGxTRIGBコンペアイベントがPWMジェネレータトリガ
#define PWM_DRV_PGXEVTL_PGTRGSEL_PGXTRIGC ( 3u ) //PGxTRIGCコンペアイベントがPWMジェネレータトリガ
#define PWM_DRV_PGXEVTH_FLTIEN_DISABLE ( 0u ) //フォルト割り込み無効
#define PWM_DRV_PGXEVTH_FLTIEN_ENABLE ( 1u ) //フォルト割り込み有効
#define PWM_DRV_PGXEVTH_CLIEN_DISABLE ( 0u ) //電流制限割り込み無効
#define PWM_DRV_PGXEVTH_CLIEN_ENABLE ( 1u ) //電流制限割り込み有効
#define PWM_DRV_PGXEVTH_FFIEN_DISABLE ( 0u ) //フィードフォワード割り込み無効
#define PWM_DRV_PGXEVTH_FFIEN_ENABLE ( 1u ) //フィードフォワード割り込み有効
#define PWM_DRV_PGXEVTH_SIEN_DISABLE ( 0u ) //同期割り込み無効
#define PWM_DRV_PGXEVTH_SIEN_ENABLE ( 1u ) //同期割り込み有効
#define PWM_DRV_PGXEVTH_IEVTSEL_EOC ( 0u ) //EOC時にCPUに割り込む
#define PWM_DRV_PGXEVTH_IEVTSEL_TRIGA ( 1u ) //TRIGAコンペアイベント時にCPUに割り込む
#define PWM_DRV_PGXEVTH_IEVTSEL_ADC1 ( 2u ) //ADCトリガ1イベント時にCPUに割り込む
#define PWM_DRV_PGXEVTH_IEVTSEL_TB_DISABLE ( 3u ) //タイムベース割り込みを無効にする
#define PWM_DRV_PGXEVTH_ADTR2EN1_DISABLE ( 0u) //PGxTRIGAレジスタコンペアイベントをADCトリガ2向け信号源として無効にする
#define PWM_DRV_PGXEVTH_ADTR2EN1_ENABLE ( 1u) //PGxTRIGAレジスタコンペアイベントをADCトリガ2向け信号源として無効にする
#define PWM_DRV_PGXEVTH_ADTR2EN2_DISABLE ( 0u) //PGxTRIGBレジスタコンペアイベントをADCトリガ2向け信号源として無効にする
#define PWM_DRV_PGXEVTH_ADTR2EN2_ENABLE ( 1u) //PGxTRIGBレジスタコンペアイベントをADCトリガ2向け信号源として無効にする
#define PWM_DRV_PGXEVTH_ADTR2EN3_DISABLE ( 0u) //PGxTRIGCレジスタコンペアイベントをADCトリガ2向け信号源として無効にする
#define PWM_DRV_PGXEVTH_ADTR2EN3_ENABLE ( 1u) //PGxTRIGCレジスタコンペアイベントをADCトリガ2向け信号源として無効にする
#define DAC_DRV_DACCTRL1L_DACON_DISABLE ( 0u ) /* DAC モジュールを無効にする */
#define DAC_DRV_DACCTRL1L_DACON_ENABLE ( 1u ) /* DAC モジュールを有効にする */
#define DAC_DRV_DACCTRL1L_DACSIDL_CONTINUES ( 0u ) /* アイドル中もモジュールは動作を継続する */
#define DAC_DRV_DACCTRL1L_DACSIDL_STOP ( 1u ) /* デバイスがアイドルに移行した時にモジュールは動作を停止する */
#define DAC_DRV_DACCTRL1L_CLKSEL_AFVCODIV2 ( 0u )
#define DAC_DRV_DACCTRL1L_CLKSEL_FVCODIV2 ( 1u )
#define DAC_DRV_DACCTRL1L_CLKSEL_AFPLLO ( 2u )
#define DAC_DRV_DACCTRL1L_CLKSEL_FPLLO ( 3u )
#define DAC_DRV_DACCTRL1L_CLKDIV_1X1 ( 0u )
#define DAC_DRV_DACCTRL1L_CLKDIV_1X2 ( 1u )
#define DAC_DRV_DACCTRL1L_CLKDIV_1X3 ( 2u )
#define DAC_DRV_DACCTRL1L_CLKDIV_1X4 ( 3u )
#define DAC_DRV_DACCTRL1L_FCLKDIV_1X1 ( 0u )
#define DAC_DRV_DACCTRL1L_FCLKDIV_1X2 ( 1u )
#define DAC_DRV_DACCTRL1L_FCLKDIV_1X3 ( 2u )
#define DAC_DRV_DACCTRL1L_FCLKDIV_1X4 ( 3u )
#define DAC_DRV_DACCTRL1L_FCLKDIV_1X5 ( 4u )
#define DAC_DRV_DACCTRL1L_FCLKDIV_1X6 ( 5u )
#define DAC_DRV_DACCTRL1L_FCLKDIV_1X7 ( 6u )
#define DAC_DRV_DACCTRL1L_FCLKDIV_1X8 ( 7u )
#define DAC_DRV_DACXCONL_DACEN_DISABLE ( 0u ) /* DACxモジュールを無効にする */
#define DAC_DRV_DACXCONL_DACEN_ENABLE ( 1u ) /* DACxモジュールを有効にする */
#define DAC_DRV_DACXCONL_IRQM_DISABLE ( 0u ) /* 割り込みを無効にする */
#define DAC_DRV_DACXCONL_IRQM_RISING_EDGE ( 1u ) /* 立ち上がりエッジ検出時に割り込みを生成する */
#define DAC_DRV_DACXCONL_IRQM_FALLING_EDGE ( 2u ) /* 立ち下がりエッジ検出時に割り込みを生成する */
#define DAC_DRV_DACXCONL_IRQM_BOTH_EDGE ( 3u ) /* 立ち上がり / 立ち下がりエッジ検出時に割り込みを生成する */
#define DAC_DRV_DACXCONL_CBE_DISABLE ( 0u ) /* アナログコンパレータへのブランキング信号を無効にする */
#define DAC_DRV_DACXCONL_CBE_ENABLE ( 1u ) /* スロープ動作完了後の復帰遷移中にアナログコンパレータ出力のブランキング(停止)を有効にする */
#define DAC_DRV_DACXCONL_DACOEN_DISABLE ( 0u ) /* DACxアナログ電圧をDACOUT1ピンに接続しない */
#define DAC_DRV_DACXCONL_DACOEN_ENABLE ( 1u ) /* DACxアナログ電圧をDACOUT1ピンに接続する */
#define DAC_DRV_DACXCONL_FLTREN_DISABLE ( 0u ) /* デジタルフィルタを無効にする */
#define DAC_DRV_DACXCONL_FLTREN_ENABLE ( 1u ) /* デジタルフィルタを有効にする */
#define DAC_DRV_DACXCONL_CMPPOL_NORMAL ( 0u ) /* 出力を反転しない */
#define DAC_DRV_DACXCONL_CMPPOL_INVERT ( 1u ) /* 出力を反転する */
#if (CORE_TYPE == CORE_MASTER)
#define DAC_DRV_DACXCONL_INSEL_CMPXA ( 0u ) /* CMPxA 入力ピン */
#define DAC_DRV_DACXCONL_INSEL_CMPxB ( 1u ) /* CMPxB 入力ピン */
#define DAC_DRV_DACXCONL_INSEL_CMPxD ( 3u ) /* CMPxD 入力ピン */
#define DAC_DRV_DACXCONL_INSEL_SPGA1_OUT ( 4u ) /* SPGA1 出力 */
#define DAC_DRV_DACXCONL_INSEL_SPGA2_OUT ( 5u ) /* SPGA2 出力*/
#else
#define DAC_DRV_INSEL_S1CMPXA ( 0u ) /* S1CMPxA 入力ピン */
#define DAC_DRV_INSEL_S1CMPxB ( 1u ) /* S1CMPxB 入力ピン */
#define DAC_DRV_INSEL_S1CMPxD ( 3u ) /* S1CMPxD 入力ピン */
#define DAC_DRV_INSEL_SPGA1_OUT ( 4u ) /* SPGA1 出力 */
#define DAC_DRV_INSEL_SPGA2_OUT ( 5u ) /* SPGA2 出力*/
#endif
#define DAC_DRV_DACXCONL_HYSPOL_RISING_EDGE ( 0u ) /* 立ち下がりエッジにヒステリシスを適用する */
#define DAC_DRV_DACXCONL_HYSPOL_FALLING_EDGE ( 1u ) /* 立ち上がりエッジにヒステリシスを適用する */
#define DAC_DRV_DACXCONL_HYSSEL_NO ( 0u ) /* ヒステリシスを適用しない */
#define DAC_DRV_DACXCONL_HYSSEL_15MV ( 1u ) /* 15mVのヒステリシス */
#define DAC_DRV_DACXCONL_HYSSEL_30MV ( 2u ) /* 30mVのヒステリシス */
#define DAC_DRV_DACXCONL_HYSSEL_45MV ( 3u ) /* 45mVのヒステリシス */
#define DAC_DRV_SLPXCONH_SLOPEN_DISABLE ( 0u ) /* スロープ機能を無効にする */
#define DAC_DRV_SLPXCONH_SLOPEN_ENABLE ( 1u ) /* スロープ機能を有効にする */
#define DAC_DRV_SLPXCONH_HME_DISABLE ( 0u ) /* DACx のヒステリシス モードを無効にする */
#define DAC_DRV_SLPXCONH_HME_ENABLE ( 1u ) /* DACx のヒステリシス モードを有効にする */
#define DAC_DRV_SLPXCONH_TWME_DISABLE ( 0u ) /* DACx の三角波モードを無効にする */
#define DAC_DRV_SLPXCONH_TWME_ENABLE ( 1u ) /* DACx の三角波モードを有効にする */
#define DAC_DRV_SLPXCONH_PSE_DEC ( 0u ) /* スロープモードは負 ( 減少 ) */
#define DAC_DRV_SLPXCONH_PSE_ADD ( 1u ) /* スロープモードは正 ( 増加 ) */
#define DAC_DRV_SLPXCONL_HCFSEL_0 ( 0u ) /* 0 */
#define DAC_DRV_SLPXCONL_HCFSEL_PWM1H ( 1u ) /* PWM1H */
#define DAC_DRV_SLPXCONL_HCFSEL_PWM2H ( 2u ) /* PWM2H */
#define DAC_DRV_SLPXCONL_HCFSEL_PWM3H ( 3u ) /* PWM3H */
#define DAC_DRV_SLPXCONL_HCFSEL_PWM4H ( 4u ) /* PWM4H */
#define DAC_DRV_SLPXCONL_HCFSEL_S1PWM1H ( 5u ) /* S1PWM1H*/
#define DAC_DRV_SLPXCONL_HCFSEL_S1PWM2H ( 6u ) /* S1PWM2H */
#define DAC_DRV_SLPXCONL_HCFSEL_S1PWM3H ( 7u ) /* S1PWM3H */
#define DAC_DRV_SLPXCONL_HCFSEL_S1PWM4H ( 8u ) /* S1PWM4H*/
#define DAC_DRV_SLPXCONL_HCFSEL_1 ( 15u ) /* 1 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_0 ( 0u ) /* 0 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_PWM1TRG1 ( 1u ) /* Master PWM1 Trigger 1 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_PWM2TRG1 ( 2u ) /* Master PWM2 Trigger 1 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_PWM3TRG1 ( 3u ) /* Master PWM3 Trigger 1 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_PWM4TRG1 ( 4u ) /* Master PWM4 Trigger 1 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_PWM1TRG2 ( 5u ) /* Master PWM1 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_PWM2TRG2 ( 6u ) /* Master PWM2 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_PWM3TRG2 ( 7u ) /* Master PWM3 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_PWM4TRG2 ( 8u ) /* Master PWM4 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_S1PWM1TRG2 ( 13u ) /* Slave PWM1 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_S1PWM2TRG2 ( 14u ) /* Slave PWM2 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTOPA_1 ( 15u ) /* 1 */
#define DAC_DRV_SLPXCONL_SLPSTOPB_0 ( 0u ) /* 0 */
#define DAC_DRV_SLPXCONL_SLPSTOPB_CMP1 ( 1u ) /* CMP1 Out */
#define DAC_DRV_SLPXCONL_SLPSTOPB_S1CMP1 ( 2u ) /* S1CMP1 Out */
#define DAC_DRV_SLPXCONL_SLPSTOPB_S1CMP2 ( 3u ) /* S1CMP2 Out */
#define DAC_DRV_SLPXCONL_SLPSTOPB_S1CMP3 ( 4u ) /* S1CMP3 Out */
#define DAC_DRV_SLPXCONL_SLPSTOPB_1 ( 15u ) /* 1 */
#define DAC_DRV_SLPXCONL_SLPSTRT_0 ( 0u ) /* 0 */
#define DAC_DRV_SLPXCONL_SLPSTRT_PWM1TRG1 ( 1u ) /* Master PWM1 Trigger 1 */
#define DAC_DRV_SLPXCONL_SLPSTRT_PWM2TRG1 ( 2u ) /* Master PWM2 Trigger 1 */
#define DAC_DRV_SLPXCONL_SLPSTRT_PWM3TRG1 ( 3u ) /* Master PWM3 Trigger 1 */
#define DAC_DRV_SLPXCONL_SLPSTRT_PWM4TRG1 ( 4u ) /* Master PWM4 Trigger 1 */
#define DAC_DRV_SLPXCONL_SLPSTRT_PWM1TRG2 ( 5u ) /* Master PWM1 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTRT_PWM2TRG2 ( 6u ) /* Master PWM2 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTRT_PWM3TRG2 ( 7u ) /* Master PWM3 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTRT_PWM4TRG2 ( 8u ) /* Master PWM4 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTRT_S1PWM1TRG2 ( 13u ) /* Slave PWM1 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTRT_S1PWM2TRG2 ( 14u ) /* Slave PWM2 Trigger 2 */
#define DAC_DRV_SLPXCONL_SLPSTRT_1 ( 15u ) /* 1 */
#define PWM_DRV_PGxyPCIL_TSYNCDIS_PWM_EOC ( 0u)
#define PWM_DRV_PGxyPCIL_TSYNCDIS_PWM_IMMED ( 1u)
#define PWM_DRV_PGxyPCIL_TERM_MANUAL ( 0u)
#define PWM_DRV_PGxyPCIL_TERM_AUTO ( 1u)
#define PWM_DRV_PGxyPCIL_TERM_TRIGA ( 2u)
#define PWM_DRV_PGxyPCIL_TERM_TRIGB ( 3u)
#define PWM_DRV_PGxyPCIL_TERM_TRIGC ( 4u)
#define PWM_DRV_PGxyPCIL_TERM_PCI1 ( 5u)
#define PWM_DRV_PGxyPCIL_TERM_PCI8 ( 6u)
#define PWM_DRV_PGxyPCIL_TERM_PCI9 ( 7u)
#define PWM_DRV_PGxyPCIL_AQPS_NOT_INVERT ( 0u)
#define PWM_DRV_PGxyPCIL_AQPS_INVERT ( 1u)
#define PWM_DRV_PGxyPCIL_AQSS_MANUAL ( 0u)
#define PWM_DRV_PGxyPCIL_AQSS_DUTY_ACTIVE ( 1u)
#define PWM_DRV_PGxyPCIL_AQSS_LEB_ACTIVE ( 2u)
#define PWM_DRV_PGxyPCIL_AQSS_PWM_GEN_TRIG ( 3u)
#define PWM_DRV_PGxyPCIL_AQSS_PCI1 ( 4u)
#define PWM_DRV_PGxyPCIL_AQSS_PCI8 ( 5u)
#define PWM_DRV_PGxyPCIL_AQSS_PCI9 ( 6u)
#define PWM_DRV_PGxyPCIL_AQSS_SWPCI ( 7u)
#define PWM_DRV_PGxyPCIL_PSYNC_NOT_PWM_EOC ( 0u)
#define PWM_DRV_PGxyPCIL_PSYNC_PWM_EOC ( 1u)
#define PWM_DRV_PGxyPCIL_PPS_NOT_INVERT ( 0u)
#define PWM_DRV_PGxyPCIL_PPS_INVERT ( 1u)
#define PWM_DRV_PGxyPCIL_PSS_0 ( 0u)
#define PWM_DRV_PGxyPCIL_PSS_PWMPCI_MUX ( 1u)
#define PWM_DRV_PGxyPCIL_PSS_COMBO_TRIGA ( 2u)
#define PWM_DRV_PGxyPCIL_PSS_COMBO_TRIGB ( 3u)
#define PWM_DRV_PGxyPCIL_PSS_PCI8R ( 8u)
#define PWM_DRV_PGxyPCIL_PSS_PCI9R ( 8u)
#define PWM_DRV_PGxyPCIL_PSS_PCI10R ( 10u)
#define PWM_DRV_PGxyPCIL_PSS_PCI11R ( 11u)
#define PWM_DRV_PGxyPCIL_PSS_PCI12R ( 12u)
#define PWM_DRV_PGxyPCIL_PSS_PCI13R ( 13u)
#define PWM_DRV_PGxyPCIL_PSS_PCI14R ( 14u)
#define PWM_DRV_PGxyPCIL_PSS_PCI15R ( 15u)
#define PWM_DRV_PGxyPCIL_PSS_PCI16R ( 16u)
#define PWM_DRV_PGxyPCIL_PSS_PCI17R ( 17u)
#define PWM_DRV_PGxyPCIL_PSS_PCI18R ( 18u)
#define PWM_DRV_PGxyPCIL_PSS_PCI19R ( 19u)
#define PWM_DRV_PGxyPCIL_PSS_PCI20R ( 20u)
#define PWM_DRV_PGxyPCIL_PSS_PCI21R ( 21u)
#define PWM_DRV_PGxyPCIL_PSS_PCI22R ( 22u)
#define PWM_DRV_PGxyPCIL_PSS_PWMSEVENT_C ( 23u)
#define PWM_DRV_PGxyPCIL_PSS_PWMSEVENT_D ( 24u)
#define PWM_DRV_PGxyPCIL_PSS_PWMSEVENT_E ( 25u)
#define PWM_DRV_PGxyPCIL_PSS_PWMSEVENT_F ( 26u)
#define PWM_DRV_PGxyPCIL_PSS_MCOMP1 ( 27u)
#define PWM_DRV_PGxyPCIL_PSS_SCOMP1 ( 28u)
#define PWM_DRV_PGxyPCIL_PSS_SCOMP2 ( 29u)
#define PWM_DRV_PGxyPCIL_PSS_SCOMP3 ( 30u)
#define PWM_DRV_PGxyPCIL_PSS_CLC1 ( 31u)
#define PWM_DRV_PGxyPCIH_BPEN_DISABLE ( 0u)
#define PWM_DRV_PGxyPCIH_BPEN_ENABLE ( 1u)
#define PWM_DRV_PGxyPCIH_BPSEL_PWM1 ( 0u)
#define PWM_DRV_PGxyPCIH_BPSEL_PWM2 ( 1u)
#define PWM_DRV_PGxyPCIH_BPSEL_PWM3 ( 2u)
#define PWM_DRV_PGxyPCIH_BPSEL_PWM4 ( 3u)
#define PWM_DRV_PGxyPCIH_BPSEL_PWM5 ( 4u)
#define PWM_DRV_PGxyPCIH_BPSEL_PWM6 ( 5u)
#define PWM_DRV_PGxyPCIH_BPSEL_PWM7 ( 6u)
#define PWM_DRV_PGxyPCIH_BPSEL_PWM8 ( 7u)
#define PWM_DRV_PGxyPCIH_ACP_LEVEL ( 0u)
#define PWM_DRV_PGxyPCIH_ACP_RISE_EDGE ( 1u)
#define PWM_DRV_PGxyPCIH_ACP_ANY_EDGE ( 2u)
#define PWM_DRV_PGxyPCIH_ACP_LATCH ( 3u)
#define PWM_DRV_PGxyPCIH_ACP_LATCH_RISE_EDGE ( 4u)
#define PWM_DRV_PGxyPCIH_ACP_LATCH_ANY_EDGE ( 5u)
#define PWM_DRV_PGxyPCIH_SWPCI_DISABLE ( 0u)
#define PWM_DRV_PGxyPCIH_SWPCI_ENABLE ( 1u)
#define PWM_DRV_PGxyPCIH_SWPCIM_PCI_ACCPT ( 0u)
#define PWM_DRV_PGxyPCIH_SWPCIM_ACCPT_QUAL ( 1u)
#define PWM_DRV_PGxyPCIH_SWPCIM_TERM_QUAL ( 2u)
#define PWM_DRV_PGxyPCIH_LATMODE_SET_DOMI ( 0u)
#define PWM_DRV_PGxyPCIH_LATMODE_RESET_DOMI ( 1u)
#define PWM_DRV_PGxyPCIH_TQPS_NOT_INVERT ( 0u)
#define PWM_DRV_PGxyPCIH_TQPS_INVERT ( 1u)
#define PWM_DRV_PGxyPCIH_TQSS_1 ( 0u)
#define PWM_DRV_PGxyPCIH_TQSS_DUTY_ACTIVE ( 1u)
#define PWM_DRV_PGxyPCIH_TQSS_LEB_ACTIVE ( 2u)
#define PWM_DRV_PGxyPCIH_TQSS_PWM_GEN_TRIG ( 3u)
#define PWM_DRV_PGxyPCIH_TQSS_PCI1 ( 4u)
#define PWM_DRV_PGxyPCIH_TQSS_PCI8 ( 5u)
#define PWM_DRV_PGxyPCIH_TQSS_PCI9 ( 6u)
#define PWM_DRV_PGxyPCIH_TQSS_SWPCI ( 7u)
#define HRPWM_PCI_NO_USE 0
#define HRPWM_PCI_LEVEL 1
#define HRPWM_PCI_LATCH_TERM 2
#define HRPWM_PCI_MODE HRPWM_PCI_LATCH_TERM
/*----------------------------------------------------------------------------*/
/* 変数定義*/
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* クロック設定 */
/*----------------------------------------------------------------------------*/
//ここにクロック設定ソースを挿入する//
/*----------------------------------------------------------------------------*/
/* Main関数 */
/*----------------------------------------------------------------------------*/
int main(int argc, char** argv)
{
/*------------------------------------------------------------------------*/
/* クロック初期化*/
/*------------------------------------------------------------------------*/
vds_Main_Init_Clock_Register(); /* クロック初期化 */
/*------------------------------------------------------------------------*/
/* GPIO初期化*/
/*------------------------------------------------------------------------*/
ANSELBbits.ANSELB2 = 1u; /* RB2ピンはアナログピン(DACOUT1) */
ANSELAbits.ANSELA0 = 1u; /* RA0ピンはアナログピン(ポテンション入力)*/
/*------------------------------------------------------------------------*/
/* リマッパブルピン初期化*/
/*------------------------------------------------------------------------*/
RPOR5bits.RP43R = 0x17u; /* CMP1]出力 */
/*------------------------------------------------------------------------*/
/* PWM初期化*/
/*------------------------------------------------------------------------*/
PG1CONLbits.ON = 0u;
/*------------------------------------------------------------------------*/
/* PWMクロックの設定*/
/*------------------------------------------------------------------------*/
PCLKCONbits.MCLKSEL = 3u; /* Auxiliary PLL post-divider output*/
/*------------------------------------------------------------------------*/
/* PGx制御レジスタLの設定*/
/*------------------------------------------------------------------------*/
PG1CONLbits.CLKSEL = 1u;
PG1CONLbits.MODSEL = 0u;
/*------------------------------------------------------------------------*/
/* PGx制御レジスタHの設定*/
/* 周期はマスターピリオドレジスタ(MPER)を使用*/
/*------------------------------------------------------------------------*/
PG1CONH = 0x0000;
/*------------------------------------------------------------------------*/
/* PGxIOレジスタHの設定*/
/* PWMジェネレータがピンを使用する*/
/*------------------------------------------------------------------------*/
PG1IOCONH = 0x000C;
/*------------------------------------------------------------------------*/
/* PGxIOレジスタLの設定*/
/* PCI電流リミットが発生した時にCLDATの値を使用*/
/* CLDAT = PWMxHがLow,PWMxLがHigh*/
/*------------------------------------------------------------------------*/
PG1IOCONL = 0x0000;
PG1IOCONLbits.CLDAT = 0u;
/*------------------------------------------------------------------------*/
/* 周期/Duty/フェーズの設定*/
/*------------------------------------------------------------------------*/
PG1PER = 4999;
PG1DC = 3999; /* PG3 Dutyレジスタ*/
PG1PHASE = 0;
PG1TRIGA = 200;
PG1TRIGB = 3999;
PG1TRIGC = 2999;
/*------------------------------------------------------------------------*/
/* デッドタイムの設定*/
/*------------------------------------------------------------------------*/
PG1DTH = 10;
PG1DTL = 10;
/*------------------------------------------------------------------------*/
/* ブランキングの設定*/
/* PWMxHの立ち上がりでLEBカウンタをクリアする*/
/*------------------------------------------------------------------------*/
PG1LEBH = 0x0008u;
PG1LEBL = 1000u;
/*------------------------------------------------------------------------*/
/* PCI電流制御レジスタHの設定*/
/*------------------------------------------------------------------------*/
PG1CLPCIH = 0x0300;
/*------------------------------------------------------------------------*/
/* イベントレジスタの設定*/
/*------------------------------------------------------------------------*/
PG1EVTL = 0x0118; /* Trigger1 updated by TrigA, Auto update of UPTRG */
PG1EVTLbits.ADTR1PS = 0u;
PG1EVTLbits.ADTR1EN3 = PWM_DRV_PGXEVTL_ADTR1EN3_DISABLE;
PG1EVTLbits.ADTR1EN2 = PWM_DRV_PGXEVTL_ADTR1EN2_DISABLE;
PG1EVTLbits.ADTR1EN1 = PWM_DRV_PGXEVTL_ADTR1EN1_ENABLE;
PG1EVTLbits.UPDTRG = PWM_DRV_PGXEVTL_UPDTRG_PGXTRIGA;
PG1EVTLbits.PGTRGSEL = PWM_DRV_PGXEVTL_PGTRGSEL_EOC;
PG1EVTH = 0x0340; /* Trigger1 updated by TrigB, Disable interrupts */
PG1EVTHbits.FLTIEN = PWM_DRV_PGXEVTH_FLTIEN_DISABLE;
PG1EVTHbits.CLIEN = PWM_DRV_PGXEVTH_CLIEN_DISABLE;
PG1EVTHbits.FFIEN = PWM_DRV_PGXEVTH_FFIEN_DISABLE;
PG1EVTHbits.SIEN = PWM_DRV_PGXEVTH_SIEN_DISABLE;
PG1EVTHbits.IEVTSEL = PWM_DRV_PGXEVTH_IEVTSEL_TB_DISABLE;
PG1EVTHbits.ADTR2EN3 = PWM_DRV_PGXEVTH_ADTR2EN3_DISABLE;
PG1EVTHbits.ADTR2EN2 = PWM_DRV_PGXEVTH_ADTR2EN2_ENABLE;
PG1EVTHbits.ADTR2EN1 = PWM_DRV_PGXEVTH_ADTR2EN1_DISABLE;
PG1EVTHbits.ADTR1OFS = 0u;
#if (HRPWM_PCI_MODE == HRPWM_PCI_LEVEL) || (HRPWM_PCI_MODE == HRPWM_PCI_LATCH_TERM )
/*------------------------------------------------------------------------*/
/* PGx過電流制限PCIレジスタLow */
/*------------------------------------------------------------------------*/
PG1CLPCIL = 0x0000u;
PG1CLPCILbits.PSS = PWM_DRV_PGxyPCIL_PSS_MCOMP1;
PG1CLPCILbits.PPS = PWM_DRV_PGxyPCIL_PPS_NOT_INVERT;
PG1CLPCILbits.PSYNC = PWM_DRV_PGxyPCIL_PSYNC_NOT_PWM_EOC;
PG1CLPCILbits.SWTERM = 0u;
PG1CLPCILbits.AQSS = PWM_DRV_PGxyPCIL_AQSS_LEB_ACTIVE;
PG1CLPCILbits.AQPS = PWM_DRV_PGxyPCIL_AQPS_INVERT;
PG1CLPCILbits.TERM = PWM_DRV_PGxyPCIL_TERM_AUTO;
PG1CLPCILbits.TSYNCDIS = PWM_DRV_PGxyPCIL_TSYNCDIS_PWM_EOC;
/*------------------------------------------------------------------------*/
/* PGx過電流制限PCIレジスタHigh */
/*------------------------------------------------------------------------*/
PG1CLPCIH = 0x0000u;
PG1CLPCIHbits.TQSS = PWM_DRV_PGxyPCIH_TQSS_1;
PG1CLPCIHbits.TQPS = PWM_DRV_PGxyPCIH_TQPS_NOT_INVERT;
PG1CLPCIHbits.LATMOD = PWM_DRV_PGxyPCIH_LATMODE_SET_DOMI;
PG1CLPCIHbits.SWPCIM = PWM_DRV_PGxyPCIH_SWPCIM_TERM_QUAL;
PG1CLPCIHbits.SWPCI = PWM_DRV_PGxyPCIH_SWPCI_DISABLE;
PG1CLPCIHbits.ACP = PWM_DRV_PGxyPCIH_ACP_LEVEL;
PG1CLPCIHbits.BPSEL = PWM_DRV_PGxyPCIH_BPSEL_PWM1;
PG1CLPCIHbits.BPEN = PWM_DRV_PGxyPCIH_BPEN_DISABLE;
#endif
#if (HRPWM_PCI_MODE == HRPWM_PCI_LATCH_TERM )
PG1CLPCIHbits.ACP = PWM_DRV_PGxyPCIH_ACP_LATCH_RISE_EDGE;
PG1CLPCILbits.TERM = PWM_DRV_PGxyPCIL_TERM_TRIGC;
PG1CLPCILbits.TSYNCDIS = PWM_DRV_PGxyPCIL_TSYNCDIS_PWM_IMMED;
#endif
/*------------------------------------------------------------------------*/
/* PWMの有効化*/
/*------------------------------------------------------------------------*/
PG1CONLbits.ON = 1u;
/*------------------------------------------------------------------------*/
/* DAC制御1Lレジスタの設定*/
/*------------------------------------------------------------------------*/
DACCTRL1L = 0x0000u;
DACCTRL1Lbits.DACON = DAC_DRV_DACCTRL1L_DACON_DISABLE;
DACCTRL1Lbits.DACSIDL = DAC_DRV_DACCTRL1L_DACSIDL_CONTINUES;
DACCTRL1Lbits.CLKSEL = DAC_DRV_DACCTRL1L_CLKSEL_AFVCODIV2;
DACCTRL1Lbits.CLKDIV = DAC_DRV_DACCTRL1L_CLKDIV_1X1;
DACCTRL1Lbits.FCLKDIV = DAC_DRV_DACCTRL1L_FCLKDIV_1X1;
/*------------------------------------------------------------------------*/
/* DAC制御2Hレジスタの設定*/
/*------------------------------------------------------------------------*/
DACCTRL2H = 0x3FF; //8A
/*------------------------------------------------------------------------*/
/* DAC制御2Lレジスタの設定*/
/*------------------------------------------------------------------------*/
DACCTRL2L = 0x1F0; //55
/*------------------------------------------------------------------------*/
/* DAC1制御Hレジスタの設定*/
/*------------------------------------------------------------------------*/
DAC1CONH = 0x0000u;
DAC1CONHbits.TMCB = 0;
/*------------------------------------------------------------------------*/
/* DAC1制御Lレジスタの設定*/
/*------------------------------------------------------------------------*/
DAC1CONL = 0x0000u;
DAC1CONLbits.DACEN = DAC_DRV_DACXCONL_DACEN_DISABLE;
DAC1CONLbits.IRQM = DAC_DRV_DACXCONL_IRQM_DISABLE;
DAC1CONLbits.CBE = DAC_DRV_DACXCONL_CBE_DISABLE;
DAC1CONLbits.DACOEN = DAC_DRV_DACXCONL_DACOEN_ENABLE;
DAC1CONLbits.FLTREN = DAC_DRV_DACXCONL_FLTREN_DISABLE;
DAC1CONLbits.CMPPOL = DAC_DRV_DACXCONL_CMPPOL_INVERT;
DAC1CONLbits.INSEL = DAC_DRV_DACXCONL_INSEL_CMPXA;
DAC1CONLbits.HYSPOL = DAC_DRV_DACXCONL_HYSPOL_RISING_EDGE;
DAC1CONLbits.HYSSEL = DAC_DRV_DACXCONL_HYSSEL_NO;
/*------------------------------------------------------------------------*/
/* DAC値レジスタの設定*/
/*------------------------------------------------------------------------*/
DAC1DATH = 0xFFF;
DAC1DATL = 0x000;
/*------------------------------------------------------------------------*/
/* SLP制御レジスタHレジスタの設定*/
/*------------------------------------------------------------------------*/
SLP1CONH = 0x0000u;
SLP1CONHbits.HME = DAC_DRV_SLPXCONH_HME_DISABLE;
SLP1CONHbits.PSE = DAC_DRV_SLPXCONH_PSE_ADD;
SLP1CONHbits.TWME = DAC_DRV_SLPXCONH_TWME_DISABLE;
SLP1CONHbits.SLOPEN = DAC_DRV_SLPXCONH_SLOPEN_ENABLE;
/*------------------------------------------------------------------------*/
/* SLP制御レジスタLの設定*/
/*------------------------------------------------------------------------*/
SLP1CONL = 0x0000u;
SLP1CONLbits.HCFSEL = DAC_DRV_SLPXCONL_HCFSEL_0;
SLP1CONLbits.SLPSTOPA = DAC_DRV_SLPXCONL_SLPSTOPA_PWM1TRG2;
SLP1CONLbits.SLPSTOPB = DAC_DRV_SLPXCONL_SLPSTOPB_0;
SLP1CONLbits.SLPSTRT = DAC_DRV_SLPXCONL_SLPSTRT_PWM1TRG1;
/*------------------------------------------------------------------------*/
/* スロープデータレジスタの設定*/
/*------------------------------------------------------------------------*/
SLP1DAT = 20u;
DAC1CONLbits.DACEN = DAC_DRV_DACXCONL_DACEN_ENABLE; /* Enable Master DAC 1 */
DACCTRL1Lbits.DACON = DAC_DRV_DACCTRL1L_DACON_ENABLE; /* Turn ON all Master DACs */
/*------------------------------------------------------------------------*/
/* メインルーチン*/
/*------------------------------------------------------------------------*/
while(1)
{
}
}
結果
まずは以下のマクロを「HRPWM_PCI_NO_USE」に書き換え、PCI機能を無効にします。
#define HRPWM_PCI_MODE HRPWM_PCI_NO_USE
スロープ(Ch2/水色)電圧がポテンション電圧(Ch3/マゼンタ)を超えたタイミングでコンパレータの出力(Ch4/緑)が変化しています。この時PWMに変化は有りません。

次に以下のマクロを「HRPWM_PCI_LEVEL」に書き換え、PCIをレベル動作させます。
#define HRPWM_PCI_MODE HRPWM_PCI_LEVEL
スロープ電圧がポテンション電圧を超えたタイミングでPWMがゲートされてLowレベルに変化しています。

ポテンション電圧を低下させていくと、それに追従してコンパレータの反応タイミングでPWMがLowレベルに変化しています。

更にポテンション電圧を低下させていくと、コンパレータの動作はするものの、PWMのゲート動作がトリップします。これはリーディングエッジブランキング機能によりPWMHの立ち上がりから指定期間はPCIソース入力をブランキングしている為です。

次にPCI機能をラッチモードにします。
ここでは敢えてトリッキーな事を実験します。
#define HRPWM_PCI_MODE HRPWM_PCI_LATCH_TERM
これまでと同様スロープ電圧がポテンション電圧を超えたタイミングでPWMがゲートされてLowレベルに変化していますが、PWM周期の途中で再度PWMがHighレベルに変化しています。
この動作は以下の設定をする事でコンパレータの立ち上がりでPCIをラッチし、TRIGCのタイミングでラッチを解除している為です。
PG1CLPCIHbits.ACP = PWM_DRV_PGxyPCIH_ACP_LATCH_RISE_EDGE;
PG1CLPCILbits.TERM = PWM_DRV_PGxyPCIL_TERM_TRIGC;
PG1CLPCILbits.TSYNCDIS = PWM_DRV_PGxyPCIL_TSYNCDIS_PWM_IMMED;
このような波形が必要になるアプリケーションが有るのかは不明ですが、PCI機能はソフトウェアで実現不可能な速度で瞬時的な動作を可能とします。



コメント