高分解能PWMモジュールの使い方1

dsPIC33C

概要

dsPIC33CHシリーズには高分解能PWMモジュールが最大8チャンネルペア搭載されています。
最小分解能は250psecですので、通常のマイコンやFPGAでは不可能であった高速、高分解能アプリケーションが可能です。

高分解能PWMの主なアプリケーション

•AC/DCコンバータ
•DC/DCコンバータ
•ACおよびDCモータ制御: ブラシ付きDC、BLDC、PMSM、ACIM、SRM、ステッピングモータ等
•インバータ
•バッテリ充電
•デジタル照明
•力率改善回路(PFC)

主な特徴としては以下の様な電源やモータ制御に特化した機能を備えております。

主な機能

最大8個の独立したPWMジェネレータ(各ジェネレータは2出力を備える)
•動作モード:
–独立エッジPWMモード
–可変位相PWMモード
–独立エッジPWMモード(2出力)
–センターアラインPWMモード
–2回更新センターアラインPWMモード
–両エッジセンターアラインPWMモード
•出力モード:
–相補出力モード
–独立出力モード
–プッシュプル出力モード
•デッドタイムジェネレータ
•デッドタイム補償
•リーディングエッジブランキング(LEB)•出力オーバーライド
• 柔軟な周期/デューティサイクル更新オプション
• PWMピンオーバーライドと外部PWM同期のためのPWM制御入力(PCI)
• 詳細なトリガオプション
• 組み合わせロジック出力
• PWMイベント出力

詳細なリファレンスマニュアルはこちら

PWMモジュールの全体像は以下の通りで各PWMジェネレータ(PGx)の前に共通のクロック制御ブロックが存在します。これによりPGx間でタイミングの同期などを行います。

(fig.1)PWMモジュール全体構成 DS70005371D-page 494より抜粋

共通クロックは以下の通りでクロックソースのそのまま、クロックソースを分周、周波数スケーリングしたクロックから選択が可能です。

(fig.2)PWMジェネレータマスタークロック

各PWMジェネレータはマスタークロックをベースに周期、Duty、位相、各トリガ、フォルトなどの設定・状態によりPWMを生成します。

(fig.3)PWMジェネレータ構成

ハードウェア構成と制御ブロック

今回のプログラムはPG2から相補PWMを出力します。(RB12,RB13ピン)

(fig.4) dsPIC33CH Curiosityボード外観

レジスタ

関連レジスタに関しては非常に多いため、今回の動作に関係する部分だけ抜粋します。

レジスタ名機能説明
PCLKCONPWM CLOCK CONTROL REGISTERPWMクロックを制御
PGxCONLGENERATOR x CONTROL REGISTER LOWPGxのクロックや動作モードの設定を行います
PGxIOCONHPWM GENERATOR x I/O CONTROL REGISTER LOWPGxの出力ピンに関する設定を行います
PGxPERPWM GENERATOR x PERIOD REGISTERPGxの周期を設定します
PGxDCPWM GENERATOR x DUTY CYCLE REGISTERPGxのデューティを設定します
PGxDTH
PGxDTL
PWM GENERATOR x DEAD-TIME REGISTERPGxのデッドタイムを設定します
PGxEVTLPWM GENERATOR x EVENT REGISTER LOWPGxのイベントに関する設定を行います
(fig.3)高分解能PWM関連レジスタ

ソースコード

下記のPG2CONLbits.HRENを1に設定すると高分解能モードになり、500MHzのクロックに対し8倍の分解能(=250psec)が得られます。

PG2CONLbits.HREN = PWM_RESOLUTION_HIGH;

PG2PERが周期レジスタです。PWMの周期を1MHzに設定する時の設定値は 500MHz * 8 / 1MHz = 4000 となります。つまり1MHzであっても0.025%でのDuty分解能があります。

コンフィグレーション設定について

コンフィグレーション設定についてはコンフィグレーション設定に記載しております。

コピーして下記のソースコードの「 //ここにコンフィグレーション設定を挿入する// 」の位置に挿入してください。

クロック設定について

