Alkaitu:STM32的IO模拟SPI

发布时间 2023-04-10 12:18:21作者: 在下彦祖
 #include "user_spi.h"
#include "stm32f10x.h"
#include "user_config.h"


/*移植需改动六处*/


/***************************************************************/
/*挂在是SPI总线上的外设的个数和延迟时间,移植修改第一处*/
/***************************************************************/
#define SPI_NUM_ALL 1
#define SPI_DELAY_TIME 0
/***************************************************************/

/*SPI的SCK引脚电平设置,移植修改第二处*/
/***************************************************************/
#define SPI_SCK_SET_1       GPIO_SetBits(GPIOE, GPIO_Pin_6)
#define SPI_SCK_SET_0       GPIO_ResetBits(GPIOE, GPIO_Pin_6)
/***************************************************************/

/*SPI的MOSI引脚电平设置,输出引脚,移植修改第三处*/
/***************************************************************/
#define SPI_MOSI_SET_1       GPIO_SetBits(GPIOE, GPIO_Pin_4)
#define SPI_MOSI_SET_0       GPIO_ResetBits(GPIOE, GPIO_Pin_4)
/***************************************************************/

/*SPI的MISO引脚电平设置,输入引脚,移植修改第四处*/
/***************************************************************/
#define SPI_MISO_READ  GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)
/***************************************************************/

/*SPI的CS引脚电平设置,移植修改第五处*/
/***************************************************************/
#define SPI_CS1_SET_1       GPIO_SetBits(GPIOE, GPIO_Pin_0)
#define SPI_CS1_SET_0       GPIO_ResetBits(GPIOE, GPIO_Pin_0)

#if SPI_NUM_ALL > 1
#define SPI_CS2_SET_1       GPIO_SetBits(GPIOB, GPIO_Pin_12)
#define SPI_CS2_SET_0       GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#endif

#if SPI_NUM_ALL > 2
#define SPI_CS3_SET_1       GPIO_SetBits(GPIOB, GPIO_Pin_12)
#define SPI_CS3_SET_0       GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#endif

#if SPI_NUM_ALL > 3
#define SPI_CS4_SET_1       GPIO_SetBits(GPIOB, GPIO_Pin_12)
#define SPI_CS4_SET_0       GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#endif
/***************************************************************/


/***************************************************************************/
/*SPI引脚初始化,移植修改第六处*/
/***************************************************************************/
void user_spi_init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_4 | GPIO_Pin_6 | GPIO_Pin_2 | GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/***************************************************************************/


/***************************************************************/
/*SPI的SCK引脚设置*/
/***************************************************************/
void spi_sck_set(unsigned char IOvalue)
{
  if(IOvalue != 0)
    {SPI_SCK_SET_1;user_delay_us(SPI_DELAY_TIME);}
    else{SPI_SCK_SET_0;user_delay_us(SPI_DELAY_TIME);}
}
/***************************************************************/


/***************************************************************/
/*SPI的MOSI引脚设置*/
/***************************************************************/
void spi_mosi_set(unsigned char IOvalue)
{
    if(IOvalue != 0){SPI_MOSI_SET_1;user_delay_us(SPI_DELAY_TIME);}
    else{SPI_MOSI_SET_0;user_delay_us(SPI_DELAY_TIME);}
}
/***************************************************************/


/***************************************************************/
/*SPI的MISO引脚设置*/
/***************************************************************/
unsigned char spi_miso_read(void)
{
  unsigned char bit_value;
  bit_value = SPI_MISO_READ;
    user_delay_us(SPI_DELAY_TIME);
    return bit_value;
}
/***************************************************************/


/***************************************************************/
/*SPI起始信号*/
/***************************************************************/
void user_spi_start(unsigned char spi_id)
{
  switch(spi_id)
    {
      case 1: SPI_CS1_SET_0;user_delay_us(SPI_DELAY_TIME);break;
        
        #if SPI_NUM_ALL > 1
        case 2: SPI_CS2_SET_0;user_delay_us(SPI_DELAY_TIME);break;
    #endif

    #if SPI_NUM_ALL > 2
        case 3: SPI_CS3_SET_0;user_delay_us(SPI_DELAY_TIME);break;
    #endif

    #if SPI_NUM_ALL > 3
        case 4: SPI_CS4_SET_0;user_delay_us(SPI_DELAY_TIME);break;
    #endif
    }
}
/***************************************************************/


/***************************************************************/
/*SPI停止信号*/
/***************************************************************/
void user_spi_stop(unsigned char spi_id)
{
  switch(spi_id)
    {
      case 1: SPI_CS1_SET_1;user_delay_us(SPI_DELAY_TIME);break;
        
        #if SPI_NUM_ALL > 1
        case 2: SPI_CS2_SET_1;user_delay_us(SPI_DELAY_TIME);break;
    #endif

    #if SPI_NUM_ALL > 2
        case 3: SPI_CS3_SET_1;user_delay_us(SPI_DELAY_TIME);break;
    #endif

    #if SPI_NUM_ALL > 3
        case 4: SPI_CS4_SET_1;user_delay_us(SPI_DELAY_TIME);break;
    #endif
    }
}
/***************************************************************/


/************************************************************************************************/
/*SPI移位寄存器收发一个字节数据*/
/************************************************************************************************/
unsigned char user_spi_swap_byte(unsigned char send_byte)
{
  unsigned char i,receice_byte = 0x00;
    for(i = 0;i < 8;i++)
    {
      if((send_byte & (0x80 >> i)) != 0){spi_mosi_set(1);}else{spi_mosi_set(0);}
        spi_sck_set(1);
        if(spi_miso_read() != 0){receice_byte |= (0x80 >> i);}else{receice_byte &= (~(0x80 >> i));}
        spi_sck_set(0);
    }
    return receice_byte; 
}
/***********************************************************************************************/
#ifndef _user_spi_h_
#define _user_spi_h_

/*头文件移植无需改动*/

/*************************************************************************/
/*SPI引脚初始化函数,移植需在.C文件改动*/
/*************************************************************************/

void user_spi_init(void);

/*************************************************************************/



/***********************************************************************/
/*移植无需改动,函数实现SPI的脚位电平设置,无需改动*/
/***********************************************************************/

void spi_sck_set(unsigned char IOvalue);
void spi_mosi_set(unsigned char IOvalue);
unsigned char spi_miso_read(void);

/***********************************************************************/

/***********************************************************************/
/*实际IO模拟主要引用这三个函数,无需改动*/
/***********************************************************************/

void user_spi_start(unsigned char spi_id);
void user_spi_stop(unsigned char spi_id);
unsigned char user_spi_swap_byte(unsigned char send_byte);

/***********************************************************************/
#endif