文章
博客 网店

 软件模拟SPI口四种模式


以下软件模拟SPI口先发送高位,每次发送一个字节





//总线模式符号定义  0:CPHA=0 CPOL=0   1:CPHA=0 CPOL=1   2:CPHA=1 CPOL=0   3:CPHA=1 CPOL=1
#define SOFT_SPI_MODE   0

//总线延时功能定义
#define SPI_DELAY_BUS 

//定义引脚操作宏
#define MOSI_SET  GPIO_SetBits(GPIOA , GPIO_Pin_7)
#define MOSI_CLR  GPIO_ResetBits(GPIOA,GPIO_Pin_7)
#define SCK_SET  GPIO_SetBits(GPIOA , GPIO_Pin_5)
#define SCK_CLR  GPIO_ResetBits(GPIOA,GPIO_Pin_5)
#define MISO_IN GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)

void SPI1_Init(void)
{  
  GPIO_InitTypeDef GPIO_InitStructure;
  
  // SCK, MOSI
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //MISO
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  SCK_CLR;
}

#if SOFT_SPI_MODE == 0     //CPHA=0  CPOL=0

uint8_t  SPI1_RWByte(uint8_t dat)
{
  uint8_t i;
  for(i=0;i<8;i++)
  {
    //准备要写入的数据到输出口
    if(dat &0x80)
      MOSI_SET;
    else
      MOSI_CLR;
    dat<<=1;
    SPI_DELAY_BUS; //总线延时
      
    SCK_SET; //触发上升沿
    //紧跟第一个上升沿读取数据
    if(MISO_IN)
      dat++;
    
    SPI_DELAY_BUS; //总线延时 
                  
    SCK_CLR;//触发下降沿
  }
  return dat; 
}


#elif SOFT_SPI_MODE == 1     //CPHA=0  CPOL=1

uint8_t  SPI1_RWByte(uint8_t dat)
{
  uint8_t i;
  for(i=0;i<8;i++)
  {
    //准备要写入的数据到输出口
    if(dat &0x80)
      MOSI_SET;
    else
      MOSI_CLR;
    dat<<=1;

    SPI_DELAY_BUS; //总线延时
      
    SCK_CLR;   //触发下降沿
    //紧跟第一个下降沿读数据
    if(MISO_IN)
      dat++;

    SPI_DELAY_BUS; //总线延时   
                
    SCK_SET;  //触发上升沿
  }
  return dat; 
}

#elif SOFT_SPI_MODE == 2    //CPHA=1  CPOL=0

uint8_t  SPI1_RWByte(uint8_t dat)
{
  uint8_t i;
  for(i=0;i<8;i++)
  {
    SCK_SET;  //触发上升沿

    //准备要写入的数据到输出口
    if(dat &0x80)
      MOSI_SET;
    else
      MOSI_CLR;
    dat<<=1;
    
    SPI_DELAY_BUS; //总线延时
      
    SCK_CLR; //触发下降沿  
    //紧跟第二个下降沿读数据
    if(MISO_IN)
      dat++;
      
    SPI_DELAY_BUS; //总线延时             
  }
  return dat; 
}

#else //SOFT_SPI_MODE == 3    //CPHA=1  CPOL=1 
  
uint8_t  SPI1_RWByte(uint8_t dat)
{
  uint8_t i;
  for(i=0;i<8;i++)
  {
    SCK_CLR;  //触发下降沿

    //准备要写入的数据到输出口
    if(dat &0x80)
      MOSI_SET;
    else
      MOSI_CLR;
    dat<<=1;
    
    SPI_DELAY_BUS; //总线延时
      
    SCK_SET; //触发上升沿  
    //紧跟第二个上升沿读数据
    if(MISO_IN)
      dat++; 
      
    SPI_DELAY_BUS; //总线延时            
  }
  return dat; 
}
#endif

芯艺工作室    蒙ICP备06005492号
Copyright© 2004-2023 ChipArt Studio All Rights Reserved