********************************************************************************
* 詳細説明:
* この例では、eTimer0 モジュール チャネル 2 からトリガーされる CTU モジュールの使用方法を示します。
*
* CTUの仕組みの詳細については、アプリケーションノートを確認することをお勧めします
※MPC5643LPWM_ADC_concept
※ https://community.freescale.com/docs/DOC-102559
*
※この例では、eTimer0 channel2をPWM信号生成用に設定します。
*この信号は、MSRトリガーをCTUモジュールに送信するために使用されます
* 例には、単純な CTU モジュール ドライバーの初期化も含まれています
* CTUスケジューラサブモジュールは、CTUトリガーに基づいて外部ピンと切り替えられます
*
* ------------------------------------------------------------------------------
* Test HW: MPC57xx Motherboard + MPC5744PE257DC minimodule, MPC5744P,
※シリコンマスクセット 1N65H
* 対象 : internal_FLASH*
********************************************************************************
元の添付ファイルは次の場所に移動しました Example-MPC5744P-CTU-eTimer-v1_1-GHS614.zip
Hi,
私たちも同様の問題を経験しています。推奨される解決策はありますか?
どうもありがとうございます!
Hi Linuxz,
最近同様の問題が発生していますが、この問題を解決しましたか?この問題についてフィードバックをいただけますか?
よろしくお願いいたします。
[ピーター]–うーん、すでに処理されているコマンドがあるときにADCコマンドを発行すると、ADC_OEフラグ(ADCコマンド生成オーバーランエラー)が設定されます。
私には、CTUコマンドリストにタイミングの問題があるようです。「 最初のコマンドがADCによって実行されることが時々見える」と書かれていました。それは時々どういう意味ですか?これは、デューティサイクルが変更されたとき、またはこの状況が発生したときに何が異なるかです。
Hi,
MPC5744PのCTUに問題があり、PMSMモーターを制御するためにFlexPWM_0に3つの同期PWM信号を設定しました。
このモーターを制御するには、PWMサイクルの特定の場所で電流を測定する必要もあります。
PWM サブモジュール 0 を設定してOUT_TRIG0を生成し、ADC でデュアル変換を開始するように CTU を設定しようとしましたが、デザインでより多くのアナログ信号を変換する必要があるため、CTU が ADC に送信するコマンドのリストを作成しました。
6つのコマンドが完了すると、dma転送によってデータが配列に移動されます。
しかし、何かが間違っている、私は時々最初のコマンドがADCによって実行され、結果がCTU FIFOに戻されるのを見ることがありますが、その後はすべて停止し、ADC_OEとERRCMPフラグがCTUで設定されているようです。
私のコードで何が間違っていたのかについて何かヒントはありますか?
私のコードについては以下を参照してください、それを添付する方法を見つけることができませんでした。
よろしくお願いします、ライナス
#include 「mpc55xx.h」
#include「pwm_driver.h」
/* ************************************************************************** *
* グローバル宣言 *
* ************************************************************************** */
uint32_t ADC_results[16];
/**
* @brief setPwmDutyCycle
* @Param chn1 符号なし値 (チャネル 1 の 0 から 1000 のデューティ サイクルを含む)
* チャネル 2 の 0 から 1000 のデューティ サイクルを含む @Param chn2 符号なし値
* @Param chn3 符号なし値 (チャネル 3 の 0 から 1000 のデューティ サイクルを含む)
* @return ブール値、1 = 成功、0 = デューティを設定できませんでした
*
* @details この関数は、デューティサイクルを設定する必要がある場合に呼び出されます
*/
boolean Pwm_SetDutyCycle (uint16 chn1, uint16 chn2, uint16 chn3)
{
if (chn1 > 950) chn1 = 950;
if (chn1 < 50) chn1 = 50;
if (chn2 > 950) chn2 = 950;
if (chn2 < 50) chn2 = 50;
if (chn3 > 950) chn3 = 950;
if (chn3 < 50) chn3 = 50;
if (FLEXPWM_0.MCTRL.B.LDOK == 0)
{
FLEXPWM_0.SUB[0].VAL[2].B.VAL = 5000 - (chn1*5);
FLEXPWM_0.SUB[0].VAL[3].B.VAL = 5000 + (chn1*5);
FLEXPWM_0.SUB[1].VAL[2].B.VAL = 5000 - (chn2*5);
FLEXPWM_0.SUB[1].VAL[3].B.VAL = 5000 + (chn2*5);
FLEXPWM_0.SUB[2].VAL[2].B.VAL = 5000 - (chn3*5);
FLEXPWM_0.SUB[2].VAL[3].B.VAL = 5000 + (chn3*5);
/* PWMモジュールに値をラッチ */
FLEXPWM_0.MCTRL.B.LDOK |= 7;
return 1;
} else
{
return 0;
}
}
/**
※@brief pwm_Init
*
* @details この関数は、モーターを制御するためのpwm出力を設定するために呼び出されます
*/
void pwm_Init(void)
{
SIUL2です。PCR検査[46]。R = 0x30000000 |0x02000000 |0x2;CTU0 外部トリガ出力 (EVB では PG[13])
LDOKをクリアしてレジスタ設定を変更できるようにします
FLEXPWM_0.MCTRL.B.CLDOK |= 1 << 0;
FLEXPWM_0.MCTRL.B.CLDOK |= 1 << 1;
FLEXPWM_0.MCTRL.B.CLDOK |= 1 << 2;
FLEXPWM_0.SUB[0].CTRL.B.PRSC = 5;
FLEXPWM_0.SUB[1].CTRL.B.PRSC = 0;
FLEXPWM_0.SUB[2].CTRL.B.PRSC = 0;
FLEXPWM_0.SUB[0] です。Ctrl キー 2 キー。B.RELOAD_SEL = 0;
FLEXPWM_0.SUB[1]。Ctrl キー 2 キー。B.RELOAD_SEL = 1;/* サブモジュール 0 からの RELOAD 信号はレジスタのリロードに使用されます*/
FLEXPWM_0.SUB[2]。Ctrl キー 2 キー。B.RELOAD_SEL = 1;/* サブモジュール 0 からの RELOAD 信号はレジスタのリロードに使用されます*/
FLEXPWM_0.SUB[0] です。Ctrl キー 2 キー。B.CLK_SEL = 0;/* ペリフェラルクロックは、ローカルプリスケーラとカウンタのクロックとして使用されます。*/
FLEXPWM_0.SUB[1]。Ctrl キー 2 キー。B.CLK_SEL = 2;/* サブモジュール 0 のクロック (AUX_CLK) は、ローカル プリスケーラとカウンタのソース クロックとして使用されます。*/
FLEXPWM_0.SUB[2]。Ctrl キー 2 キー。B.CLK_SEL = 2;/* サブモジュール 0 のクロック (AUX_CLK) は、ローカル プリスケーラとカウンタのソース クロックとして使用されます。*/
FLEXPWM_0.SUB[0] です。Ctrl キー 2 キー。B.FORCE_SEL = 0;/* ペリフェラルクロックは、ローカルプリスケーラとカウンタのクロックとして使用されます。*/
FLEXPWM_0.SUB[1]。Ctrl キー 2 キー。B.FORCE_SEL = 1;/* サブモジュール 0 のクロック (AUX_CLK) は、ローカル プリスケーラとカウンタのソース クロックとして使用されます。*/
FLEXPWM_0.SUB[2]。Ctrl キー 2 キー。B.FORCE_SEL = 1;/* サブモジュール 0 のクロック (AUX_CLK) は、ローカル プリスケーラとカウンタのソース クロックとして使用されます。*/
FLEXPWM_0.SUB[0] です。Ctrl キー 2 キー。B.INIT_SEL = 0;/* ペリフェラルクロックは、ローカルプリスケーラとカウンタのクロックとして使用されます。*/
FLEXPWM_0.SUB[1]。Ctrl キー 2 キー。B.INIT_SEL = 1;/* サブモジュール 0 のクロック (AUX_CLK) は、ローカル プリスケーラとカウンタのソース クロックとして使用されます。*/
FLEXPWM_0.SUB[2]。Ctrl キー 2 キー。B.INIT_SEL = 1;/* サブモジュール 0 のクロック (AUX_CLK) は、ローカル プリスケーラとカウンタのソース クロックとして使用されます。*/
FLEXPWM_0.SUB[0] です。ディスマップ。R = 0x0000;/* 障害ピン状態を無効にする */
FLEXPWM_0.SUB[1]。ディスマップ。R = 0x0000;/* 障害ピン状態を無効にする */
FLEXPWM_0.SUB[2]。ディスマップ。R = 0x0000;/* 障害ピン状態を無効にする */
FLEXPWM_0.SUB[0].INIT.B.INIT = 0;
FLEXPWM_0.SUB[0].VAL[0].B.VAL = 20;
FLEXPWM_0.SUB[0].VAL[1].B.VAL = 10000;
FLEXPWM_0.SUB[0].VAL[2].B.VAL = 5000;
FLEXPWM_0.SUB[0].VAL[3].B.VAL = 5000;
FLEXPWM_0.SUB[0] です。TCTRLです。B.OUT_TRIG_EN = 1;/* OUT_TRIG0 は、カウンタ値が VAL0 値と一致する場合に設定されます。*/
FLEXPWM_0.SUB[1].INIT.B.INIT = 0;
FLEXPWM_0.SUB[1].VAL[0].B.VAL = 20;
FLEXPWM_0.SUB[1].VAL[1].B.VAL = 10000;
FLEXPWM_0.SUB[1].VAL[2].B.VAL = 5000;
FLEXPWM_0.SUB[1].VAL[3].B.VAL = 5000;
FLEXPWM_0.SUB[2].INIT.B.INIT = 0;
FLEXPWM_0.SUB[2].VAL[0].B.VAL = 20;
FLEXPWM_0.SUB[2].VAL[1].B.VAL = 10000;
FLEXPWM_0.SUB[2].VAL[2].B.VAL = 5000;
FLEXPWM_0.SUB[2].VAL[3].B.VAL = 5000;
/*
FLEXPWM_0.SUB[0] です。DTCNT0 です。B.DTCNT0 = 0x0078;
FLEXPWM_0.SUB[0] です。DTCNT1 です。B.DTCNT1 = 0x0078;
FLEXPWM_0.SUB[1]。DTCNT0 です。B.DTCNT0 = 0x0078;
FLEXPWM_0.SUB[1]。DTCNT1 です。B.DTCNT1 = 0x0078;
FLEXPWM_0.SUB[2]。DTCNT0 です。B.DTCNT0 = 0x0078;
FLEXPWM_0.SUB[2]。DTCNT1 です。B.DTCNT1 = 0x0078;
*/
FLEXPWM_0.SUB[0] です。DTCNT0 です。B.DTCNT0 = 0x0;
FLEXPWM_0.SUB[0] です。DTCNT1 です。B.DTCNT1 = 0x0;
FLEXPWM_0.SUB[1]。DTCNT0 です。B.DTCNT0 = 0x0;
FLEXPWM_0.SUB[1]。DTCNT1 です。B.DTCNT1 = 0x0;
FLEXPWM_0.SUB[2]。DTCNT0 です。B.DTCNT0 = 0x0;
FLEXPWM_0.SUB[2]。DTCNT1 です。B.DTCNT1 = 0x0;
FLEXPWM_0.OUTEN.B.PWMA_EN |= 1 << 0;
FLEXPWM_0.OUTEN.B.PWMA_EN |= 1 << 1;
FLEXPWM_0.OUTEN.B.PWMA_EN |= 1 << 2;
FLEXPWM_0.OUTEN.B.PWMB_EN |= 1 << 0;
FLEXPWM_0.OUTEN.B.PWMB_EN |= 1 << 1;
FLEXPWM_0.OUTEN.B.PWMB_EN |= 1 << 2;
FLEXPWM_0.MCTRL.B.LDOK |= 1 << 0;
FLEXPWM_0.MCTRL.B.LDOK |= 1 << 1;
FLEXPWM_0.MCTRL.B.LDOK |= 1 << 2;
FLEXPWM_0.MCTRLです。B.RUN|= 1 << 0;
FLEXPWM_0.MCTRLです。B.RUN|= 1 << 1;
FLEXPWM_0.MCTRLです。B.RUN |= 1 << 2;
/** PWMを有効にする */
Enable_pwm();
}
/***********************************************************************/
/* CTU_Init */
/***********************************************************************/
void CTU_Init (void)
{
CTU_0.TGSISRです。B.I1_RE = 0x1; /* CTU - PWM ch0 奇数 - 周期 50usec の MRS を選択 */
CTU_0.CRです。B.TGSISR_RE = 0x1;/* TGS入力選択レジスタのリロードイネーブル */
CTU_0.TGSCR.B.PRES = 0x4; /* CTU プリスケーラーは 1 に設定されています */
CTU_0.TCR[0]。R = 0x10; /* CTU タイマーはレジスタ 0 の値と比較します */
CTU_0.TGSCCR.R = 0xFFFF; /* TGSカウンタコンペアレジスタ */
CTU_0.TGSCRR.R = 0; /* TGSカウンタリロードレジスタ */
CTU_0.TGSCR.B.TGS_M = 0;
CTU_0.TGSCR.B.ET_TM = 0;
CTU_0.THCR1。B.T0_E = 1; /* トリガー 0 出力イネーブル */
CTU_0.THCR1。B.T0_ADCE = 1; /* トリガー 0 ADC コマンド出力イネーブル */
CTU_0.CLCR1.B.T0_INDEX = 0; /* トリガー 0 コマンドリスト - 最初のコマンドアドレス */
(*(揮発性uint16_t *)0xFFE0C06C) = 1;/* CTU_0.FDCR = 1 - FIFO の DMA が (ヘッダー ファイルにありません!)*/
CTU_0.FDCR.B.DE0 = 1;
CTU_0.FCRのR = 0; /* FIFO制御レジスタ */
/* CTUトリガーADC - ADCコマンドリスト */
/* SU : ADC コマンドリスト */
CTU_0.CLR[0] です。R = 14; /* 最初のコマンド - CTU は、このコマンドの後、ADC へのコマンドの送信を開始します */
CTU_0.CLR[0] です。A.B.CH = 5; /* ADC_0モジュール、チャンネル11 */
//CTU_0.CLR[0].B.B.CMS = 0;
//CTU_0.CLR[0].B.B.LC = 1;
CTU_0.CLR[0] です。B.B.CH_A = 11; /* ADC_0モジュール、チャンネル11 */
CTU_0.CLR[0].B.B.CH_B = 12; /* ADC_1 module, channel 12 */
CTU_0.CLR[0].B.B.CMS = 1;
CTU_0.CLR[1]。B.B.CH_A = 13; /* ADC_0モジュール、チャンネル13 */
CTU_0.CLR[1].B.B.CH_B = 1; /* ADC_1 module, channel 1 */
CTU_0.CLR[1].B.B.CMS = 1;
//CTU_0.CLR[1].B.B.LC = 1;
CTU_0.CLR[2]。B.B.CH_A = 5; /* ADC_0モジュール、チャンネル5 */
CTU_0.CLR[2].B.B.CH_B = 0; /* ADC_1 module, channel 0 */
CTU_0.CLR[2].B.B.CMS = 1;
CTU_0.CLR[3]。B.B.CH_A = 14; /* ADC_0モジュール、チャンネル14 */
CTU_0.CLR[3].B.B.CH_B = 2; /* ADC_1 module, channel 2 */
CTU_0.CLR[3].B.B.CMS = 1;
CTU_0.CLR[4]。B.B.CH_A = 10; /* ADC_0モジュール、チャンネル10 */
CTU_0.CLR[4].B.B.CH_B = 15; /* ADC_1 module, channel 15 */
CTU_0.CLR[4].B.B.CMS = 1;
CTU_0.CLR[5]。B.B.CH_A = 15; /* ADC_0モジュール、チャンネル15 */
CTU_0.CLR[5].B.B.CH_B = 10; /* ADC_1 module, channel 10 */
CTU_0.CLR[5].B.B.CMS = 1;
CTU_0.CLR[6]。A.R = 0x4000; /* 最後のコマンド - このコマンドはADCに送信されません */
CTU_0.FTHです。B.TH0 = 5;
CTU_0.FTHです。B.TH0 = 5;
CTU_0.TH1.B.THRESHOLD0 = 0xE; /* FIFO 0 しきい値。最大値は 15 で、しきい値は FIFO 0 エントリの数より小さくなければなりません。*/
CTU_0.FCRのB.FIFO_OVERFLOW_EN0 = 1; /* FIFO 0 しきい値 オーバーフロー割り込み有効 - この割り込みで FIFO 0 を読み取ります */
CTU_0.EFRです。R = 0x0400;/*開始前にフラグをクリアする */
CTU_0.IFR.R = 0x01FE;
CTU_0.CRです。B.GRE = 1; /* 一般的なリロード有効 */
}//CTU_Init
/***********************************************************************/
/* ADC_Init */
/***********************************************************************/
void ADC_Init (void)
{
/* USE_ADC */
ADC_0.MCR.B.PWDN = 0; // Enable ADC0
/* 1 */
ADC_0.MCR.B.CTUEN = 1; // CTU mode
/* 2 */
ADC_0.NCMR[0]。R = 0xFFFF; ADC_0チャンネル0
ADC_0.MCRのB.モード = 1; ワンショットモード
ADC_1.MCR.B.PWDN = 0; // Enable ADC1
/* 1 */
ADC_1.MCR.B.CTUEN = 1; // CTU mode
/* 2 */
ADC_1.NCMR[0]。R = 0xFFFF; ADC_1チャンネル0
ADC_1.MCRです。B.モード = 1; ワンショットモード
} //ADC_Init
/***********************************************************************/
/* DMA_Init */
/***********************************************************************/
void DMA_Init (void)
{
DMA_0.CRです。R = 0x00000002;/* デバッグモードを有効にする */
DMA_0.EEIです。R = 0x0000;/* エラー割り込みはすべてのチャネルで無効 */
DMA_0.ERQ.B.ERQ0 = 1 << 2;/*チャネル2を使用 *//* eDMAリクエスト2 -> CTUトリガー FIFO_0を有効にします */
}//DMA_Init
/***********************************************************************/
/* DMA_MUX_Init */
/***********************************************************************/
void DMA_MUX_Init(void)
{
DMAMUX_0.CHCFG[2]です。R = 0x0000;/* チャネル設定レジスタ 2 をクリア*/
DMAMUX_0.CHCFG[2]です。B.ソース = 6;/* チャネル 2 の MUX ソースを選択 -> CTU FIFO_1 */
DMAMUX_0.CHCFG[2]です。B.ENBL = 1;/* DMAチャネルイネーブル */
}//DMA_MUX_Init
/***********************************************************************/
/* DMA_TCD_2 */
/***********************************************************************/
void DMA_TCD_2(void)
{
(*(揮発性uint16 *)&DMA_0.TCD[2])= 0x0;DMAをクリアします。TCD[0]0.ワード7
//DMA_0.TCD[2] = 0x0;
DMA_0.TCD[2].SADDR.B.SADDR = &CTU_0.FR[0]; /* Source Address - CTU FIFO_0 */
DMA_0.TCD[2]。お父さん。B.DADDR = (uint32_t) &ADC_results[0]; /* 宛先アドレス - SRAM */
DMA_0.TCD[2]。ATTRです。B.SMOD = 0x0; /* 送信元アドレスモジュロ */
DMA_0.TCD[2].ATTR.B.DMOD = 0x0; /* Destination Address Modulo */
DMA_0.TCD[2]。ATTRです。B.SSIZE = 0x2; /* ソース転送サイズ: 32 ビット*/
DMA_0.TCD[2]。ATTRです。B.DSIZE = 0x2; /* 宛先転送サイズ: 32 ビット*/
DMA_0.TCD[2]。SOFFです。B.SOFF = 0x0; /* 符号付きソース加算オフセット調整*/
DMA_0.TCD[2]。NBYTES です。MLOFFNOです。B.NBYTES = 0x40;/* 内部の「マイナー」バイトカウント */
DMA_0.TCD[2]。スラスト。B.SLAST = 0x0; /* 最後に署名された送信元アドレスを調整 */
DMA_0.TCD[2]。ドフ。B.DOFF = 0x4; /* 署名付き宛先アドレスオフセット */
DMA_0.TCD[2]。DLASTSGAです。B.DLASTSGA = 0xFFFFFFC0;/* 署名付き宛先アドレス オフセット -64 */
DMA_0.TCD[2]。かみつく。エリクノー。B.ELINK=0x0; /* マイナーループのチャンネル間リンク完了:無効*/
DMA_0.TCD[2]。かみつく。エリクノー。B.BITER = 0x1; /* 現在のメジャー反復回数またはリンクチャネル番号 */
DMA_0.TCD[2]。CITERです。エリンキーはい。B.ELINK=0x0; /* マイナーループのチャンネル間リンク完了:無効*/
DMA_0.TCD[2]。CITERです。エリンキーはい。B.LINKCH = 0x0; /* マイナーループでのチャンネル間リンクのチャンネル番号 : 未完成*/
DMA_0.TCD[2]。CITERです。エリンキーはい。B.ELINK = 0x0001; /* 現在のメジャー反復回数またはリンクチャネル番号 */
DMA_0.TCD[2]。CSR(社会貢献活動)。B.BWC = 0x00; /* 帯域幅制御 */
DMA_0.TCD[2]。CSR(社会貢献活動)。B.MAJORLINKCH = 0x00; /* メジャーチャンネル番号 */
DMA_0.TCD[2]。CSR(社会貢献活動)。B.MAJORELINK = 0x00; /*メジャーループのチャンネル間リンク完了:無効*/
DMA_0.TCD[2]。CSR(社会貢献活動)。B.DONE = 0x00; /* チャネル完了ビット */
DMA_0.TCD[2]。CSR(社会貢献活動)。B.アクティブ = 0x00; /* チャネルアクティブビット */
DMA_0.TCD[2]。CSR(社会貢献活動)。B.ESG = 0x00; /* スキャッター/ギャザーを有効にする: 無効*/
DMA_0.TCD[2]。CSR(社会貢献活動)。B.DREQ = 0x00; /* 完了時に DMA チャネルを無効にする: 無効*/
DMA_0.TCD[2]。CSR(社会貢献活動)。B.イントハーフ = 0x00; /* ハーフメジャーカウント完了時の割り込み:無効*/
DMA_0.TCD[2]。CSR(社会貢献活動)。B.INTMAJOR = 0x01; /* メジャーループ完了時の割り込み: 無効*/
DMA_0.TCD[2]。CSR(社会貢献活動)。B.スタート= 0x00; /* 明示的なチャンネル開始ビット */
}//DMA_0