RX621のCM0とDMAでLEDを点滅

RX621のCM0とDMAでLEDを点滅しました。
 
 RX600には、RX610,RX621,RX631等のシリーズが有りますが、周辺回路が微妙に違っているようです。
 今回使ったRX621のDMAでは、ノーマル転送モード、リピート転送モード、ブロック転送モードが有ります。しかし、頼りにしていた解説書ではRX610の説明です。RX610では、オペランド転送方式、ノンストップ転送方式が有ります。一瞬、私の頭が狂ったのか?と思いました。

 気を取り直して調べると、シリーズによって違いが有るのに気づきました。

●実験の構成と動作結果

 CM0とDMAでLEDを点滅する構成を次に示します。 使った機能は、CM0、ICU、DMA、Port、RAMで、そのはたらきです。

 
T、CM0で0.5mS毎に割り込みを発生
    48MHzのPCLKを512分割したものを入力して、46,874分割した0.5mS毎に割込を発生します。

 
U、ICUで、CM0割込みを検出して、DMAを起動。
   @CM0割り込みを検出するため、IEN(CMT0,CMI0) マクロで、CM0に該当するIERを設定。
   ACMT0割り込みでDMAC0起動するため、DMRSRレジスタにCM0割り込みベクタ番号を設定

 
VDMACで、DMA起動毎に1バイト転送してLEDを点滅させる。
   LEDを点滅は、点滅パタンを記憶した2バイトの変数をリピートサイズ2のリピートDMAモードを使います。
   @DMSARは転送元アドレスを格納。DMA毎に+1します。しかし、リピートサイズが2なので、2回目に元に戻ります。
   ADMDARは転送先アドレスを格納。今回は、Port0のDR指定のままです。
   BDMCRAHはリピートサイズを格納。DMA回数がリピートサイズになれば、DMCRAHの内容をDMCRALに転送します。
   CDMCRALは転送カウンタを格納。DMA毎にー1します。
   DDMCRBはリピート転送回数を格納。例えば10を設定すると、LEDの点滅が10サイクルしたら停止します。

 以上の内容で、問題無く動作しました。

 又、役に立った資料も次に示しました。Webで検索して入手しました。


 



 


●実験のプログラム

 HEWで作成したプログラムを下に置きます。

 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

/***********************************************************************/
/* */
/* FILE :Rx621_DmaLed_Cm0.c */
/* DATE :Wed, Jul 15, 2015 */
/* DESCRIPTION :Main Program */
/* CPU TYPE :RX62N */
/* */
/* This file is generated by Renesas Project Generator (Ver.4.53). */
/* NOTE:THIS IS A TYPICAL EXAMPLE. */
/* */
/***********************************************************************/



//#include "typedefine.h"
#ifdef __cplusplus
//#include <ios> // Remove the comment when you use ios
//_SINT ios_base::Init::init_cnt; // Remove the comment when you use ios
#endif

void main(void);
#ifdef __cplusplus
extern "C" {
void abort(void);
}
#endif


#include "iodefine.h" // Include iodefine.h

// **********************************************
// ********** Global variable definition
unsigned char LedDat[2];

// **********************************************
// ********** システムクロック,SPIレジスタ初期設定
void HardwareSetupMain(void)
{

// ********** システムクロック設定
SYSTEM.SCKCR.LONG = 0x00010100; // システムクロック設定 ICLK=96MHz, BCLK=48MHz, PCLK=48MHz

// ********** LED接続ポート初期設定
PORT0.DR.BYTE = 0xff; // P0データレジスタ(DR)の設定
// (LED1,0(P0_1,P0_0)に消灯データ(0xff)を設定)
PORT0.DDR.BYTE = 0x03; // P0データディレクションレジスタ(DDR)の設定
// (P0_1,P0_0を出力方向)


//*** IPR( CMT0, CMI0 ) = 1; // CMI0 Interrupt Level is 1


// ********** BCLK出力ポート初期設定
PORT5.DDR.BIT.B3 = 1; // P53ディレクションレジスタ(DDR)の設定


// ********** CMT0初期設定
SYSTEM.MSTPCRA.BIT.MSTPA15 = 0; // CMT0モジュールストップ解除

CMT0.CMCR.WORD = 0x0043; // カウントソース:PCLK/512=93.75KHz(PCLK=48MHz)
// 割り込み要因の出力を許可(IRビットに反映)
CMT0.CMCOR = 46875-1; // 500ms周期 PCLK/512/46,875=2Hz

IEN(CMT0,CMI0) = 1; // CMT0コンペアマッチ割り込み要求を許可は、IENマクロを使用。
// IENマクロ(割り込み要求元, 割り込み信号名)

// ********** CMT0コンペアマッチ割り込みで、DMAC0起動の初期設定
ICU.DMRSR0 = 28; // CMT0コンペアマッチ割り込みベクタ番号を設定


// ********** DMAC0初期設定

DMAC0.DMAMD.WORD = 0x8000; // DMA0アドレスモードレジスタ設定
//  転送元アドレス更新モード:プラス方向
//  転送元アドレス拡張リピート領域:設定しない
//  転送先アドレス更新モード:固定(P0.DR)
//  転送先アドレス拡張リピート領域:設定しない

DMAC0.DMCNT.BYTE = 0x00; // DMA0起動不許可設定

DMAC0.DMTMD.WORD = 0x5001; // DMA0モードレジスタ設定
//  転送モード:リピート転送
//  リピート領域:設定しない
//  転送データビット長:8bit
//  転送要求:周辺モジュールか

DMAC0.DMSAR = LedDat; // 転送元アドレス設定
DMAC0.DMDAR = (void *)&PORT0.DR;// 転送先アドレス設定 (P0.DR)
DMAC0.DMCRA = 0x00020002; // リロード転送バイト数/転送バイト数設定
DMAC0.DMCRB = 0x000F; // リピート転送カウント設定

// ********** DMAC0起動設定 転送許可
DMAC.DMAST.BYTE = 0x01; // DMACモジュール起動設定
DMAC0.DMCNT.BYTE = 0x01; // DMAC0転送許可


}


// **********************************************
// ******************** main ********************
void main(void)
{
unsigned long n; //
unsigned long SpiRxDat; //

LedDat[0] = 1; // LED1=On,LED0=OFF
LedDat[1] = 2; // LED1=OFF,LED0=On

PORT0.DDR.BIT.B1 = 1; // Reverse P01(LED)
PORT0.DDR.BIT.B0 = 1; // Reverse P00(LED)

PORT5.DDR.BIT.B3 = 1; // Reverse P53

HardwareSetupMain(); //システムクロック,SPIレジスタ初期設定

// ********** CMT0起動
CMT.CMSTR0.BIT.STR0 = 1; // CMT0起動


while( 1 )
{
// PORT0.DR.BIT.B1 = 0; // Reverse P01(LED)
// PORT0.DR.BIT.B0 = 1; // Reverse P00(LED)


for(n=0; n<20000000; n++){} //時間待ち


// PORT0.DR.BIT.B1 = 1; // Reverse P01(LED)
// PORT0.DR.BIT.B0 = 0; // Reverse P00(LED)

for(n=0; n<20000000; n++){} //時間待ち


}



}


#ifdef __cplusplus
void abort(void)
{

}
#endif







ホームへ戻る