一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 1476|回复: 0
收起左侧

请教下SPI四种模式的代码bug

[复制链接]
发表于 2024-7-28 10:02 | 显示全部楼层 |阅读模式
csdn扒了个SPI的驱动,改了下在STC15单片机下不能正常使用,读取全是0xFF。目前用到的案例是CPOL不限,CPHA =1。也就是1和3模式:

//CPOL:规定了SCK时钟信号空闲状态的电平(0-低电平,1-高电平)
//CPHA:规定了数据是在SCK时钟的上升沿还是下降沿被采样(0-第一个时钟边沿开始采样,1-第二个时钟边沿开始采样)
//模式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的上升沿被采样(提取数据)

  1. #ifndef __SPI_H
  2. #define __SPI_H

  3. #define FOSC        22118400UL
  4. #define BAUD        115200

  5. #include "STC15W4K.H"      
  6. #include<intrins.h>
  7. typedef unsigned char u8;
  8. typedef unsigned int u16;

  9. #define CS_L                                                         P16=0
  10. #define CS_H                                                         P16=1
  11. #define SCK_L                                                  P15=0
  12. #define SCK_H                                                  P15=1
  13. #define MOSI_L                                                P13=0
  14. #define MOSI_H                                                P13=1
  15. #define MISO              P44

  16. u8 SOFT_SPI_RW_MODE(u8 write_dat);

  17. u8 SPI2_ReadWriteByte(u8 TxData);

  18. #endif
复制代码
spi.c
  1. #include "spi.h"
  2. #define  SPI_Mode 3  //选择SPI的模式

  3. //CPOL:规定了SCK时钟信号空闲状态的电平(0-低电平,1-高电平)
  4. //CPHA:规定了数据是在SCK时钟的上升沿还是下降沿被采样(0-第一个时钟边沿开始采样,1-第二个时钟边沿开始采样)
  5. //模式0:CPOL=0,CPHA =0  SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据)
  6. //模式1:CPOL=0,CPHA =1  SCK空闲为低电平,数据在SCK的下降沿被采样(提取数据)
  7. //模式2:CPOL=1,CPHA =0  SCK空闲为高电平,数据在SCK的下降沿被采样(提取数据)
  8. //模式3:CPOL=1,CPHA =1  SCK空闲为高电平,数据在SCK的上升沿被采样(提取数据)


  9. /*spi延时函数,微秒*/
  10. static void spi_delay(u16 time)
  11. {
  12.     u8 i = 0;
  13.     while(time--)
  14.     {
  15.         i = 10;
  16.         while(i--) ;
  17.     }
  18. }

  19. #if SPI_Mode==0
  20. /* CPOL = 0, CPHA = 0 */
  21. u8 SOFT_SPI_RW_MODE(u8 write_dat)
  22. {
  23.     u8 i, read_dat = 0;
  24.     SCK_L;
  25.     for(i = 0; i < 8; i++)
  26.     {
  27.         if(write_dat & 0x80)
  28.             MOSI_H;
  29.         else
  30.             MOSI_L;
  31.         write_dat <<= 1;
  32.         spi_delay(1);
  33.         SCK_H;
  34.         read_dat <<= 1;

  35.         if(MISO)
  36.             read_dat++;
  37.         spi_delay(1);
  38.         SCK_L;
  39.         _nop_();
  40.     }
  41.     return read_dat;
  42. }
  43. #elif SPI_Mode==1
  44. /* CPOL=0,CPHA=1 */
  45. u8 SOFT_SPI_RW_MODE(u8 write_dat)
  46. {
  47.     u8 i, read_dat = 0;
  48.     SCK_L;
  49.     for(i = 0; i < 8; i++)
  50.     {
  51.         SCK_H;
  52.         if(write_dat & 0x80)
  53.             MOSI_H;
  54.         else
  55.             MOSI_L;
  56.         write_dat <<= 1;
  57.         spi_delay(1);
  58.         SCK_L;
  59.         read_dat <<= 1;

  60.         if(MISO)
  61.             read_dat++;
  62.         spi_delay(1);
  63.     }
  64.     return read_dat;
  65. }
  66. #elif SPI_Mode==2
  67. /* CPOL=1,CPHA=0 */
  68. u8 SOFT_SPI_RW_MODE(u8 write_dat)
  69. {
  70.     u8 i, read_dat = 0;
  71.     SCK_H;
  72.     for(i = 0; i < 8; i++)
  73.     {
  74.         if(write_dat & 0x80)
  75.             MOSI_H;
  76.         else
  77.             MOSI_L;
  78.         write_dat <<= 1;
  79.         spi_delay(1);
  80.         SCK_L;
  81.         read_dat <<= 1;

  82.         if(MISO)
  83.             read_dat++;
  84.         spi_delay(1);
  85.         SCK_H;
  86.     }
  87.     return read_dat;
  88. }
  89. #elif SPI_Mode==3
  90. /* CPOL = 1, CPHA = 1 */
  91. u8 SOFT_SPI_RW_MODE(u8 write_dat)
  92. {
  93.     u8 i, read_dat = 0;
  94.     SCK_H;
  95.     for(i = 0; i < 8; i++)
  96.     {
  97.         SCK_L;
  98.         if(write_dat & 0x80)
  99.             MOSI_H;
  100.         else
  101.             MOSI_L;
  102.         write_dat <<= 1;
  103.         spi_delay(1);
  104.         SCK_H;
  105.         read_dat <<= 1;

  106.         if(MISO)
  107.             read_dat++;
  108.         spi_delay(1);
  109.         _nop_();
  110.     }
  111.     return read_dat;
  112. }
  113. #endif        

  114. //SPI2 读写一个字节
  115. //TxData:要写入的字节
  116. //返回值:读取到的字节
  117. u8 SPI2_ReadWriteByte(u8 TxData)
  118. {
  119.     u8 Rxdata;
  120.           CS_L;
  121.     Rxdata = SOFT_SPI_RW_MODE(TxData);
  122.           CS_H;
  123.     return Rxdata;
  124. }
复制代码



本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-2-17 03:38 , Processed in 0.050336 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表