概要
今回は、dsPIC33AKシリーズに搭載されているCLC(Configurable Logic Cell)モジュールの使い方についてご紹介します。
CLCモジュールは、過去の記事でも取り上げたことがありますが、PICシリーズに搭載されているペリフェラルの中でも非常にユニークな機能です。以下のような特徴があります。
CLCは「Configurable Logic Cell」の略で、ANDやOR、フリップフロップなどの論理機能を自由に組み合わせて、簡易的な論理回路を構成できるモジュールです。
・VHDLやVerilogなどのHDL言語で記述する必要はなく、レジスタ設定のみで構成可能
・複雑な回路は組めないものの、動的にロジック構成を変更できる柔軟性
・ハードウェア処理のため、ソフトウェアよりも高速な信号処理が可能
・外付け部品が不要で、基板の集積度向上やシステムコストの削減に貢献
・他モジュールとの連携により機能拡張が可能
・CPU負荷を軽減可能
記事変更履歴
| 公開/ 変更日 | 特記 |
| 25/5/23 | 初版公開。 |
| 25/5/26 | 対応型式の追加 |
| 25/6/14 | 開発環境、ブロック図、ソースコード、結果の追加 |
dsPIC33系CLCの残念なポイント
これまでのdsPICシリーズに搭載されているCLCには大きな課題がありました。
それは、データソース(DS:Data Selection)の選択肢が非常に少なかったという点です。
例えば、8bit PICシリーズではDSの選択肢が6〜7ビット用意されているのに対し、dsPIC系ではわずか3ビットしかなく、しかも割り当て可能な入力が限られていました。
その結果、「CLCを使いたくても使えない」という状況が多く、使い勝手が悪い印象を持っていた方も多いのではないでしょうか。


改善されなかったdsPIC33AK 初代のCLC
これはdsPIC33AKの初代でも変わらず、下記のように特定のモジュールの出力しかデータソースとして割り当てられていませんでした。
一応、他モジュールの出力を一度I/Oピンに出力し、再びCLC入力ピン(例:CLCINA)から取り込むといった回避策もありましたが、貴重な外部ピンを消費してしまうという大きなデメリットがありました。



改善されたdsPIC33AK 2nd GenerationのCLC
このような状況が、dsPIC33AKシリーズの第2世代で大きく改善されました。
DSのビット幅自体は変わらず3ビットのままですが、各DS入力に「バーチャルピン出力」が割り当てられるようになったのです。
つまり、Peripheral Pin Select(PPS)で出力できるすべての機能が、CLCのデータソースとして使用可能になっています
これにより、従来のように外部ピンを経由する必要がなくなり、使い勝手が飛躍的に向上しています。
さらに、10チャンネル分のCLCが使用可能となり、クリティカルなリアルタイム処理にも十分に対応できます。





関連リンク
内部リンク
| 記事タイトル | リンク |
| CLCモジュールの使い方 | CLCモジュールの使い方 – ぴくおの電子工作的な何かWP |
| CLCモジュールの使い方2 | dsPIC33Cシリーズ CLCモジュールの使い方2 – ぴくおの電子工作的な何かWP |
外部リンク
開発環境
開発環境を以下に示します。
今回はCPUボード(EV80L65A)で動作確認を行います。
| 項目 | 値 | リンク |
| ベースボード | dsPIC33A CURIOSITY PLATFORM DEVELOPMENT BOARD | dsPIC33A Curiosity Platform Development Board User’s Guide (microchip.com) |
| CPUボード(EV80L65A) | dsPIC33AK512MPS512 General Purpose Dual In-Line Module (DIM) | dsPIC33AK512MPS512 General Purpose Dual In-Line Module (DIM) | Microchip Technology |
| 統合開発環境 | MPLAB X IDE v6.25 | MPLAB® X IDE | Microchip Technology |
| コンパイラ | MPLAB XC DSC v3.21 | MPLAB® XC DSC Compiler | Microchip Technology |

