时钟相位(CPHA)和时钟极性(CPOL)的不同组合使得SPI 传输有了4 种方式 如果CPOL =0,SCK 引脚在空闲状态保持低电平; 如果CPOL =1,SCK 引脚在空闲状态保持高电平 时序图如下: (一) A V R 单片机实现代码 //IO 端口定义 #define SPI_SCK PC0 #define SPI_MOSI PC1 #define SPI_MISO PC2 #define SPI_DDR DDRC #define SPI_PORT PROTC #define SPI_PIN PINC //端口操作符定义 #define SCK_SET SPI_PORT|=_BV(SPI_SCK) #define SCK_CLR SPI_PORT&=~ _BV(SPI-SCK) #define MOSI_SET SPI_PORT|=_BV(SPI_MOSI) #define MOSI_CLR SPI_PORT&=~ _BV(SPI_MOSI) #define MISO_PIN PINC&_BV(SPI_MISO) #define DELAY_BUS //如需要延时,用延时函数替代此符号 //模式1:CPOL=1 CPHA=1 void spi_init(void) { SCK_SET; SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK); } uint8_t spi_readwrite_byte(uint8_t data) { uint8_t i,ret=0; for(i=0;i<8;i++) { //下降沿模拟 if(data&0x80)//设置输出 MOSI_SET; else MOSI_CLR; SCK_CRL;//SCK 产生下降沿 DELAY_BUS; //上升沿模拟 ret<<=1; if(MISO_PIN)//读数据 ret|=1; SCK_SET; //SCK 产生上升沿 data<<=1; DELAY_BUS; } return ret; } //模式2:CPOL=0 CPHA=1 void spi_init(void) { SCK_CLR; SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK); } uint8_t spi_readwrite_byte(uint8_t data) { uint8_t i,ret=0; for(i=0;i<8;i++) { //上升沿模拟 if(data&0x80)//设置输出 MOSI_SET; else MOSI_CLR; SCK_SET;//SCK 产生上升沿 DELAY_BUS; //下降沿模拟 ret<<=1; if(MISO_PIN)//读数据 ret|=1; SCK_CLR; //SCK 产生下降沿 data<<=1; DELAY_BUS; } return ret; } //模式 3:CPOL=1 CPHA=0 void spi_init(void) { SCK_SET; SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK); } uint8_t spi_readwrite_byte(uint8_t data) { uint8_t i,ret=0; //设置好输出口 if(data&0x80) MOSI_SET; else MOSI_CLR; for(i=0;i<8;i++) { DELAY_BUS; //下降沿模拟 ret<<=1; if(MISO_PIN)//读数据 ret|=1; SCK_CRL;//SCK 产生下降沿 DELAY_BUS; //上升沿模拟 data<<=1; if(data&0x80)//设置输出 MOSI_SET; else MOSI_CLR; SCK_SET; //SCK 产生上升沿 } return ret; } //模式 4:CPO...