最近要用5509A做一些工作,平日里很少使用DSP,这次算是比较系统的来使用DSP了。当我浏览一些例程的时候发现对寄存器操作的时候都是调用的CSL封装好的库,这样确实挺方便的,直接套寄存器和值就好了,但是一个对DSP陌生的新手来说,什么时候该使用什么样的CSL库又该怎样操作这些库呢,确实挺苦恼的,起码我是挺郁闷的,到底该用哪个库函数。当然也可以直接在CSL库函数说明文档里一个一个去查,这样也挺麻烦的。我就想可不可以不调用库函数,而是直接操作寄存器。
方法还是有的。我想到在Linux系统中对寄存器操作是直接定义宏定义的,比如:#define A (*(volatial unsigned long *)B)的形式,那么在DSP中是不是也是可以的呢?
我用操作GPIO来做实验。实验效果闪烁一个灯。
最初的代码:
#define IODIR (*(unsigned long *)0x3400)
#define IODATA (*(unsigned long *)0x3401)
main()
{
/*初始化CSL库*/
CSL_init();//初始化CSL,使用任何CSL函数前必须初始化,只需初始化一次
PLL_config(&myConfig);
/*确定方向为输出*/
IODIR = 0xFF;
while(1)
{
IODATA = 0x040;
delay();
IODATA = 0x00;
delay();
}
}
void delay()
{
Uint32 j = 0,k = 0;
for(j = 0;j<0x30;j++)
{
for(k= 0;k<0xffff;k++)
{}
}
}
下载运行。。。不成功!!!
郁闷,为何不行呢?于是我顺着操作GPIO用的库函数GPIO_RSET一直找下去,终于发现了秘密:在CSL_stdhal.h文件中发现了这么一行:#define PREG16(addr) (*(volatile ioport Uint16*)(addr))
原来玄机在这里,于是我修改代码:
#define IODIR (*(volatile ioport unsigned short *)0x3400)
#define IODATA (*(volatile ioport unsigned short *)0x3401)
其他不变,下载运行。。。OK!灯是闪烁的。窃喜!对比之前的宏定义发现亮点不同:1。添加了“ioport” 2、是unsigned short型。我又试了unsigned int,unsigned char都可行,唯独unsigned long型不行,我猜测是寄存器地址是16位的不能用大于16位的类型定义。但是不明白这里的ioport是何意?
于是我想到了CCS的编译器,猜测是没加ioport时编译器不能识别我所定义的地址指针也就不能将数据写入地址,加了ioport就可以识别了。但是怎么来证明我的猜想。
于是去官网查找关于编译器的文档,终于被我找到了
ioport是我们访问IO空间的关键字,可用于2x,2xx,5x系列的编译器,看类型,必须是char,short,int跟我之前实验的结果是一样的
到这里就可以做个结论了:ioport是编译器识别端口寄存器地址的关键字也就是识别标志,类型必须是char,short,int,那么以后操作寄存器就可以不用调用库函数,直接宏定义进行操作就可以了。(必要的时候还是要调用的)