ブロック図
今回はCLCの動作確認を目的として、以下のような構成でLEDを点滅させます。

- CLC1:PWM1Hの出力を内部バーチャルピンに接続し、Standard ClockとのAND演算結果を出力します。
最終的な出力は外部ピンに接続し、LED1を点灯させて動作を確認します。
ソースコード
int main()
{
/*-----------------------------------------------------------------------*/
/*初期化*/
/*-----------------------------------------------------------------------*/
vdg_Clock_Set_Register();
RPOR10bits.RP42R = 69; //CLC1OUT
RPOR34bits.RP139R = 1; //PWM1OUT
/*-----------------------------------------------------------------------*/
/* CLC1CONレジスタ */
/*-----------------------------------------------------------------------*/
CLC1CON =
( 2 << _CLC1CON_MODE_POSITION ) | //4 in AND
( 0 << _CLC1CON_LCPOL_POSITION ) |
( 0 << _CLC1CON_LCOUT_POSITION ) |
( 1 << _CLC1CON_LCOE_POSITION ) |
( 0 << _CLC1CON_INTN_POSITION ) |
( 0 << _CLC1CON_INTP_POSITION ) |
( 0 << _CLC1CON_ON_POSITION ) |
( 0 << _CLC1CON_G1POL_POSITION ) |
( 0 << _CLC1CON_G2POL_POSITION ) |
( 1 << _CLC1CON_G3POL_POSITION ) |
( 1 << _CLC1CON_G4POL_POSITION ) ;
/*-----------------------------------------------------------------------*/
/* CLC1SELレジスタ */
/*-----------------------------------------------------------------------*/
CLC1SEL =
( 0 << _CLC1SEL_DS1_POSITION ) | //Standard Peripheral Clock (system clock/2)
( 6 << _CLC1SEL_DS2_POSITION ) | //Virtual Pin 10 Output
( 0 << _CLC1SEL_DS3_POSITION ) | //BFRC/244
( 0 << _CLC1SEL_DS4_POSITION ) ; //FRC
/*-----------------------------------------------------------------------*/
/* CLC1GLSレジスタ */
/*-----------------------------------------------------------------------*/
CLC1GLS =
( 0 << _CLC1GLS_G1D1N_POSITION ) |
( 1 << _CLC1GLS_G1D1T_POSITION ) |
( 0 << _CLC1GLS_G1D2N_POSITION ) |
( 0 << _CLC1GLS_G1D2T_POSITION ) |
( 0 << _CLC1GLS_G1D3N_POSITION ) |
( 0 << _CLC1GLS_G1D3T_POSITION ) |
( 0 << _CLC1GLS_G1D4N_POSITION ) |
( 0 << _CLC1GLS_G1D4T_POSITION ) |
( 0 << _CLC1GLS_G2D1N_POSITION ) |
( 0 << _CLC1GLS_G2D1T_POSITION ) |
( 0 << _CLC1GLS_G2D2N_POSITION ) |
( 1 << _CLC1GLS_G2D2T_POSITION ) |
( 0 << _CLC1GLS_G2D3N_POSITION ) |
( 0 << _CLC1GLS_G2D3T_POSITION ) |
( 0 << _CLC1GLS_G2D4N_POSITION ) |
( 0 << _CLC1GLS_G2D4T_POSITION ) |
( 0 << _CLC1GLS_G3D1N_POSITION ) |
( 0 << _CLC1GLS_G3D1T_POSITION ) |
( 0 << _CLC1GLS_G3D2N_POSITION ) |
( 0 << _CLC1GLS_G3D2T_POSITION ) |
( 0 << _CLC1GLS_G3D3N_POSITION ) |
( 0 << _CLC1GLS_G3D3T_POSITION ) |
( 0 << _CLC1GLS_G3D4N_POSITION ) |
( 0 << _CLC1GLS_G3D4T_POSITION ) |
( 0 << _CLC1GLS_G4D1N_POSITION ) |
( 0 << _CLC1GLS_G4D1T_POSITION ) |
( 0 << _CLC1GLS_G4D2N_POSITION ) |
( 0 << _CLC1GLS_G4D2T_POSITION ) |
( 0 << _CLC1GLS_G4D3N_POSITION ) |
( 0 << _CLC1GLS_G4D3T_POSITION ) |
( 0 << _CLC1GLS_G4D4N_POSITION ) |
( 0 << _CLC1GLS_G4D4T_POSITION ) ;
CLC1CONbits.ON = 1;
/*-----------------------------------------------------------------------*/
/* PWM設定*/
/*-----------------------------------------------------------------------*/
PCLKCONbits.MCLKSEL = 0u;
PCLKCONbits.DIVSEL = 0u;
MPER = 1000;
MDC = MPER / 2;
PG1PHASE = 0u;
PG1CONbits.MODSEL = 0u; //可変フェーズ
PG1CONbits.CLKSEL = 1u; //MCLKSEL
PG1CONbits.TRGCNT = 0u;
PG1CONbits.SOCS = 0u;
PG1CONbits.TRGMOD = 0u;
PG1CONbits.UPDMOD = 0u;
PG1CONbits.MSTEN = 0u;
PG1CONbits.MPHSEL = 0u;
PG1CONbits.MPERSEL = 1u; //MPER
PG1CONbits.MDCSEL = 1u; //MDC
PG1IOCON1bits.POLL = 0;
PG1IOCON1bits.POLH = 0;
PG1IOCON1bits.PENL = 0;
PG1IOCON1bits.PENH = 1;
PG1IOCON1bits.PMOD = 0;
PG1IOCON1bits.DTCMPSEL = 0;
PG1IOCON1bits.PPSEN = 0;
PG1IOCON1bits.FORCEON = 0;
PG1IOCON1bits.SWAP = 0;
PG1IOCON1bits.CAPTRSEL = 0;
PG1IOCON1bits.CAPTREN = 0;
PG1IOCON1bits.CAPSRC = 0;
PG1IOCON1bits.CAPEN = 0;
/*-----------------------------------------------------------------------*/
/* PG1IOCON2レジスタ */
/*-----------------------------------------------------------------------*/
PG1IOCON2 = 0x00000000;
PG1CONbits.ON = 1u;
while(1){;}
}
結果
下記のように、Standard ClockがPWM信号でチョッピングされている事が確認できると思います。

