欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Ti的C28x系列的DSP(28069)使用经验,SPI通讯经验

程序员文章站 2024-03-17 23:41:46
...

本人使用SPI通讯经验不多,当初是为了实现DSP与FPGA之间的通讯,DSP在SPI通讯中作主机,SPI数据位数为16位模式。SPI的原理我不多说了,我对这种通讯的方式理解,这是一种高速通讯,同时还有个特点,就是接收了多少位数据的同时意味着发送了多少位数据,比如你希望接收2个字节的数据,那么你应该发送2个字节的数据,发送数据就意味着接收数据,接收数据就意味着发送数据,关键看你需要的是接收还是发送的数据。嘿嘿,有点像绕口令。

本文提出的SPI通讯也是基于FIFO的轮询方式,这种SPI函数要么在DSP架构中的主中断,或者主循环中运行。

关于SPI的CS引脚,我这里用的是SPI自带的CS引脚,简而言之,不是普通的IO引脚,为啥我不用普通的IO引脚,是因为我用了之后,我用示波器观看,SPI的CLK信号还没结束,充当CS的IO引脚已经拉高了,然后我增加延时,效果不显著,这延时会随不同SPI读写的数据长度的改变而改变,实在太麻烦了,最终我没有选择这种CS引脚的使用方式。如果使用普通的IO引脚,大部分人是这么做的,在SPI函数之前将充当CS的IO引脚拉低,然后在在SPI函数之后将充当CS的IO引脚拉高,我用的也是这种办法,但会出现上述的问题。

所以我干脆把GPIO配置成SPI的CS引脚,让SPI自动控制,不过我这种用法,SPI读写的字节数不过超过FIFO的级数,可怜的DSP28069,只有4级FIFO,而DSP28377D有16级的FIFO。

代码:

  • SPI初始化;
void InitSpia(void)
{
	SpiaRegs.SPICCR.bit.SPISWRESET = 1;		//Clear the SPI Software Reset bit to force 
                                            //the SPI to the reset state
	SpiaRegs.SPICCR.bit.SPILBK = 0;			//loopback mode
	SpiaRegs.SPICCR.bit.SPICHAR = 0xf;		//data format  16bit mode


	SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;	//spi master
	SpiaRegs.SPICTL.bit.TALK = 1;			//enable transmit

	SpiaRegs.SPICTL.bit.CLK_PHASE = 0;		//transmit on falling edge,receives on rising
	SpiaRegs.SPICCR.bit.CLKPOLARITY = 1;    //When no SPI data is sent, SPICLK is at high 
                                            //level
                                          


	SpiaRegs.SPIBRR =0x0001;	//SPI波特率=20M/4	=5Mhz;
	SpiaRegs.SPIPRI.bit.FREE = 1;  // *运行


	DELAY_US(10);

	SpiaRegs.SPIFFTX.all=0xE040;//使能FIFO;清除发送中断标志位;禁止FIFO发送中断;
								//发送中断级别定义为0;
	SpiaRegs.SPIFFRX.all=0x204f;//清除FF溢出标志位;清除溢出接受中断标志位;禁止
								//FF接受中断;接受中断级别为16;
	SpiaRegs.SPIFFCT.all=0x0;//SPITXBUF到移位寄存器传送不延迟;      sysclock/4


	SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;

}


void InitSpib(void)
{
	SpibRegs.SPICCR.bit.SPISWRESET = 1;		//Clear the SPI Software Reset bit to force 
                                            //the SPI to the reset state
	SpibRegs.SPICCR.bit.SPILBK = 0;			//loopback mode
	SpibRegs.SPICCR.bit.SPICHAR = 0xf;		//data format  16bit mode


	SpibRegs.SPICTL.bit.MASTER_SLAVE = 1;	//spi master
	SpibRegs.SPICTL.bit.TALK = 1;			//enable transmit

	SpibRegs.SPICTL.bit.CLK_PHASE = 0;		//transmit on falling edge,receives on rising
	SpibRegs.SPICCR.bit.CLKPOLARITY = 1;    //When no SPI data is sent, SPICLK is at high 
                                            //level



	SpibRegs.SPIBRR =0x0001;	//SPI波特率=20M/4	=5Mhz;
	SpibRegs.SPIPRI.bit.FREE = 1;  // *运行


	DELAY_US(10);

	SpibRegs.SPIFFTX.all=0xE040;//使能FIFO;清除发送中断标志位;禁止FIFO发送中断;
								//发送中断级别定义为0;
	SpibRegs.SPIFFRX.all=0x204f;//清除FF溢出标志位;清除溢出接受中断标志位;禁止
								//FF接受中断;接受中断级别为16;
	SpibRegs.SPIFFCT.all=0x0;//SPITXBUF到移位寄存器传送不延迟;      sysclock/4


	SpibRegs.SPIFFRX.bit.RXFIFORESET = 1;

}


