DSP

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

2019-07-13 10:28发布

本人使用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(;iSPITXBUF = sndbuf[i++]; } while(p->SPIFFRX.bit.RXFFSTSPIFFRX.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;jSPITXBUF = 0; } while(p->SPIFFRX.bit.RXFFSTSPIFFRX.bit.RXFFST>0) { rcvbuf[i++] = p->SPIRXBUF & 0xFFFF; } }