ソーマ&るいのマイコン備忘録

マイコン関連の備忘録的なこと

PIC32MMのCCP(PWM)を使う

32bitPICの32MM0064GPL28の単純PWM設定です。

コンフィグビットやPLLの設定などはMPLABのMCCで自動的に作成されますのでそちらを利用してください。

8BITマイコンでは単純にPWMと呼んでいたユニットですが32BITマイコンではMCCPとかOCMなどと呼ばれるのでPWM出力が無い?と勘違いしていましたが、32MMにはMCCP1~MCCP3の三つのユニットがあり、そのうち2と3はピン割付可能なピンに出力することが出来ます。

 

具体的にはMCCP1の出力をRA0(ピン2)に(データシートではOCM1Eになっている)。

MCCP2をRP13(ピン24)、MCCP3をRP12(ピン23)に割り付けて見ます。

 

この例では分解能9ビットのPWMをクロック1/4周波数で回していますので、最高動作周波数の24Mhzでは11718Hzになります。

 

ピン割付ですが、不用意な変更を防ぐためにシステムキーの解除が必要になるようです、この処理に関してはMCCが自動作成したソースを流用します。

内容はMPLABのバージョンによって変わる可能性があるので、上記に関しては必ず自動生成されたソースを流用してください。

 

自分でもよくわかっていない部分がありますがCCPXRPとCCPXRBに全体周期-1を設定し(9bit分解能なら 512-1=511)、CCPXRAに0~全体周期の間の値を入れるとDUTYが設定されます、実際には0でdutyが100%になります。

CCPユニット一つに付き、出力端子はA~FまであってCCP1に関しては

CCP1CON2bits.OCEN = 1 として出力端子Eを指定するとRA0に出力されるようなりますが(データシートのピンダイアグラム参照)

CCP2とCCP3の出力はピン割付による指定しか出来なくて、

RPOR3bits.RP13R = 0x0006; // RB13->SCCP2:OCM2 CCP(PWM2)出力

のようにコードで指定するのですが、A~Fのどの端子を指定するとか言うコードは無くて、0x0006がCCP2 0x0007がCCP3という指定になっています、とりあえずは端子Aを許可すると出力されるようです。

 

//
// CCP(PWM)設定
//
void SetCCP( void ) {

 

//
// CCP1の設定
//
CCP1CON1 = 0;
CCP1CON1bits.CLKSEL = 0; // CLK = SYSTEM CLK
CCP1CON1bits.CCSEL = 0; // PWM mode
CCP1CON1bits.T32 = 0; // 16bitTimer
CCP1CON1bits.TMRPS = 1; // Clock/4
CCP1CON1bits.MOD = 5;

CCP1CON2 = 0;
CCP1CON2bits.OCEEN = 1; // PWMパルス出力許可ビット
CCP1CON3 = 0;
CCP1STAT = 0;
//TMRL 0; TMRH 0;
CCP1TMR = 0x0;
// (全体周期/分解能)
CCP1PR = 511;//0x200;
//CMPA 32;
CCP1RA = 256; // Duty
//CMPB 128;
CCP1RB = 511;
//BUFL 0; BUFH 0;
CCP1BUF = 0x0;

CCP1CON1bits.ON = 1; // CCP1 ON

//
// CCP2の設定
//
CCP2CON1 = 0;
CCP2CON1bits.CLKSEL = 0; // CLK = SYSTEM CLK
CCP2CON1bits.CCSEL = 0; // PWM mode
CCP2CON1bits.T32 = 0; // 16bitTimer
CCP2CON1bits.TMRPS = 1; // Clock/4
CCP2CON1bits.MOD = 5;

CCP2CON2 = 0;
CCP2CON2bits.OCAEN = 1; // PWMパルス出力許可ビット
CCP2CON3 = 0;
CCP2STAT = 0;
//TMRL 0; TMRH 0;
CCP2TMR = 0x0;
// (全体周期/分解能)
CCP2PR = 511;//0x200;
//CMPA 32;
CCP2RA = 256; // Duty
//CMPB 128;
CCP2RB = 511;
//BUFL 0; BUFH 0;
CCP2BUF = 0x0;

CCP2CON1bits.ON = 1; // CCP2 ON

//
// CCP3の設定
//
CCP3CON1 = 0;
CCP3CON1bits.CLKSEL = 0; // CLK = SYSTEM CLK
CCP3CON1bits.CCSEL = 0; // PWM mode
CCP3CON1bits.T32 = 0; // 16bitTimer
CCP3CON1bits.TMRPS = 1; // Clock/4
CCP3CON1bits.MOD = 5;

CCP3CON2 = 0;
CCP3CON2bits.OCAEN = 1; // PWMパルス出力許可ビット
CCP3CON3 = 0;
CCP3STAT = 0;
//TMRL 0; TMRH 0;
CCP3TMR = 0x0;
// (全体周期/分解能)
CCP3PR = 511;//0x200;
//CMPA 32;
CCP3RA = 256; // Duty
//CMPB 128;
CCP3RB = 511;
//BUFL 0; BUFH 0;
CCP3BUF = 0x0;

CCP3CON1bits.ON = 1;


}

 

MCCが作成したピン割付やPLL設定時のおまじないルーチン

unlockを呼んだ後必要な設定をして再度lockを掛けます。

 

inline static void SYSTEM_RegUnlock(void) {
SYSKEY = 0x0; //write invalid key to force lock
SYSKEY = 0xAA996655; //write Key1 to SYSKEY
SYSKEY = 0x556699AA; //write Key2 to SYSKEY
}

inline static void SYSTEM_RegLock(void) {
SYSKEY = 0x00000000;
}

 

ピン割付

void SetPinConnect( void ) {

//    ロック解除

SYSTEM_RegUnlock(); // unlock PPS
RPCONbits.IOLOCK = 0;

// ピン割付を行う
RPOR3bits.RP13R = 0x0006; // RB13->SCCP2:OCM2 CCP(PWM2)出力
RPOR2bits.RP12R = 0x0007; // RB12->SCCP3:OCM3 CCP(PWM3)出力

 //    ロック

RPCONbits.IOLOCK = 1; // lock PPS
SYSTEM_RegLock();

}