C2000 launchpad 调试中碰到很奇怪的问题,望高手解惑

cools1860   2013-1-21 14:57 楼主
在用C2000 launchpad (tms320f28027)测试板载led时,碰到如下问题:
1.功能描述:实现4个led灯的交替闪烁,led2、led3同时亮灭,led3、led5同时灭亮
2.实现代码:

int main(void)
{
        InitSysCtrl();  // 系统初始化子程序,在F28_sysctrl.c中
        InitGpio();//初始化GPIO,已经把GPIO0~GPIO3初始化为GPIO,OUTPUT

        DINT;

        InitPieCtrl();//初始化PIE控制器
        IER = 0x0000;
        IFR = 0x0000;
        InitPieVectTable();//初始化PIE向量表
        //led状态初始化语句
        GpioDataRegs.GPADAT.bit.GPIO0 = 1;//初始状态,led2灭
        GpioDataRegs.GPADAT.bit.GPIO1 = 0;//初始状态,led4亮
        GpioDataRegs.GPADAT.bit.GPIO2 = 1;//初始状态,led3灭
        GpioDataRegs.GPADAT.bit.GPIO3 = 0;//初始状态,led5亮


        while(1)
        {
                int i;
                for(i=0;i<50;i++)
                {
                        DELAY_US(10000L);//10ms
                }
                LED0_TOGGLE = 1;//宏定义,反转寄存器
                LED1_TOGGLE = 1;
                LED2_TOGGLE = 1;
                LED3_TOGGLE = 1;
                       
        }

}

3.出现的问题:
    ccs5.3中调试程序,把程序加载到ram中运行后,点击全速运行(resume,F8),不能够实现预期效果,而是4个led同时亮灭。通过观察窗口查看GpioDataRegs.GPADAT.bit.GPIO0 ~GpioDataRegs.GPADAT.bit.GPIO03的值,发现主循环前的led初始化语句没有起作用。
    尝试(1):加载完成,在led初始化语句之前加断点,然后单步运行完这四句初始化语句后,再全速运行,能够实现预期效果。
    尝试(2):把led初始化语句换成,GpioDataRegs.GPADAT.all=GpioDataRegs.GPADAT.all |0xfffffff5; ,加载完成,全速运行(不需单步),能够实现预期效果。

以上问题,久思不得其解,还望高手解惑,谢谢!

回复评论 (12)

效果是眼睛观察,还是仪器测量?

[ 本帖最后由 蓝雨夜 于 2013-1-21 15:16 编辑 ]
点赞  2013-1-21 15:13
楼主可以设置的再慢一点1-2S试下,也许是你的灯闪的太快,你眼睛无法分辨。
工程 = 数学+物理+经济
点赞  2013-1-21 15:41

回复 沙发 蓝雨夜 的帖子

眼睛观察,其实while(1)里面的延时0.5s完全足够了。还有就是通过CCS5.3的变量观察窗口查看的GpioDataRegs.GPADAT.bit.GPIOx的值,这个应该不存在太快,眼睛分辨不出来的问题。
简单来说,就是程序加载到ram后,我在4个 led初始化语句的后面语句上加个断点,然后全速运行至断点,这时通过变量观察窗口查看GpioDataRegs.GPADAT.bit.GPIOx的值,发现同预期效果不同(当然板载led灯也是显示同样的效果)。

[ 本帖最后由 cools1860 于 2013-1-21 16:11 编辑 ]
  • expression.jpg
点赞  2013-1-21 15:51

回复 板凳 安_然 的帖子

0.5s的延时应该可以了,我一会测试下2s的
点赞  2013-1-21 15:52

回复 楼主 cools1860 的帖子

发完帖子我又进行了如下测试:
尝试(3):把led初始化语句改为如下:
        GpioDataRegs.GPADAT.bit.GPIO0 = 1;
       
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");//间隔时间至少5个空周期,一个不能少。
       
        GpioDataRegs.GPADAT.bit.GPIO1 = 0;
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");
       
        GpioDataRegs.GPADAT.bit.GPIO2 = 1;
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");

        GpioDataRegs.GPADAT.bit.GPIO3 = 0;
编译加载完程序,直接全速运行,出现预期效果。这是否能够说明,对同一GPIO数据寄存器的两次操作必须保证一定的时间间隔,否则赋值无效或者是cpu处理不过来。
注意:上面的空指令必须至少5个,如果改为4个或者更少,都不能够出现预期效果。
点赞  2013-1-21 15:57
C28的CPU,对DATA寄存器的操作就需要好几个周期。DATASHEET中有交待。在介绍汇编指令那里具体说明了它在什么状态下寄存器内容可用
点赞  2013-1-21 17:01
楼主善于思考
点赞  2013-1-21 20:23

回复 7楼 dontium 的帖子

嗯,谢谢版主的回复,能否告知你所说的文档名,我在数据手册里面没有看到。

[ 本帖最后由 cools1860 于 2013-1-21 21:48 编辑 ]
点赞  2013-1-21 21:40
《TMS320F2802x/TMS320F2802xx Piccolo System Control and Interrupts Reference Guide》

《TMS320C28x Assembly Language Tools User's Guide》
点赞  2013-1-21 21:50

回复 10楼 dontium 的帖子

3q very hardly 我找找看
点赞  2013-1-21 22:08
首先感谢各位的热情相助,我把问题的主要点做下简要概述:
在版主提到的datasheet 《TMS320F2802x/TMS320F2802xx Piccolo System Control and Interrupts Reference Guide》中的第76页,很详细的提到了一楼所出现的问题。详细解释请参考文档。我仅对问题的解决方式做简要总结:
1.如果使用GPxDATA寄存器来write pins状态,对同一GPIO组的数据寄存器的两次操作之间必须插入几个周期的NOP或直接调用us延时函数。如下:
        GpioDataRegs.GPADAT.bit.GPIO1 = 0;
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");
        asm ("      NOP");      
        GpioDataRegs.GPADAT.bit.GPIO2 = 1;
2.使用GPxSET/GPxCLEAR/GPxTOGGLE寄存器来操作,这样就能避免使用GPxDATA寄存器带来的麻烦。

再次感谢各位的帮忙,谢谢版主。



[ 本帖最后由 cools1860 于 2013-1-22 10:42 编辑 ]
  • lag
点赞  2013-1-22 10:24

回复 8楼 常见泽1 的帖子

点赞  2013-1-22 10:27
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复