C2000 launchpad 调试中碰到很奇怪的问题,望高手解惑
在用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; ,加载完成,全速运行(不需单步),能够实现预期效果。
以上问题,久思不得其解,还望高手解惑,谢谢!
效果是眼睛观察,还是仪器测量?
[ 本帖最后由 蓝雨夜 于 2013-1-21 15:16 编辑 ]
楼主可以设置的再慢一点1-2S试下,也许是你的灯闪的太快,你眼睛无法分辨。
回复 沙发 蓝雨夜 的帖子
眼睛观察,其实while(1)里面的延时0.5s完全足够了。还有就是通过CCS5.3的变量观察窗口查看的GpioDataRegs.GPADAT.bit.GPIOx的值,这个应该不存在太快,眼睛分辨不出来的问题。
简单来说,就是程序加载到ram后,我在4个 led初始化语句的后面语句上加个断点,然后全速运行至断点,这时通过变量观察窗口查看GpioDataRegs.GPADAT.bit.GPIOx的值,发现同预期效果不同(当然板载led灯也是显示同样的效果)。
[ 本帖最后由 cools1860 于 2013-1-21 16:11 编辑 ]
回复 板凳 安_然 的帖子
0.5s的延时应该可以了,我一会测试下2s的
回复 楼主 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个或者更少,都不能够出现预期效果。
C28的CPU,对DATA寄存器的操作就需要好几个周期。DATASHEET中有交待。在介绍汇编指令那里具体说明了它在什么状态下寄存器内容可用
回复 7楼 dontium 的帖子
嗯,谢谢版主的回复,能否告知你所说的文档名,我在数据手册里面没有看到。
[ 本帖最后由 cools1860 于 2013-1-21 21:48 编辑 ]
《TMS320F2802x/TMS320F2802xx Piccolo System Control and Interrupts Reference Guide》
《TMS320C28x Assembly Language Tools User's Guide》
回复 10楼 dontium 的帖子
3q very hardly
我找找看
首先感谢各位的热情相助,我把问题的主要点做下简要概述:
在版主提到的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 编辑 ]
回复 8楼 常见泽1 的帖子