PICのPSMCを試してみる 単相PWM

投稿日 2016/12/24

新しいPICマイコンに搭載されているPSMC(Programmable Switch Mode Controller)を試してみました。PSMCは多機能な16ビットのパルス幅変調器(PWM)です。今回は簡単にPSMCの解釈をした後、12種類のPWMのうち最も単純な単相PWM信号を作ってみました。

 

なお、PSMCにはマイクロチップ社から日本語訳のアプリケーションノートAN1468が公開されています。(ただしほとんどモードの説明だけです)

 

PSMCは従来のPICに搭載されていたCCP/ECCPを強化したような機能で、多種多様なPWM信号が作り出せる機能で、一度設定すればCPUとは独立に動作します。8Bit PICの16F178xシリーズに搭載されています。

 

PSMCは多機能ですので、いかんせん設定しなければならないレジスタ等が多く、データシートやアプリケーションノートを見ながら意図したパルスが出せるようになるまで一苦労します。このためmicrochip社はPSMC designerを公開していますが、今回は使っていません。

 

今回は手持ちのPIC 16F1783(秋月電子で入手可)を使って、PSMCのもつ各種PWM信号生成機能のうち単相PWMを確認してみました。16F1783はPSMCのほか、12/10ビットADコンバータや、FVR、高速コンパレータ、DAC、OPアンプなどを搭載する高機能8ビットマイコンです。

まず、PSMCで生成できるPWM信号モードの種類ですが、

 

○単相PWM

○相補PWM

○プッシュプルPWM

○相補出力を備えたプッシュプルPWM

○4系統フルブリッジ出力を備えたプッシュプルPWM

○4系統フルブリッジ出力と相補出力を備えたプッシュプルPWM

○パルススキッピングPWM

○相補出力を備えたパルススキッピングPWM

○ECCP互換フルブリッジPWM

○可変周波数-固定デューティサイクルPWM

○相補出力を備えた可変周波数-固定デューティサイクルPWM

○3相PWM

 

の計12種類が可能で、さまざまなアプリケーション(DC-DCコンバータ、インバータ、モーター制御、調光など)に対応します。

 

回路ブロックは以下のようになっており、基本はクロック源と16ビットのカウンタ、周期イベント、立上がりイベント、立下りイベントを制御するレジスタです。出力端子はAからFの6本あり、モードによって使い分けます。

PSMC_01.jpg

PSMCのブロック図

Microchip社 PIC 16F1783のデータシートより抜粋

 

ブロック図を見るとかなり複雑な構造になっていますが、タイムベースでの動作が基本です。それはクロック源から供給されたクロックによってタイマーカウンター(PSMCxTMR)が常にカウントアップしており、周期を決めるレジスタ(PSMCxPRH/L)、立ちあがりタイミングを決めるレジスタ(PSMCxPHH/L)、立ち下がりタイミングを決めるレジスタ(PSMCxDCH/L)の各レジスタと、タイマーカウンタの一致を見ており、一致したら周期、立ちあがり、立ち下がりのタイミングが決まります。PSMCxTMRは16ビットの内部カウンタです。またブロック図ではPSMCxPRとPSMCxDCとなっていますが、16F1783は8ビットマイコンなので、実際にはPSMCxPRH/LとPSMCxDCH/Lの8ビットのHigh byteとLow Byteに分かれています。

 

PSMCxTMRのクロック源は専用の64MHzのPSMC専用クロック、外部クロック(PSMCxCLKピン)、Foscから選べます。カウンタは16ビットですから2の16乗 = 65536パルス カウントできます。カウンタの前にプリスケーラがあり、クロックを1/8、1/4、1/2、1/1(スルー)にできます。クロック源とプレスケーラの指定はPSMCxCLKレジスタで行います。PSMCxTMRがリセット(ロールオーバー)される要因であるPSMCxINピン、3つのコンパレータの出力、PSMCxPRH/Lレジスタとの一致はPSMCxPRSレジスタで指定できます。これらのリセット条件は別々のビット設定になっているのでOR条件で指定可能です。

 

なお、外部クロックは32KHzから20MHzの範囲で供給できます。64MHzのPSMC専用クロックはCPUクロックとは独立しているためPSMCを高速で動かし、CPUは低速の低消費電力で動かすことも可能です。

 

PSMCxPRSレジスタのPxPRSTビットがセットされている場合、周期(period)を決めるPSMCxPRH/Lレジスタの内容は、PSMCxTMRと比較されており、一致するとPSMCxTMRはリセットされ最初からカウントし直し(ロールオーバー)になります。つまり、それで1周期の時間が決まります。たとえばPSMCxTMRが64MHzでカウントアップされていて、プリスケーラが1:1(スルー)の場合で、PSMCxPRH/Lに640をセットすると、周期は(1 / 64000000) x 640 = 10uSとなり、すなわち周波数は100KHzとなります。この計算と設定は、

 

