今回私の工作でサーボモーター用のPWM(周期14ms)とモータードライバの駆動用のPWM(周期10us: 100kHz)の2系統のPWMを使う機会がありました。LPC1768はPWMが6本ついているので足りると思い基板を製作してプログラムを組んでから気づいたのですが、
「LPC1768の6つのPWMの周期はすべて同じになる」
という落とし穴に気づきました。新しく基板を製作するのも手間なので対策をWebで調べていたところ「Motor Control PWM(以下MCPWM)」というモジュールに気づきました。この名前のモジュールがPWM用のモジュールとは別にあり、これを使うと複数の周期のPWMが使えそうです。
ただ残念ながら青mbedではMCPWMのピンは出ていません。改造mbed専用になります。
概要
このモジュールは名前の通り、モータードライブ用のモジュールです。正確に言うとブラシレスDCモーター(BLDC)駆動用の3相の矩形波を出すためのモジュールです。
オリエンタルモーターのページに解説があります。以下がブロックダイヤグラムです(LPC176Xユーザーマニュアルより)。
このモジュールですがBLDC用の波形も出せるのですが、3組のタイマー+マッチレジスタが基本的な構成要素です。
ピン
MCOA0、MCOB0、MCOA1、MCOB1、MCOA2、MCOB2の6つの出力ピンがあります。
timer channelが3つありそれぞれの出力がA、Bの2つがあります。出力のAとBは基本的に逆位相(+デットタイムの設定)になるためにPWMとしては実質3つの出力になります。
通常のPWMとMCPWMを比較すると
Pin PWM MCPWM
P1.18 PWM1
P1.19 MCOA0
P1.20 PWM2
P1.21 PWM3
P1.22 MCOB0
P1.23 PWM4
P1.24 PWM5
P1.25 MCOA1
P1.26 PWM6 MCOB1
P1.27
P1.28 MCOA2
P1.29 MCOB2
というピン配置になっています。頑張ると最大で9つのPWMがLPC1768で使えます。
レジスタ説明
レジスタ名はmbed onlineコンパイラで使える名前です。[]内はビット位置
■Power Control Register (LPC_SC->PCONP)
[17]MCPWM control bit
MCPWMは初期設定で無効になっているので設定は必須です。
■Peripheral Clock Selection registers 1 (LPC_SC->PCLKSEL1)
[31:30]Peripheral clock selection for the Motor Control PWM
00 PCLK=CCLK/4
01 PCLK=CCLK
10 PCLK=CCLK/2
11 PCLK=CCLK/8
MCPWMへの入力クロックの設定です。Mbedの基本設定だと、CCLK=96MHzです。
■Pin Function Select Register 3 (LPC_PINCON->PINSEL3)
[7:6]P1.19(MCO0A)
[13:12]P1.22(MCO0B)
[19:18]P1.25(MCO1A)
[21:20]P1.26(MCO1B)
[25:24]P1.28(MCO2A)
[27:26]P1.29(MCO2B)
00 Other
01 MCPWM
10 Other
11 Other
ピンの機能選択です。使うピンだけ01に設定してください。
■MCPWM Control read address (LPC_MCPWM->MCCON)
■MCPWM Control set address (LPC_MCPWM->MCCON_SET)
■MCPWM Control clear address (LPC_MCPWM->MCCON_CLR)
[0]Stops/starts timer channel 0
[2]Selects polarity of channel 0
[8]Stops/starts timer channel1
[10]Selects polarity of channel 1
[16]Stops/starts timer channel 2
[18]Selects polarity of channel 2
Stops/starts...を1にすると該当するチャンネルのタイマーが動作します。
Selects polarityは出力を反転します。
読み込むときは一番上のレジスタを、レジスタの一部を1にしたければSetレジスタ、0にしたければClearレジスタに「1」を書き込みます。
普通のレジスタと書き込みが違いますね、ARMコアのペリフェラルでたまにある構成です。
■MCPWM Limit 0-2 registers (LPC_MCPWM->MCPER0、MCPER1、MCPER2)
[31:0]Limit values for TC0, 1, 2.
タイマーの上限値を設定します。この値と一致するとタイマーの値は0に初期化されます。
データシート中では「MCLIM0-2」という名前ですが、Mbedのライブラリではこの名前です(何かとの互換性のため?)。
■MCPWM Match 0-2 registers (LPC_MCPWM->MCPW0、MCPW1、MCPW2)
[31:0]Match values for TC0, 1, 2.
タイマーの一致の値を設定します。
このレジスタもデータシート中では「MCMAT0-2」という名前ですが、変更されています。
プログラム例
// Power up MCPWM
LPC_SC->PCONP |= 1<<17;
// PCLK = CCLK (100MHz in our case)
LPC_SC->PCLKSEL1 |= 1<<30;
// Configuring P1.22 as MC0B
LPC_PINCON->PINSEL3 |= (1<<12);
// Start MCPWM channels 1 and 2 and POLA = 1
LPC_MCPWM->MCCON_CLR = 0xffffffff;
LPC_MCPWM->MCCON_SET = (1<<0);
// Set the Limit register
LPC_MCPWM->MCPER0 = 960;
//Set the match register
LPC_MCPWM->MCPW0 = 96;
P1.22(MCO0B)を出力に設定しています。MCPWMに入っているクロックは96Mhzでそれを960で文集するので100kHzになります。また96/960=10%のデューティー非になります。
参考
https://os.mbed.com/users/mbed2f/notebook/mcpwm-in-lpc17xx/