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); } }