【driver】SPI
根据相位和极性分类
CPOL=0,空闲低电平
CPOL=1,空闲高电平
CPHA=0,第一跳变沿采集
CPHA=1,第二跳变沿采集
分析一段代码:
1 /* CPOL = 1, CPHA = 1, MSB first */ 2 uint8_t SOFT_SPI_RW_MODE3( uint8_t write_dat ) 3 { 4 uint8_t i, read_dat; 5 for( i = 0; i < 8; i++ ) 6 { 7 SCK_L; 8 if( write_dat & 0x80 ) 9 MOSI_H; 10 else 11 MOSI_L; 12 write_dat <<= 1; 13 delay_us(1); 14 SCK_H; 15 read_dat <<= 1; 16 if( MISO ) 17 read_dat++; 18 delay_us(1); 19 __nop(); 20 } 21 return read_dat; 22 }
这是软件模拟SPI的代码,首先分析时序,CPHA=1,说明在第二个沿,CPOL=1,说明空闲SCK电平是1,那么也就是说在SCK每个时钟周期的第二个上升沿处理数据
注意这个处理数据
可以看到14行把时钟拉高,那么满足闲时高电平
第7行把时钟拉低,这是第一个沿,是个下降沿
第13行延时1us,这是半个时钟周期(第一个沿到第二个沿之间)
第14行把时钟拉高,这里是第二个沿,是个上升沿
在第一个沿和第二个沿之间,我们可以发现代码操作“输出了一个bit的数据”,在第二个沿之后我们处理了一个bit的数据
实际上我们不应该这样去理解
根据SPI的原理和时序图去理解,我们在第二个上升沿“处理数据”,对于发送那么我们要提前把数据,准备好放在MOSI的管脚数据寄存器上,8~12行就做了这件事
所以在SCK拉了一个上升沿以后,slave那边就把这个数据取走了,也正是在此时,slave那边的数据也写进了master MISO管脚的数据寄存器,所以才有了接下来15~18行对读入数据的梳理