This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28335:无法在 lash 存储器中配置 GPIO 引脚

Guru**** 2391415 points
Other Parts Discussed in Thread: TMS320F28335, TMDSDOCK28335, C2000WARE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/824936/tms320f28335-unable-to-configure-gpio-pins-in-lash-memory

器件型号:TMS320F28335
主题中讨论的其他器件: TMDSDOCK28335C2000WARE

我在 CCS v8.0中制作了一个代码、其中在 LED 上配置了 GPIO 34以测试闪存代码。 代码能够在 从 RAM 运行时打开 LED、但在从闪存运行时打开相同的代码 LED 未打开。 尽管出现错误、加载和验证过程已成功完成。 我甚至还尝试了 example_28335闪存代码,在该代码中,PWM 也不会生成。 硬件跳线是否存在任何问题或需要对代码执行什么操作?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Avichal、

    是的、器件具有引导模式。 根据施加到特殊"引导模式引脚"的电压、器件将进入哪种工作模式。 有关详细信息、请参阅文档。

    如果您希望从闪存引导、则需要配置您的硬件以执行此操作。 您使用的是什么硬件? 例如、F28335 controlCARD 使用 SW2对其进行配置、请参阅 controlCARD 用户指南的摘录。

    此致、
    Cody  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我使用的是带 TMS320F28335控制卡的 TMDSDOCK28335电路板。我已经尝试了用于引导至闪存的外部连接、即将引脚84、85、86、87连接至1、但情况仍然相同。 如果代码中有任何错误、我将附上我用于此代码的代码                                                    

    //包含的文件
    //
    #include "DSP28x_Project.h"    //器件头文件和示例 include 文件
    #include

    //
    //定义在哪个配置启用了 ePWM 计时器中断
    // PIE 级别:1 =启用、 0 =禁用
    //
    #define PWM1_INT_ENABLE 1.
    #define PWM2_INT_ENABLE 1.
    #define PWM3_INT_ENABLE 1.

    //
    //为每个计时器的周期定义
    //
    #define PWM1_TIMER_TBPRD  0x1FFF
    #define PWM2_TIMER_TBPRD  0x1FFF
    #define PWM3_TIMER_TBPRD  0x1FFF

    //
    //使其足够长,以便我们可以看到 LED 切换
    //
    #define DELAY 1000000L

    //
    //需要将从 RAM 运行的函数分配给
    //另一个段。  然后、将使用映射此段
    //链接器 cmd 文件。
    //
    #pragma CODE_SECTION (epwm1_timer_ISR、"ramfuncs");
    #pragma CODE_SECTION (epwm2_timer_ISR、"ramfuncs");

    //
    //函数原型
    //
    _interrupt void epwm1_timer_ISR (void);
    _interrupt void epwm2_timer_ISR (void);
    _interrupt void epwm3/timer_ISR (void);
    空 InitEPwmTimer (空);

    //
    //全局
    //
    uint32 EPwm1TimerIntCount;
    uint32 EPwm2TimerIntCount;
    uint32 EPwm3TimerIntCount;
    uint32 环计数;

    //
    //这些由链接器定义(请参阅 F28335.cmd)
    //
    extern UINT16 RamfuncsLoadStart;
    extern UINT16 RamfuncsLoadEnd;
    extern UINT16 RamfuncsRunStart;
    extern UINT16 RamfuncsLoadSize;

    //
    //主函
    //
    void main (void)

       //
       //步骤1. 初始化系统控制:
       // PLL、安全装置、启用外设时钟
       //此示例函数位于 DSP2833x_SYSCTRL.c 文件中。
       //
       InitSysCtrl();

       //
       //步骤2. 初始化 GPIO:
       //此示例函数位于 DSP2833x_GPIO.c 文件和中
       //说明了如何将 GPIO 设置为其默认状态。
       //
       //InitGpio(); //针对此示例跳过

       //
       //步骤3. 清除所有中断并初始化 PIE 矢量表:
       //禁用 CPU 中断
       //
       Dint;

       //
       //将 PIE 控制寄存器初始化为默认状态。
       //默认状态为禁用所有 PIE 中断和标志
       //被清除。
       //此函数位于 DSP2833x_PIECTRL.c 文件中。
       //
       InitPieCtrl();

       //
       //禁用 CPU 中断并清除所有 CPU 中断标志
       //
       IER = 0x0000;
       IFR = 0x0000;

       //
       //使用指向 shell 中断的指针初始化 PIE 矢量表
       //服务例程(ISR)。
       //这将填充整个表,即使是中断也是如此
       //在本例中未使用。  这对于调试很有用。
       //可以在 DSP2833x_DefaultIsr.c 中找到 shell ISR 例程
       //此函数可在 DSP2833x_PieVect.c 中找到
       //
       InitPieVectTable();

       //
       //此示例中使用的中断被重新映射到
       //此文件中的 ISR 函数。
       //
       EALLOW;         //这是写入 EALLOW 受保护寄存器所必需的
       PieVectTable.EPWM1_INT =&epwm1_timer_ISR;
       PieVectTable.EPWM2_INT =&epwm2_timer_ISR;
       PieVectTable.EPWM3_INT =&epwm3/timer_ISR;
       EDIS;   //这是禁止写入 EALLOW 受保护寄存器所必需的

       //
       //步骤4. 初始化所有器件外设:
       //此函数位于 DSP2833x_InitPeripherals.c 中
       //
       //InitPeripheral(); //本示例不需要
       InitEPwmTimer();   //对于本示例,只初始化 ePWM 计时器

       //
       //步骤5. 特定于用户的代码、启用中断
                 EALLOW;
                 GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
                 GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 0;
                 GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
                 GpioCtrlRegs.GPADIR.bit.GPIO31 = 1;
                 EDIS;
       //
       //将时间关键代码和闪存设置代码复制到 RAM
       //这包括以下 ISR 函数:epwm1_timer_isr ()、
       // epwm2_timer_isr (),epwm3_timer_isr 和 InitFlash();
       // RamfuncsLoadStart、RamfuncsLoadEnd 和 RamfuncsRunStart
       //符号由链接器创建。 请参阅 F28335.cmd 文件。
       //
       memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(uint32)&RamfuncsLoadSize);

       //
       //调用闪存初始化以设置闪存等待状态
       //此函数必须驻留在 RAM 中
       //
       InitFlash();

       //
       //初始化计数器
       //
       EPwm1TimerIntCount = 0;
       EPwm2TimerIntCount = 0;
       EPwm3TimerIntCount = 0;
       LoopCount = 0;

       //
       //启用连接到 EPWM1-3 INT 的 CPU INT3
       //
       IER |= M_INT3;

       //
       //在 PIE 中启用 ePWM INTn:组3中断1-3
       //
      PieCtrlRegs.PIEIER3.bit.INTx1 = PWM1_INT_ENABLE;
       PieCtrlRegs.PIEIER3.bit.INTx2 = PWM2_INT_ENABLE;
       PieCtrlRegs.PIEIER3.bit.INTx3 = PWM3_INT_ENABLE;

       //
       //启用全局中断和更高优先级的实时调试事件
       //
       EINT;  //启用全局中断 INTM
       ERTM;  //启用全局实时中断 DBGM
       GpioDataRegs.GPBSET.BIO34 = 1;
         //
       //步骤6. 空闲循环。 只需坐下来循环(可选)
       //


    //
    // InitEPwmTimer -
    //
    无效
    InitEPwmTimer (空)

       EALLOW;
       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=0;     //停止所有 TB 时钟
       EDIS;

       //
       //设置同步
       //
       EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; //直通
       EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; //直通
       EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; //直通

       //
       //允许同步每个计时器
       //
       EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;
       EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
       EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;

       EPwm1Regs.TBPHS.Half.TBPHS = 100;
       EPwm2Regs.TBPHS.Half.TBPHS = 200;
       EPwm3Regs.TBPHS.Half.TBPHS = 300;

       EPwm1Regs.TBPRD = PWM1_TIMER_TBPRD;
       EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;   //向上计数
       EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;    //选择零事件时的 INT
       EPwm1Regs.ETSEL.bit.INTEN = PWM1_INT_ENABLE; //启用 INT
       EPwm1Regs.ETPS.bit.INTPRD = et_1st;          //在发生第一个事件时生成 INT


       EPwm2Regs.TBPRD = PWM2_TIMER_TBPRD;
       EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;    //向上计数
       EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     //启用零事件上的 INT
       EPwm2Regs.ETSEL.bit.INTEN = PWM2_INT_ENABLE;  //启用 INT
       EPwm2Regs.ETPS.bit.INTPRD = et_2nd;           //在发生第二个事件时生成 INT


       EPwm3Regs.TBPRD = PWM3_TIMER_TBPRD;
       EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;   //向上计数
       EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;    //启用零事件上的 INT
       EPwm3Regs.ETSEL.bit.INTEN = PWM3_INT_ENABLE; //启用 INT
       EPwm3Regs.ETPS.bit.INTPRD = et_3rd;         //在第三个事件发生时生成 INT

       EALLOW;
       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=1;      //启动所有已同步的计时器
       EDIS;
       GpioDataRegs.GPBSET.BIO34 = 1;


    //
    // epwm1_timer_ISR -此 ISR 必须从 RAM 中执行、因为它将放置闪存
    //进入睡眠中断例程在该示例中使用
    //
    _interrupt void
    epwm1_timer_ISR (空)

       //
       //将闪存置于睡眠状态
       //
       EALLOW;
       FlashRegs.FPWR.bit.PWR = FLASH_SLEEP;
       EDIS;
       EPwm1TimerIntCount++;


       GpioDataRegs.GPBSET.BIO34 = 1;

       //
       //清除此计时器的 INT 标志
       //
       EPwm1Regs.ETCLR.bit.INT = 1;

       //
       //确认此中断以接收来自组3的更多中断
       //
       PieCtrlRegs.PIEACX.ALL = PIEACK_Group3;


    //
    // epwm2_timer_ISR -此 ISR 必须从 RAM 执行、因为它将放置
    //闪存进入待机状态
    //
    _interrupt void
    epwm2_timer_ISR (空)

       EPwm2TimerIntCount++;

       //
       //将闪存置于待机状态
       //
       EALLOW;
       FlashRegs.FPWR.bit.PWR = FLASH_STANDBY;
       EDIS;
       GpioDataRegs.GPBSET.BIO34 = 1;
       //
       //清除此计时器的 INT 标志
       //
       EPwm2Regs.ETCLR.bit.INT = 1;

       //
       //确认此中断以接收来自组3的更多中断
       //
       PieCtrlRegs.PIEACX.ALL = PIEACK_Group3;


    //
    // epwm3_timer_ISR -
    //
    _interrupt void
    epwm3_timer_ISR (空)

       uint16 i;

       EPwm3TimerIntCount++;

       //
       //短延迟以模拟某些 ISR 代码
       //
       对于(I = 1;I < 0x01FF;I++)
       {
           
       }




                 GpioDataRegs.GPBSET.BIO34 = 1;

       //
       //清除此计时器的 INT 标志
       //
       EPwm3Regs.ETCLR.bit.INT = 1;

       //
       //确认此中断以接收来自组3的更多中断
       //
       PieCtrlRegs.PIEACX.ALL = PIEACK_Group3;


    //
    //文件结束
    //

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Avichal、

    从一个示例开始、了解它的功能、然后尝试对您的代码执行相同的操作或将您的代码合并到示例中。

    一个很好的示例是 C2000Ware。 请查看:C:\ti\c2000\C2000Ware_2_00_00_02\device_support\F2833x\examples\flash_F28335

    您还应查看 F2833x 微控制器技术讲座 https://training.ti.com/c2000-f2833x-microcontroller-workshop?cu=1137791的第10部分。 它介绍了如何将 RAM 示例移动到闪存中。

    此致、
    Cody  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已经尝试过您建议的代码示例

    C2000Ware。 请查看:C:\ti\c2000\C2000Ware_2_00_00_02\device_support\F2833x\examples\flash_F28335

    但正如我之前所说的、代码已成功刷写到器件中、引脚84-87连接到1。 仍然没有从任何 GPIO 引脚生成 PWM。 后来、我添加了 GPIO 34 (LED 引脚)的代码作为输出为1、但 LED 不亮。 将代码刷写到器件中。  

    我已经介绍了实验课程代码的第10节、但我在闪存代码实现中观察到的变化不像我所做的那样。 请帮助我了解其他哪些内容以使其正常工作。

    此致、

    Avichal

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Avichal、

    在该示例中、未设置 PWM 输出。 如果您希望发生这种情况、则需要配置 GPIO。

    不过、该示例应切换 GPIO32、如果代码从闪存正确运行、您应该能够看到切换。 是否可以确认 GPIO32正在切换?

    此致、
    Cody  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    否、GPIO32未切换。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    有一个观察结果表明、当使用 header_nonbios.cmd 文件来构建代码时、LED 闪烁、但当使用 F28335.cmd 文件时、LED 不闪烁。 那么、我应该继续 使用 Header_nonbios.cmd 文件吗?

    此致、

    Avichal

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Avichal、

    您需要在您的 cmd 文件中配置几个东西来使加载到闪存中的程序工作。

    请查看以下研讨会中的第10部分。 这将帮助您解决您遇到的任何问题。

    此致、
    Cody