1109078_zh-CN

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

1109078_zh-CN

1109078_zh-CN

由 eTimer0 GSH614 触发的 MPC5744P CTU 示例<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

********************************************************************************

* 详细说明:

* 此示例显示如何使用从 eTimer0 模块通道 2 触发的 CTU 模块。

*

* 有关 CTU 工作原理的详细信息,我建议您查看应用说明

*MPC5643LPWM_ADC_概念

* https://community.freescale.com/docs/DOC-102559

*

* 此示例设置 eTimer0 通道 2 用于 PWM 信号生成。

* 该信号用于将 MSR 触发信号发送到 CTU 模块

* 示例还包含简单的 CTU 模块驱动程序初始化

* CTU 调度器子模块根据 CTU 触发器通过外部引脚进行切换

*

* ------------------------------------------------------------------------------

* Test HW:  MPC57xx Motherboard + MPC5744PE257DC minimodule, MPC5744P,

* 硅掩模套装 1N65H

* 目标:internal_FLASH*

********************************************************************************

原始附件已移至: Example-MPC5744P-CTU-eTimer-v1_1-GHS614.zip

回复:由 eTimer0 GSH614 触发的 MPC5744P CTU 示例<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Hi,

我们也遇到过类似的问题。有任何推荐的解决方案吗?

多谢!

回复:由 eTimer0 GSH614 触发的 MPC5744P CTU 示例<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Hi Linuxz

我们最近确实遇到了类似的问题,您解决了吗?您能就此问题向我们提供一些反馈吗?

先行致谢。

回复:由 eTimer0 GSH614 触发的 MPC5744P CTU 示例<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

[Peter] – 嗯,如果在已经有命令正在处理时发出 ADC 命令,则会设置 ADC_OE 标志(ADC 命令生成溢出错误)。

我觉得你的CTU命令列表存在时序问题。你写道:“我有时可以看到第一个命令是由ADC执行的”。有时这意味着什么?是指当占空比发生变化时,或者当这种情况发生时,情况会有什么不同。

回复:由 eTimer0 GSH614 触发的 MPC5744P CTU 示例<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Hi,

我对 MPC5744P 的 CTU 有疑问,我在 FlexPWM_0 上设置了 3 个同步 PWM 信号来控制 PMSM 电机。

为了控制该电机,我还需要测量 PWM 周期中特定位置的电流。

我尝试设置 PWM 子模块 0 来生成 OUT_TRIG0,并配置 CTU 以在 ADC 上启动双重转换,但由于我需要在我的设计中转换更多的模拟信号,所以我创建了一个 CTU 应该发送到 ADC 的命令列表。

当 6 个命令完成后,dma 传输将把数据移动到我的阵列中。

但有些地方不对劲,我有时可以看到第一个命令由 ADC 执行,结果移回到 CTU FIFO,但之后一切似乎都停止了,并且在 CTU 中设置了 ADC_OE 和 ERRCMP 标志。

关于我的代码出了什么问题,有什么提示吗?

请参阅下面的我的代码,找不到附加它的方法。

谨致问候 Linus

#包括“mpc55xx.h”

#包括“pwm_driver.h”

/* ************************************************************************** *

* 全局声明 *

* ************************************************************************** */

uint32_t ADC_结果[16];

/**

* @brief 设置PWM占空比

* @Param chn1 无符号值,包含通道 1 的占空比,范围为 0 至 1000

* @Param chn2 无符号值,包含通道 2 的占空比,范围为 0 至 1000

* @Param chn3 无符号值,包含通道 3 的占空比 0 至 1000

* @return boolean 值,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].CTRL2.B.重新加载_SEL = 0;

FLEXPWM_0.SUB[1].CTRL2.B.RELOAD_SEL = 1; /* 来自子模块 0 的 RELOAD 信号用于重新加载寄存器*/

FLEXPWM_0.SUB[2].CTRL2.B.RELOAD_SEL = 1; /* 来自子模块 0 的 RELOAD 信号用于重新加载寄存器*/

FLEXPWM_0.SUB[0].CTRL2.B.CLK_SEL = 0; /* 外设时钟作为本地预分频器和计数器的时钟。*/

FLEXPWM_0.SUB[1].CTRL2.B.CLK_SEL = 2; /* 子模块 0 的时钟 (AUX_CLK) 用作本地预分频器和计数器的源时钟。*/

FLEXPWM_0.SUB[2].CTRL2.B.CLK_SEL = 2; /* 子模块 0 的时钟 (AUX_CLK) 用作本地预分频器和计数器的源时钟。*/

// FLEXPWM_0.SUB[0].CTRL2.B.FORCE_SEL = 0; /* 外设时钟用作本地预分频器和计数器的时钟。*/

// FLEXPWM_0.SUB[1].CTRL2.B.FORCE_SEL = 1; /* 子模块 0 的时钟 (AUX_CLK) 用作本地预分频器和计数器的源时钟。*/

