SPI 協議簡介html
物理線說明框架
SPI 四種模式函數
SPI的協議層學習
簡單時序圖3d
模式時序圖code
R/W | CPOL | CPHA | 位置1-SCK | 位置2-SCK | 位置3-SCK | 位置4-SCK |
---|---|---|---|---|---|---|
R | 0 | 0 | X | 0 | 1 | 0 |
R | 0 | 1 | X | 1 | 0 | 0 |
R | 1 | 0 | X | 1 | 0 | 1 |
R | 1 | 1 | X | 0 | 1 | 1 |
- | - | - | - | - | - | - |
W | 0 | 0 | X | 0 | 1 | 0 |
W | 0 | 1 | 0 | 1 | 0 | X |
W | 1 | 0 | X | 1 | 0 | 1 |
W | 1 | 1 | 1 | 0 | 1 | X |
由上規律得出 支持四種模式的 SPI 讀寫源碼htm
/** * @brief SPI 寫函數 * @param * @retval * @author lzm */ void spiWriteOneByte(eSPI_ID id, unsigned char data) { unsigned char i; const spi_t * spi = &spiDriverElem[id]; // 位置1 if(spi->CPHA){ spiOut(spi->sckGpiox, spi->sckPin, spi->CPOL); } for(i=0; i<8; i++) { // 位置2 spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL != spi->CPHA)); if(data & 0x80){ spiMosiOutHi(spi); } else{ spiMosiOutLo(spi); } data <<= 1; spi->delayUsFun(spi->readDelayUsCnt); // 位置3 spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL == spi->CPHA)); } // 位置4 if(!(spi->CPHA)){ spiOut(spi->sckGpiox, spi->sckPin, spi->CPOL); } }
/** * @brief SPI 讀函數 * @param * @retval * @author lzm */ unsigned char spiReadOneByte(eSPI_ID id) { unsigned char i; unsigned char ret; const spi_t * spi = &spiDriverElem[id]; // 位置1 for(i=0; i<8; i++) { // 位置2 spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL != spi->CPHA)); ret <<= 1; if(spiMisoIn(spi)) ret |= 0x01; else ret &= 0xfe; spi->delayUsFun(spi->readDelayUsCnt); // 位置3 spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL == spi->CPHA)); } // 位置4 spiOut(spi->sckGpiox, spi->sckPin, spi->CPOL); return ret; }
/** * @brief SPI 讀寫一體函數 * @param * @retval * @author lzm */ unsigned char spiRWOneByte(eSPI_ID id, unsigned char data) { unsigned char i; unsigned char ret; const spi_t * spi = &spiDriverElem[id]; // 位置1 if(spi->CPHA){ spiOut(spi->sckGpiox, spi->sckPin, spi->CPOL); } for(i=0; i<8; i++) { // 位置2 spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL != spi->CPHA)); if(data & 0x80){ spiMosiOutHi(spi); } else{ spiMosiOutLo(spi); } data <<= 1; spi->delayUsFun(spi->readDelayUsCnt); // 位置3 spiOut(spi->sckGpiox, spi->sckPin, (spi->CPOL == spi->CPHA)); ret <<= 1; if(spiMisoIn(spi)) ret |= 0x01; else ret &= 0xfe; spi->delayUsFun(spi->readDelayUsCnt); } // 位置4 if(!(spi->CPHA)){ spiOut(spi->sckGpiox, spi->sckPin, spi->CPOL); } }