クロック設定用関数 vds_Main_Init_Clock_Register(); のソースコードはクロック設定のページに記載しております。

コピーして下記のソースコードの「 //ここにクロック設定ソースをコピペする// 」の位置に挿入してください。

/*----------------------------------------------------------------------------*/
/* <Chapter>        CHAPTER_2_8_1_HRPWM */
/* <Function>       高分解能PWMを出力 */
/* <Peripharal>     PWM関連 */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* コンフィグレーション設定*/
/*----------------------------------------------------------------------------*/
//ここにコンフィグレーション設定を挿入する//
/*----------------------------------------------------------------------------*/
/* インクルードファイル*/
/*----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
/*----------------------------------------------------------------------------*/
/* 定数定義*/
/*----------------------------------------------------------------------------*/
#define PWM_RESOLUTION_NORMAL   ( 0u )
#define PWM_RESOLUTION_HIGH     ( 1u )

#define PWM_RESOLUTION_MODE     PWM_RESOLUTION_HIGH
/*----------------------------------------------------------------------------*/
/* 変数定義*/
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* クロック設定 */
/*----------------------------------------------------------------------------*/
//ここにクロック設定ソースを挿入する//
/*----------------------------------------------------------------------------*/
/* Main関数 */
/*----------------------------------------------------------------------------*/
int main(int argc, char** argv) 
{
    /*------------------------------------------------------------------------*/
    /* クロック初期化*/
    /*------------------------------------------------------------------------*/
        vds_Main_Init_Clock_Register();     /* クロック初期化 */
    /*------------------------------------------------------------------------*/
    /* GPIO初期化*/
    /*------------------------------------------------------------------------*/
    /*------------------------------------------------------------------------*/
    /* PWM初期化*/
    /*------------------------------------------------------------------------*/
        PG2CONLbits.ON = 0u;
    /*------------------------------------------------------------------------*/
    /* PWMクロックの設定*/
    /*------------------------------------------------------------------------*/
        PCLKCONbits.MCLKSEL = 1u;    /* AFPLLO*/
    /*------------------------------------------------------------------------*/
    /* PGx制御レジスタLの設定*/
    /*      周期はマスターピリオドレジスタ(MPER)を使用*/
    /*------------------------------------------------------------------------*/
        PG2CONLbits.CLKSEL = 1u;    /* PWM ジェネレータは、MCLKSELの設定に従う */
        PG2CONLbits.MODSEL = 0u;    /* 独立エッジ PWM モード */
        PG2CONLbits.HREN = PWM_RESOLUTION_HIGH;      /* PWM ジェネレータ1の分解能モード */
    /*------------------------------------------------------------------------*/
    /* PGxIOレジスタHの設定*/
    /*      PWMジェネレータがピンを使用する*/
    /*------------------------------------------------------------------------*/
        PG2IOCONH = 0x000C;
    /*------------------------------------------------------------------------*/
    /* 周期/Duty/フェーズの設定*/
    /*------------------------------------------------------------------------*/
        PG2PER = 4000;        /* 周期レジスタ */
        PG2DC = PG2PER >> 1u; /* PG2 Dutyレジスタ*/
    /*------------------------------------------------------------------------*/
    /* デッドタイムの設定*/
    /*------------------------------------------------------------------------*/
        PG2DTH = 100;
        PG2DTL = 100;
    /*------------------------------------------------------------------------*/
    /* デッドタイムの設定*/
    /*------------------------------------------------------------------------*/
        PG2EVTLbits.UPDTRG = 1u; //PGxDCレジスタの書き込み時に自動的にUPDREQビットをセットする
    /*------------------------------------------------------------------------*/
    /* PWMの有効化*/
    /*------------------------------------------------------------------------*/
        PG2CONLbits.ON = 1u;
    /*------------------------------------------------------------------------*/
    /* メインルーチン*/
    /*------------------------------------------------------------------------*/
        while(1)
        {     
        }
}

結果

PG2から相補出力を行いました。1MHzのPWMでデッドタイムが 25nsecで出力が出来ています。

(fig.5)高分解能PWM出力結果

参考

コメント

タイトルとURLをコピーしました