“线程:C2000WARE”中讨论的其它部件
我正在寻找一种算法或一个示例,说明如何在 启用 FIFO 的情况下多写16个单词。 我将在 我们的设计中添加16MBit SPI EEPROM,并希望能够连续书写16个以上的单词。 如果需要禁用 FIFO 才能实现此目的,这也是可以的。
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我正在寻找一种算法或一个示例,说明如何在 启用 FIFO 的情况下多写16个单词。 我将在 我们的设计中添加16MBit SPI EEPROM,并希望能够连续书写16个以上的单词。 如果需要禁用 FIFO 才能实现此目的,这也是可以的。
你好,杰弗里,
向 FIFO 写入的字数不能超过16个,因为这超出了限制。 您可以通过连续写入 FIFO 来保持 FIFO 已满,但要先检查 FIFO 是否已满。 下面是我们的 C2000ware 中包含的用于新一代设备的一个例程,但您可以为 F2808创建自己的软件。
//***************************************************************************** // //! Waits for space in the FIFO and then puts data into the transmit buffer. //! //! \param base specifies the SPI module base address. //! \param data is the left-justified data to be transmitted over SPI. //! //! This function places the supplied data into the transmit buffer of the //! specified SPI module once space is available in the transmit FIFO. This //! function should only be used when the FIFO is enabled. //! //! \note The data being sent must be left-justified in \e data. The lower //! 16 - N bits will be discarded where N is the data width selected in //! SPI_setConfig(). For example, if configured for a 6-bit data width, the //! lower 10 bits of data will be discarded. //! //! \return None. // //***************************************************************************** static inline void SPI_writeDataBlockingFIFO(uint32_t base, uint16_t data) { // // Check the arguments. // ASSERT(SPI_isBaseValid(base)); // // Wait until space is available in the receive FIFO. // while(SPI_getTxFIFOStatus(base) == SPI_FIFO_TXFULL) { } // // Write data to the transmit buffer. // HWREGH(base + SPI_O_TXBUF) = data; }
//***************************************************************************** // //! Get the transmit FIFO status //! //! \param base is the base address of the SPI port. //! //! This function gets the current number of words in the transmit FIFO. //! //! \return Returns the current number of words in the transmit FIFO specified //! as one of the following: //! \b SPI_FIFO_TX0, \b SPI_FIFO_TX1, \b SPI_FIFO_TX2, \b SPI_FIFO_TX3, //! ..., or \b SPI_FIFO_TX16 // //***************************************************************************** static inline SPI_TxFIFOLevel SPI_getTxFIFOStatus(uint32_t base) { // // Check the arguments. // ASSERT(SPI_isBaseValid(base)); // // Get the current FIFO status // return((SPI_TxFIFOLevel)((HWREGH(base + SPI_O_FFTX) & SPI_FFTX_TXFFST_M) >> SPI_FFTX_TXFFST_S)); }
感谢 Gus 的回应,但我终于找到了解决方案,如果有其他人感兴趣,这就是我的答案。
要 能够连续写入大于16个单词的 SPI,请使用以下算法:
void _spi_write(volatile struct SPI_REGS* spir, Uint16* data, Uint16 numbytes) { // Writes to SPITXBUF must be left-justified for less than 16 bits per 'character' to send. // Filling the SPITXBUF auto sends the byte to SPIDAT (assuming no pending data in SPIDAT) // and then onto the data out line Uint16 i, j = 0; Uint16 numFullFifo = numbytes / SPI_FIFO_SIZE; Uint16 numLessFifo = numbytes % SPI_FIFO_SIZE; // Need to be able to write consecutive words > 16 in size do { if (j < numFullFifo) { for (i = 0; i < SPI_FIFO_SIZE; i++) { // spir->SPICCR.bit.SPICHAR + 1 since SPICHAR of 0 is 1 bit, 1 is 2 bits // so a SPICHAR of 7 is really 8 bits spir->SPITXBUF = data[i + (j * SPI_FIFO_SIZE)] << (16 - (spir->SPICCR.bit.SPICHAR + 1)); } // wait until bits have shifted out while(spir->SPIFFTX.bit.TXFFST != 0) { } j++; } else { if(numLessFifo > 0) { for (i = 0; i < numLessFifo; i++) { // spir->SPICCR.bit.SPICHAR + 1 since SPICHAR of 0 is 1 bit, 1 is 2 bits // so a SPICHAR of 7 is really 8 bits spir->SPITXBUF = data[i + (j * SPI_FIFO_SIZE)] << (16 - (spir->SPICCR.bit.SPICHAR + 1)); } // wait until bits have shifted out while(spir->SPIFFTX.bit.TXFFST != 0) { } } break; } } while(true); DELAY_US(SPI_INTERMSG_DELAY); }
但是,如果您需要读取16个以上的单词,则上述算法将不适用于“While (SPIR->SPIFFRX.Bit.RXFFST != numbytes)”。 它只读了最后16个字。 要读取超过16个单词(如 EEPROM 块),您需要执行以下操作:
Uint16 Read_I2CEEPROM(Uint16 address, Uint16* data, Uint16 numbytes) { Uint16 i = 0; Uint16 fullwords = numbytes / MAX_I2C_DATA_BYTES; Uint16 finalbytes = numbytes % MAX_I2C_DATA_BYTES; Uint16 results = DATA_SUCCESS; if(results == DATA_SUCCESS) { do { if (i < fullwords) { results |= EEPROM_Read_Memory((address + (i * MAX_I2C_DATA_BYTES)), data, MAX_I2C_DATA_BYTES); if(results != DATA_SUCCESS) break; ServiceDog(); i++; } else if(finalbytes > 0) { results |= EEPROM_Read_Memory((address + (i * MAX_I2C_DATA_BYTES)), data, finalbytes); if(results != DATA_SUCCESS) break; break; } } while(true); } return results; }
很高兴您能找到适合您的产品。 请注意,SPI_WRITE 函数看起来过于复杂。 只要 TX FIFO 未满,您就可以向其写入单词。 我将按如下方式编写 SPI_WRITE:
对于(i = 0;i <数字字节;I++)
{
SPIR->SPITXBUF =数据[i] <<(16 -(SPIR->SPICCR.bit.SPICHAR + 1));
while (SPIR->SPIFFTX.Bit.TXFFST == SPI_FIF_SIZE);
}
对 TXFFST 的检查将等到 TX FIFO 中至少有一个点可用。