対応型式
以下の型式には、すべて改良されたCLCが搭載されています。
・dsPIC33AK256MPS205・dsPIC33AK256MPS206・dsPIC33AK256MPS208・dsPIC33AK256MPS210・dsPIC33AK256MPS212
・dsPIC33AK256MPS505・dsPIC33AK256MPS506・dsPIC33AK256MPS508・dsPIC33AK256MPS510・dsPIC33AK256MPS512
・dsPIC33AK512MPS205・dsPIC33AK512MPS206・dsPIC33AK512MPS208・dsPIC33AK512MPS210・dsPIC33AK512MPS212
・dsPIC33AK512MPS505・dsPIC33AK512MPS506・dsPIC33AK512MPS508・dsPIC33AK512MPS510・dsPIC33AK512MPS512
・dsPIC33AK256MC205・dsPIC33AK256MC206・dsPIC33AK256MC208・dsPIC33AK256MC210・dsPIC33AK256MC505
・dsPIC33AK256MC506・dsPIC33AK256MC508・dsPIC33AK256MC510・dsPIC33AK512MC205・dsPIC33AK512MC206
・dsPIC33AK512MC208・dsPIC33AK512MC210・dsPIC33AK512MC505・dsPIC33AK512MC506・dsPIC33AK512MC508
・dsPIC33AK512MC510
記事についての注意点
本記事は慎重に内容を検討し正確さに努めておりますが、内容に誤りがあったとしても、この記事を参考にして生じた損害等については一切の責任を負いません。


コメント