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

版权声明:原创博客,不得用于商业用途 https://blog.csdn.net/weixin_39768579/article/details/82256928

本人使用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;
	}
}

 

猜你喜欢

转载自blog.csdn.net/weixin_39768579/article/details/82256928