// FLEXPWM_0.SUB[2].CTRL2.B.FORCE_SEL = 1; /* 子模块 0 的时钟 (AUX_CLK) 用作本地预分频器和计数器的源时钟。*/

// FLEXPWM_0.SUB[0].CTRL2.B.INIT_SEL = 0; /* 外设时钟用作本地预分频器和计数器的时钟。*/

// FLEXPWM_0.SUB[1].CTRL2.B.INIT_SEL = 1; /* 子模块 0 的时钟 (AUX_CLK) 用作本地预分频器和计数器的源时钟。*/

// FLEXPWM_0.SUB[2].CTRL2.B.INIT_SEL = 1; /* 子模块 0 的时钟 (AUX_CLK) 用作本地预分频器和计数器的源时钟。*/

FLEXPWM_0.SUB[0].DISMAP.R = 0x0000; /* 禁用故障引脚条件 */

FLEXPWM_0.SUB[1].DISMAP.R = 0x0000; /* 禁用故障引脚条件 */

FLEXPWM_0.SUB[2].DISMAP.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; /* 当计数器值与 VAL0 值匹配时,OUT_TRIG0 将设置。*/

  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.运行 |= 1 << 0;

FLEXPWM_0.MCTRL.B.运行 |= 1 << 1;

FLEXPWM_0.MCTRL.B.运行 |= 1 << 2;

/** 启用 PWM */

  Enable_pwm();

}

/***********************************************************************/

/* CTU_初始化 */

/***********************************************************************/

void CTU_Init (void)

{

CTU_0.TGSISR.B.I1_RE = 0x1; /* 为 CTU 选择 MRS - PWM ch0 奇数 - 周期 50usec */

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 命令列表 - 第一个命令地址 */

//(*(volatile 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].ABCH = 5; /* ADC_0 模块,通道 11 */

  //CTU_0.CLR[0].B.B.CMS = 0;

  //CTU_0.CLR[0].B.B.LC = 1;

CTU_0.CLR[0].BBCH_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].BBCH_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].BBCH_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].BBCH_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].BBCH_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].BBCH_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].AR = 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_初始化

/***********************************************************************/

/* ADC_初始化 */

/***********************************************************************/

void ADC_Init (void)

{

/* 使用_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.MODE = 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.MODE = 1; //单次模式

} //ADC初始化

/***********************************************************************/

/* 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_初始化

/***********************************************************************/

/* DMA_MUX_初始化 */

/***********************************************************************/

void DMA_MUX_Init(void)

{

DMAMUX_0.CHCFG[2].R = 0x0000; /*清除通道配置寄存器2*/

DMAMUX_0.CHCFG[2].B.SOURCE = 6; /* 为通道 2 选择 MUX 源 -> CTU FIFO_1 */

DMAMUX_0.CHCFG[2].B.ENBL = 1; /* DMA 通道使能 */

//DMA_MUX_初始化

/***********************************************************************/

/* DMA_TCD_2                                                           */

/***********************************************************************/

void DMA_TCD_2(void)

{

(*(volatile uint16 *)&DMA_0.TCD[2]) = 0x0; //清除DMA.TCD[0]0.WORD7

    //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].DADDR.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].SLAST.B.SLAST = 0x0; /* 最后签名的源地址调整 */

DMA_0.TCD[2].DOFF.B.DOFF = 0x4; /* 有符号目标地址偏移 */

DMA_0.TCD[2].DLASTSGA.B.DLASTSGA = 0xFFFFFFC0; /* 有符号目标地址偏移量 -64 */

DMA_0.TCD[2].BITER.ELINKNO.B.ELINK = 0x0; /* 小循环完成时的通道间链接:禁用*/

DMA_0.TCD[2].BITER.ELINKNO.B.BITER = 0x1; /* 当前主迭代计数或链路通道号 */

DMA_0.TCD[2].CITER.ELINKYES.B.ELINK = 0x0; /* 小循环完成时的通道间链接:禁用*/

DMA_0.TCD[2].CITER.ELINKYES.B.LINKCH = 0x0; /* 小循环上通道间链接的通道号:未完成*/

DMA_0.TCD[2].CITER.ELINKYES.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.ACTIVE = 0x00; /* 通道活动位 */

DMA_0.TCD[2].CSR.B.ESG = 0x00; /* 启用分散/聚集:禁用*/

DMA_0.TCD[2].CSR.B.DREQ = 0x00; /* 完成时禁用DMA通道:禁用*/

DMA_0.TCD[2].CSR.B.INTHALF = 0x00; /* 半主计数完成中断:禁用*/

DMA_0.TCD[2].CSR.B.INTMAJOR = 0x01; /* 主循环完成中断:禁用*/

DMA_0.TCD[2].CSR.B.START = 0x00; /* 显式通道启动位 */

//DMA_0

Tags (1)
No ratings
Version history
Last update:
‎01-06-2026 01:27 AM
Updated by: