DSP

DSP实验剖析系列:实验1 LED流水灯 (本实验基于TMS320F28335芯片)

2019-07-13 10:25发布

实验1  LED流水灯 首先直接贴上程序: #include "DSP2833x_Device.h" #include "DSP2833x_Examples.h" #define LED1 GpioDataRegs.GPADAT.bit.GPIO0 #define LED2 GpioDataRegs.GPADAT.bit.GPIO1 #define LED3 GpioDataRegs.GPADAT.bit.GPIO2 #define LED4 GpioDataRegs.GPADAT.bit.GPIO3 #define LED5 GpioDataRegs.GPADAT.bit.GPIO4 void configtestled(void); void main(void) { InitSysCtrl(); configtestled(); InitXintf16Gpio(); DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); LED1=0; DELAY_US(10); LED2=0; DELAY_US(10); LED3=0; DELAY_US(10); LED4=0; DELAY_US(10); LED5=0; DELAY_US(10); while(1) { LED1=~LED1; DELAY_US(100000); LED2=~LED2; DELAY_US(100000); LED3=~LED3; DELAY_US(100000); LED4=~LED4; DELAY_US(100000); LED5=~LED5; DELAY_US(100000); } } void configtestled(void) { EALLOW; GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0; GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 0; GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0; GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; EDIS; } 接下来我们对上述程序进行详细剖析: 第1-2行: 这两行是对头文件的声明,表示在本程序中会用到头文件“DSP2833x_Device.h”和“DSP2833x_Examples.h”。 一般的DSP程序基本上都会用到这两个头文件,TI(德州仪器官方)为DSP开发者提供了头文件库,如果大家在开发的时候害怕漏掉某个头文件,那么建议为每一个工程都把TI官方的头文件添加上到工程中,并在*.C源文件中声明,这样是最为保险的操作。 第4-8行: 这几行是宏定义。 DSP28335共有88个GPIO口也就是通用输入输出口,每一个GPIO口的状态都是通过它们各自的寄存器实现的,我们选择其中的5个口来连接LED发光二极管,那么通过程序的方式更改这5个GPIO对应的寄存器状态,就可以对GPIO管脚的状态进行操纵。 可以看到每一个GPIO口的寄存器名字是很长的,比如GPIO0寄存器的名字是“GpioDataRegs.GPADAT.bit.GPIO0”,这在后期编程过程中是非常繁琐的,因此可以通过宏定义的方式,将GPIO0寄存器用另一个名字“LED1”替代,这样在后面代码的编辑过程中就可以用“LED1”代替原本的那个冗长的名字。 第11行: 对configtestled函数进行声明,此函数的具体结构体在第57-73行给出,具体作用会在后面进行详细说明,在这里只需要知道调用了这个函数,目的是初始化GPIO口。 第13行: 这里正式开始编写主函数。 第15行: 在主函数中首先调用了InitSysCtrl函数,此函数是DSP系统的初始化函数,作用是对F28335系统进行初始化。 这里对系统初始化函数做一个说明,系统初始化函数能为DSP芯片正常运行提供基本条件,例如分配时钟信号等,比方说,我想让系统在开始上电之后运行在150MHz的频率,那就要对系统初始化函数中设立倍频和分频系数,同时还要对EVA、EVB、SCI等的时钟使能进行设置。 第17行: 对configtestled函数进行调用,此函数详细功能会在后面给出。 第19行: 对InitXintf16Gpio函数进行调用,此函数在源文件"DSP2833x_Xintf.c"中被定义,这个源文件是TI公司自带的文件,一般在工程建立过程中加入到工程即可,如有特殊需要可对其进行修改。 InitXintf16Gpio函数为总线初始化函数。 第21行: DINT为汇编语句,其作用是禁止CPU全局中断。 第23行: 调用InitPieCtrl函数,这个函数存放在源文件“DSP2833x_PieCtrl.c”中,也是TI公司自带的一个源文件,其作用是初始化PIE中断控制寄存器到默认状态,默认状态是禁止PIE中断及清除所有PIE中断标志。 第25-26行: 禁止CPU中断和清除所有CPU中断标志。 第28行: 初始化PIE中断向量表,并使其指向中断服务子程序(ISR)。
这些中断服务子程序被放在了DSP280x_DefaultIsr.c源文件中,这个函数放在了DSP2833x_PieVect.c源文件里面。 第30-39行: LED发光二极管状态初始化。 比如说:LED1=0,那就是说在初始时刻GPIO0为低电平,发光二极管灭DELAY_US表示经过一小段时间的延时,这个地方不用延时其实也是可以的,但是用上延时系统会更加稳定。 第41-53行: while(1)表示让程序一直在循环体内执行,反复执行,跳不出来(除非遇上中断,但是这个程序没有中断)。 LED1=~LED1表示对LED1此时的状态取反,假如原来的LED1低电平,对应的发光二极管是灭的,那么现在LED1转变成高电平,对应发光二极管点亮。 DELAY_US(100000)表示经过一定时间的延时。 那么到下一个循环周期的时候再取反由亮变灭,再延时。所以总体的效果就是:灭——延时——亮——延时——灭——延时——亮——延时——灭......无穷无尽,永不停止。 第57-73行: configtestled是GPIO的初始化函数,这一部分可以在单独的.C源文件里单独定义,在本例程中直接在LED.C文件里进行定义。其功能是初始化GPIO,使得GPIO的引脚处于已知状态,例如确定其功能是特定功能还是通用I/O功能,如果是通用I/O,则其是输入还是输出等等。 GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0 //把GPIO0设置为通用IO功能
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1// GPIO0设置为输出引脚,用来对外输出信号   其实上面说了那么多,真正对LED的控制起实际作用的只有第41-53行,剩下的都是对DSP系统进行初始化的语句。这个例子说明了对DSP进行初始化很重要,即使是一个很简单的流水灯程序,初始化工作一步都不能少。 DSP进行流水灯操作是大材小用,鲜花插在牛粪上,但是这个例程对初学者理解DSP编程与运行方式有着重要意义。 此文章为CSDN博主胖小子的小胖子原创文章,也就是本人的原创文章,如果想要转载请标明出处。 希望大家能够在下方多多评论,多提出意见和建议,有不正确的地方还请高人指出,让我们共同学好DSP,共同进步。