来源:技术让梦想更伟大
整理:李肖遥
CPOL:规定了SCK时钟信号空闲状态的电平
CPHA:规定了数据是在SCK时钟的上升沿还是下降沿被采样
----------- ------------------------------------
模式0:CPOL=0,CPHA =0 SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据)
模式1:CPOL=0,CPHA =1 SCK空闲为低电平,数据在SCK的下降沿被采样(提取数据)
模式2:CPOL=1,CPHA =0 SCK空闲为高电平,数据在SCK的下降沿被采样(提取数据)
模式3:CPOL=1,CPHA =1 SCK空闲为高电平,数据在SCK的上升沿被采样(提取数据)
以模式0为例:SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据),在SCK的下降沿切换数据线的数据。

◐在时钟的第1个上升沿(游标1处)(采样点)
MOSI上数据为1,则在此边沿从机采样(提取)数据为1,采样点在MOSI数据线的中间。
MISO上数据为0,则在此边沿主机采样(提取)数据为0,采样点在MISO数据线的中间。
◐在时钟的第1个下降沿(游标2处)(切换点)
MOSI上数据由1切换为0,,数据在时钟下降沿时切换数据。
MISO上数据由0切换为1,,数据在时钟下降沿时切换数据。
◐在时钟的第2~8个上升沿(采样点),主机在MISO上采样数据,从机在MOSI上采样数据。
◐在时钟的第2~8个下降沿(切换点),主机在MISO上切换数据,从机在MOSI上切换数据
/* CPOL = 0, CPHA = 0, MSB first */uint8_t SOFT_SPI_RW_MODE0( uint8_t write_dat ){uint8_t i, read_dat;for( i = 0; i < 8; i++ ){if( write_dat & 0x80 )MOSI_H;elseMOSI_L;write_dat <<= 1;delay_us(1);SCK_H;read_dat <<= 1;if( MISO )read_dat++;delay_us(1);SCK_L;__nop();}return read_dat;}/* CPOL=0,CPHA=1, MSB first */uint8_t SOFT_SPI_RW_MODE1(uint8_t byte){uint8_t i,Temp=0;for(i=0;i<8;i++) // 循环8次{SCK_H; //拉高时钟if(byte&0x80){MOSI_H; //若最到位为高,则输出高}else{MOSI_L; //若最到位为低,则输出低}byte <<= 1; // 低一位移位到最高位delay_us(1);SCK_L; //拉低时钟Temp <<= 1; //数据左移if(MISO)Temp++; //若从从机接收到高电平,数据自加一delay_us(1);}return (Temp); //返回数据}/* CPOL=1,CPHA=0, MSB first */uint8_t SOFT_SPI_RW_MODE2(uint8_t byte){uint8_t i,Temp=0;for(i=0;i<8;i++) // 循环8次{if(byte&0x80){MOSI_H; //若最到位为高,则输出高}else{MOSI_L; //若最到位为低,则输出低}byte <<= 1; // 低一位移位到最高位delay_us(1);SCK_L; //拉低时钟Temp <<= 1; //数据左移if(MISO)Temp++; //若从从机接收到高电平,数据自加一delay_us(1);SCK_H; //拉高时钟}return (Temp); //返回数据}/* CPOL = 1, CPHA = 1, MSB first */uint8_t SOFT_SPI_RW_MODE3( uint8_t write_dat ){uint8_t i, read_dat;for( i = 0; i < 8; i++ ){SCK_L;if( write_dat & 0x80 )MOSI_H;elseMOSI_L;write_dat <<= 1;delay_us(1);SCK_H;read_dat <<= 1;if( MISO )read_dat++;delay_us(1);__nop();}return read_dat;}
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
关注我的微信公众号,回复“加群”按规则加入技术交流群。
点击下面图片,有星球具体介绍,新用户有新人优惠券,老用户半价优惠,期待大家一起学习一起进步。
点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。