void InitSpiaGpio(void)
{

	EALLOW;

	GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;   // Enable pull-up on GPIO16 (SPISIMOA)
	GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;   // Enable pull-up on GPIO17 (SPISOMIA)
	GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;   // Enable pull-up on GPIO18 (SPICLKA)
	GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;   // Enable pull-up on GPIO19 (SPISTEA)


	GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA)
	GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
	GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
	GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)


	GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
	GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
	GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
	GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA

//	 GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0;  //gpio = gpio
//	 GpioCtrlRegs.GPADIR.bit.GPIO19  = 1;   //output
//	 GpioDataRegs.GPASET.bit.GPIO19 = 1;  //high

//	 GpioDataRegs.GPACLEAR.bit.GPIO19 =1;//low

	EDIS;
}


void InitSpibGpio(void)
{

	EALLOW;

	GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0;   // Enable pull-up on GPIO24 (SPISIMOB)
	GpioCtrlRegs.GPAPUD.bit.GPIO25 = 0;   // Enable pull-up on GPIO25 (SPISOMIB)
	GpioCtrlRegs.GPAPUD.bit.GPIO26 = 0;   // Enable pull-up on GPIO26 (SPICLKB)
	GpioCtrlRegs.GPAPUD.bit.GPIO27 = 0;   // Enable pull-up on GPIO27 (SPISTEB)


	GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 3; // Asynch input GPIO24 (SPISIMOB)
	GpioCtrlRegs.GPAQSEL2.bit.GPIO25 = 3; // Asynch input GPIO25 (SPISOMIB)
	GpioCtrlRegs.GPAQSEL2.bit.GPIO26 = 3; // Asynch input GPIO26 (SPICLKB)
	GpioCtrlRegs.GPAQSEL2.bit.GPIO27 = 3; // Asynch input GPIO27 (SPISTEB)


	GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 3; // Configure GPIO24 as SPISIMOB
	GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 3; // Configure GPIO25 as SPISOMIB
	GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 3; // Configure GPIO26 as SPICLKB
	GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 3; // Configure GPIO27 as SPISTEB


//	GpioCtrlRegs.GPAMUX2.bit.GPIO27  = 0;  //gpio = gpio
//	GpioCtrlRegs.GPADIR.bit.GPIO27   = 1;   //output
//	GpioDataRegs.GPASET.bit.GPIO27 = 1;  //high

//	GpioDataRegs.GPACLEAR.bit.GPIO27 = 1;//low


	EDIS;
}
  • SPI读写函数;

写函数:

void SendSpi_N(Uchar dev,Uint16 *sndbuf,Uint16 cnt)
{
	Uint16 i=0,num=cnt,len;

	volatile struct SPI_REGS *p;

	switch(dev)
	{
		case Spi_a:
			p = &SpiaRegs;
		break;
		case Spi_b:
			p = &SpibRegs;
		break;
		default:
			p = &SpiaRegs;
		break;
	}

	while(num-i >= 4)
	{
		p->SPIFFRX.bit.RXFIFORESET = 1;

		p->SPITXBUF = sndbuf[i++];
		p->SPITXBUF = sndbuf[i++];
		p->SPITXBUF = sndbuf[i++];
		p->SPITXBUF = sndbuf[i++];

		while(p->SPIFFRX.bit.RXFFST<4);
		p->SPIFFRX.bit.RXFIFORESET = 0;
	}
	len = num-i;
	p->SPIFFRX.bit.RXFIFORESET = 1;

	for(;i<num;)
	{
		p->SPITXBUF = sndbuf[i++];
	}
	while(p->SPIFFRX.bit.RXFFST<len);
	p->SPIFFRX.bit.RXFIFORESET = 0;

	num=0;
	p->SPIFFRX.bit.RXFIFORESET = 1;
}

读函数:

void ReadSpi_N(Uchar dev,Uint16 *rcvbuf,Uint16 cnt)
{
	Uint16 i=0,j=0,num=cnt,len;
	volatile struct SPI_REGS *p;

	switch(dev)
	{
		case Spi_a:
			p = &SpiaRegs;
		break;
		case Spi_b:
			p = &SpibRegs;
		break;
		default:
			p = &SpiaRegs;
		break;
	}

	while(num-i>=4)
	{
		p->SPITXBUF = 0x0101;
		p->SPITXBUF = 0x0101;
		p->SPITXBUF = 0x0101;
		p->SPITXBUF = 0x0101;

		while(p->SPIFFRX.bit.RXFFST<4);
		rcvbuf[i++] = p->SPIRXBUF & 0xFFFF;
		rcvbuf[i++] = p->SPIRXBUF & 0xFFFF;
		rcvbuf[i++] = p->SPIRXBUF & 0xFFFF;
		rcvbuf[i++] = p->SPIRXBUF & 0xFFFF;
	}

	len = num-i;

	for(j=0;j<len;j++)
	{
		p->SPITXBUF = 0;
	}
	while(p->SPIFFRX.bit.RXFFST<len);
	while(p->SPIFFRX.bit.RXFFST>0)
	{
		rcvbuf[i++] = p->SPIRXBUF & 0xFFFF;
	}
}

 

相关标签: SPI FIFO