DSP 2812 SPI dual-machine communication implementation[Copy link]
I need two 2812s to control four motors. The host needs to send control signals to the slave, and the slave sends encoder information to the host. Therefore, stable, real-time and rapid communication between the two machines is very important. Here I use SPI communication. Although it is a small communication code, it took a long time to adjust it. I am not very proficient in using TI's things. The main problems I encountered are that I can't enter the interrupt and the data is misplaced. The program is posted below. The SPISOMI, SPISIMO, SPISTEA, and SPICLK of the two 2812s are connected to each other. The pin function is adjusted to SPI function in the program. EALLOW; GpioMuxRegs.GPFMUX.bit.SPICLKA_GPIOF2 = 1; GpioMuxRegs.GPFMUX.bit.SPISIMOA_GPIOF0 =1; GpioMuxRegs.GPFMUX.bit.SPISOMIA_GPIOF1 = 1; GpioMuxRegs.GPFMUX.bit.SPISTEA_GPIOF3 = 1; EDIS; Copy code For the host SPI initialization, the program is as follows. Enable interrupts. SpiaRegs.SPICCR.all = 0x000F; //Reset, rising edge, 16-bit data bit SpiaRegs.SPICTL.all = 0x0007; //Enable master mode, normal phase, enable SPI interrupt SpiaRegs.SPIBRR = 0x007F; //Clock frequency, 300k SpiaRegs.SPICCR.all = 0x008F; Copy code For slave SPI initialization, it is the same as the master, but set SPICTL bit 2 to 0; SpiaRegs.SPICCR.all = 0x000F; //Reset, rising edge, 16-bit data bit SpiaRegs.SPICTL.all = 0x0003; //Enable slave mode, normal phase, turn on SPI interrupt SpiaRegs.SPIBRR = 0x007F; //Clock frequency, 300k SpiaRegs.SPICCR.all = 0x008F; Copy code The main programs of the master and slave are basically the same. Turn on the interrupt and send data. Note that when sending data, you must judge the status of the SpiaRegs.SPISTS.bit.BUFFULL_FLAG bit. Otherwise, data misalignment will occur. The judgment function is as follows: unsigned int Spi_TxReady(void) { unsigned int i; if(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 1) { i = 0; } else { i = 1; } return(i); } Copy code The host write data function is as follows: void Write(Uint16 data) { if(Spi_TxReady() == 1) { SpiaRegs.SPITXBUF = data; } while(Spi_TxReady()!=1); } Copy code The main function is as follows.Use SPI receive interrupt void main(void) { unsigned long int a; //Step1,Initialize system control //Enable related peripheral clocks, PLL phase-locked loop backup frequency and WatchDog (watchdog) use default settings InitSysCtrl(); // Step2, clear all interrupts and initialize PIE interrupt vector table //Disable CPU interrupts DINT; //And clear all CPU interrupt flags IER = 0x0000; IFR = 0x0000; //Initialize PIE control register to default value, the default value is that all PIE interrupts are disabled and the flag bits are cleared InitPieCtrl(); //Initialize the PIE interrupt vector table, and set the program to automatically jump to the service routine (ISR) when an interrupt occurs InitPieVectTable(); //step3, initialize related peripherals. In this example, the main purpose is to set IO as peripheral function InitPeripherals(); EALLOW; PieVectTable.SPIRXINTA = &spiRxIsr; EDIS; IER |= M_INT6; PieCtrl.PIEIER6.bit.INTx1=1; EINT; //Enable INTM ERTM; //Enable DBGM sdata = 0xA802; while(1) { Write(sdata); for(a=0;a<500000;a++); } } Copy code The key receiving interrupt function is as follows: [ /size] interrupt void spiRxIsr(void) { rdata = SpiaRegs.SPIRXBUF; SpiaRegs.SPISTS.bit.OVERRUN_FLAG = 1; PieCtrl.PIEACK.bit.ACK6 = 1; } Copy code For the slave, data is sent back to the host in the receive interrupt function. Because the SPI clock is only provided by the host. So the slave needs to provide the clock to the slave when writing data to the host. For example, when the host writes 0x0030 to the slave, the slave receives the interrupt function and writes the required write data to SpiaRegs.SPITXBUF, so that the slave can write data to the host. The slave receives the interrupt function as follows: interrupt void spiRxIsr(void) { rdata = SpiaRegs.SPIRXBUF; sdata = rdata; Write(sdata); SpiaRegs.SPISTS.bit.OVERRUN_FLAG = 1; PieCtrl.PIEACK.bit.ACK6 = 1; }INTx1=1; EINT; //Enable INTM ERTM; //Enable DBGM sdata = 0xA802;[/size ] while(1) { Write(sdata); for(a=0;a <500000;a++); } } Copy code Key receiving interrupt The function is as follows: interrupt void spiRxIsr(void) { rdata = SpiaRegs.SPIRXBUF; [size= 4] SpiaRegs.SPISTS.bit.OVERRUN_FLAG = 1; PieCtrl.PIEACK.bit.ACK6 = 1; } For the slave, the data is sent back to the host in the receive interrupt function. Because the SPI clock is only provided by the host. Therefore, the host needs to provide the clock to the slave when the slave writes data to the host. For example, when the host When writing 0x0030 to the slave, the slave receives an interrupt function and writes the required data into SpiaRegs.SPITXBUF, thus enabling the slave to write data to the host. The slave receives an interrupt function as follows: interrupt void spiRxIsr(void){rdata = SpiaRegs.SPIRXBUF; sdata = rdata; Write(sdata); SpiaRegs.SPISTS.bit.OVERRUN_FLAG = 1; PieCtrl.PIEACK.bit.ACK6 = 1; [/ size] } Copy codeINTx1=1; EINT; //Enable INTM ERTM; //Enable DBGM sdata = 0xA802;[/size ] while(1) { Write(sdata); for(a=0;a <500000;a++); } } Copy code Key receiving interrupt The function is as follows: interrupt void spiRxIsr(void) { rdata = SpiaRegs.SPIRXBUF; [size= 4] SpiaRegs.SPISTS.bit.OVERRUN_FLAG = 1; PieCtrl.PIEACK.bit.ACK6 = 1; } For the slave, the data is sent back to the host in the receive interrupt function. Because the SPI clock is only provided by the host. Therefore, the host needs to provide the clock to the slave when the slave writes data to the host. For example, when the host When writing 0x0030 to the slave, the slave receives an interrupt function and writes the required data into SpiaRegs.SPITXBUF, thus enabling the slave to write data to the host. The slave receives an interrupt function as follows: interrupt void spiRxIsr(void){rdata = SpiaRegs.SPIRXBUF; sdata = rdata; Write(sdata); SpiaRegs.SPISTS.bit.OVERRUN_FLAG = 1; PieCtrl.PIEACK.bit.ACK6 = 1; [/ size] } Copy code