//Period = (1 / 100KHz)s

PSMCxPRH = (64000 / 100 - 1) >> 8;

PSMCxPRL = (64000 / 100 - 1) & 0xFF;

 

というように行う事が出来ます。

 

クロック源に64MHz内蔵クロックを選んだ場合、タイマーカウンタ(PSMCxTMR)が16ビットのため、最長周期は(1 / 64000000) * 2**16 = 1.024mS(976.6Hz)となります。この場合のPWM信号の分解能は16ビットです。100KHzとした場合は、9ビット以上の精度となります。それらの精度で、たとえばデューティーを微妙に調整できるということになります。

PSMCxPRH/Lで1周期の時間を決めたら、その中でいつ信号を立ち上げ、いつ立ち下げるかを決めます。

 

立ちあげのタイミングはPSMCxPHSレジスタで決めます。PSMCxTNRのリセット要因と同じように、PSMCxINピン、3つのコンパレータ、PSMCxTMRとの一致をOR条件で選べます。

 

立ち下げのタイミングはPSMCxDCSレジスタで決めます。 PSMCxINピン、3つのコンパレータの出力、PSMCxTMRとの一致をOR条件で選べます。

 

タイマのリセット要因、立ちあげ、立ち下げのタイミングを決める要因は、PSMCxTMRと各レジスタ内容との一致のほか、PSMCxINピンとコンパレータ出力の非同期要因を加えることができます。

 

立ちあげタイミングを決めるPSMCxPHH/Lは、PSMCxTMRがリセットされてから何カウント目に立ちあげるかを決めるので、位相を決めるとも言えます。立ち上がりタイミングがずれますが、周期がその分縮まることはありません。一方PSMCxDCH/Lは、信号の立ち下がりタイミングを決めるので、信号のデューティー(1周期内での信号のHigh/Low時間の割合)を決める事になります。

 

最後に、以上のように設定した信号の論理(正/負)を決め、どのピンに出力するかを決めます。これまでの立ち上げ、立ち下げは正論理の場合ですから、負論理では逆になります。出力ピンはPSMCxAからPSMCxFの6本が選べます。なお、16F1783にはPSMCモジュールが2個搭載されていますが、2つ目のPSMCの出力ピンはAとBしかありません。

 

実際の設定は以下の様になります。この例はPSMC1モジュールで単相PWM、Period = 15.6uS(64KHz)、 プリスケーラ 1:1、Phase=0、Duty = 50%に設定しています。信号の出力ピンはPSMC1Aピン(ピン11)のみ。論理は正論理(アクティブ・ハイ)です。

 

単相PWMの設定例

 

    PSMC1CONbits.P1MODE = 0; //単一PWM 
    PSMC1CLKbits.P1CPRE = 0; //プリスケーラ1:1(スルー)
    PSMC1CLKbits.P1CSRC = 1; //Clock source 64MHz
    PSMC1OENbits.P1OEA = 1; //PSMC1Aピン有効
    PSMC1POLbits.P1POLA =1; //PSMC1A アクティブ・ハイ

    PSMC1PRSbits.P1PRST = 1; //PSMC1PRH/Lとの比較でタイマリセット
    PSMC1PHSbits.P1PHST = 1; //PSMC1PHH/Lとタイマとの比較で立ち上げ
    PSMC1DCSbits.P1DCST = 1; //PSMC1DCH/Lとたいまとの比較で立ち下げ


    period = 64; //Khz

  PSMC1PRH = (64000 / period - 1) >> 8; //100KHz
    PSMC1PRL = (64000 / period - 1) & 0xFF;


    PSMC1DCH = (( 64000 / period - 1) / 2 ) >> 8; //Duty = 50%
    PSMC1DCL = (( 64000 / period - 1) / 2 ) & 0xFF;  
  

    PSMC1STR0bits.P1STRA = 1;    
    PSMC1INT = 0; //割り込み関連は設定しない
     
    PSMC1CONbits.PSMC1EN = 1; //PSMCモジュールをイネーブルにする
    PSMC1CONbits.PSMC1LD = 1; //設定を有効にする

PSMC_02.jpg

上記の設定で観測した単相PWMの波形 3.3Vpp

Period=15.6uS(64KHz), Phase=0, Duty=50%

 

 

単相PWMはPSMCの持つモードのうちで最も単純なモードです。応用として簡単に試せるのは、最近のLEDドライバのCONTROL/PWM端子に接続してのPWM調光です。LED調光におけるPWM信号の周期(period)は、LEDドライバの応答速度を吟味した上で固定周期とし、調光はデューティーを調整して行えばよいようです。

 

関連記事: CAT4238 LEDドライバ

 

PSMCを使いこなすためには、単相PWM以外のモードや、デッドバンド、非同期タイミング、シャットダウン、同期などについて検討が必要です。これらについては後日試してみたいと思っています。

 

 

 

 

 

 

(JF1VRR)