
來源:技術讓夢想更偉大
整理:李肖遙
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 ????????????????
關注我的微信公眾號,回復“加群”按規則加入技術交流群。
點擊下面圖片,有星球具體介紹,新用戶有新人優惠券,老用戶半價優惠,期待大家一起學習一起進步。
點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。