SPI

 

 

 

 

 

/* 
 * @Description : SPI(串行同步全双工)
 * @Author      : wangxy
 * @Date        : 2020-12-04 13:30:00
 * @LastEditTime: Today
 * @LastEditors : wangxy
 * @FilePath    : SPI.c
 *
**/

//选择协议模式
#define SPI_CPOL    1            //时钟极性    0:时钟空闲低电平                        1:时钟空闲高电平                        
#define SPI_CPHA    0            //时钟相位    0:第一个跳变沿接收; 第二个跳变沿发送    1:第二个跳变沿接收; 第一个跳变沿发送
//设置IO引脚
#define CLOK_PIN    PD_ODR_ODR6    //时钟引脚
#define MOSI_PIN    PD_ODR_ODR6    //输出引脚
#define MISO_PIN    PD_IDR_IDR5    //输入引脚
#define NCSS_PIN    PD_ODR_ODR7    //片选引脚

//======================================================
//* @description: SPI初始化
//* @param        : NULL
//* @return        : NULL
//======================================================
void SPI_Init(void)
{
    NCSS_PIN =0;
#if    SPI_CPOL==0 && SPI_CPHA==0    //模式0:时钟空闲低电平 - 第一个跳变沿接收; 第二个跳变沿发送
    CLOK_PIN =0;
#endif
#if    SPI_CPOL==0 && SPI_CPHA==1    //模式1:时钟空闲低电平 - 第二个跳变沿接收; 第一个跳变沿发送
    CLOK_PIN =0;
#endif
#if    SPI_CPOL==1 && SPI_CPHA==0    //模式2:时钟空闲高电平 - 第一个跳变沿接收; 第二个跳变沿发送
    CLOK_PIN =1;
#endif
#if    SPI_CPOL==1 && SPI_CPHA==1    //模式3:时钟空闲高电平 - 第二个跳变沿接收; 第一个跳变沿发送
    CLOK_PIN =1;
#endif
}

//======================================================
//* @description: SPI_MODE1_WRITE
//* @param        : #Spi_Sed_Data    写一个数据
//* @return        : NULL
//======================================================
void SPI_Write(u8 Spi_Sed_Data)
{
    u8 n =0;
#if    SPI_CPOL==0 && SPI_CPHA==0    //模式0:时钟空闲低电平 - 第一个跳变沿接收; 第二个跳变沿发送
    for(n=0;n<8;n++){
        SCK_D(1);
        if(Spi_Sed_Data&0x80)
            MOSI_D(1);
        else
            MOSI_D(0);
        Spi_Sed_Data<<=1;
        SCK_D(0);
    }
    SCK_D(0); //CLOK空闲低
#endif
#if    SPI_CPOL==0 && SPI_CPHA==1    //模式1:时钟空闲低电平 - 第二个跳变沿接收; 第一个跳变沿发送
    for(n=0;n<8;n++){
        SCK_D(0);
        if(Spi_Sed_Data&0x80)
            MOSI_D(1);
        else
            MOSI_D(0);
        Spi_Sed_Data<<=1;
        SCK_D(1);
    }
    SCK_D(0); //CLOK空闲低
#endif
#if    SPI_CPOL==1 && SPI_CPHA==0    //模式2:时钟空闲高电平 - 第一个跳变沿接收; 第二个跳变沿发送
    for(n=0;n<8;n++){
        SCK_D(0);
        if(Spi_Sed_Data&0x80)
            MOSI_D(1);
        else
            MOSI_D(0);
        Spi_Sed_Data<<=1;
        SCK_D(1);
    }
    SCK_D(1); //CLOK空闲高
#endif
#if    SPI_CPOL==1 && SPI_CPHA==1    //模式3:时钟空闲高电平 - 第二个跳变沿接收; 第一个跳变沿发送
    for(n=0;n<8;n++){
        SCK_D(1);
        if(Spi_Sed_Data&0x80)
            MOSI_D(0);
        else
            MOSI_D(1);
        Spi_Sed_Data<<=1;
        SCK_D(0);
    }
    SCK_D(1); //CLOK空闲高
#endif
}

//======================================================
//* @description: SPI_MODE1_READ
//* @param        : NULL
//* @return        : #Spi_Rcv_Data    读一个数据
//======================================================
u8 SPI_Read(void)
{
    u8 n =0;
    u8 Spi_Rcv_Data =0;
#if    SPI_CPOL==0 && SPI_CPHA==0    //模式0:时钟空闲低电平 - 第一个跳变沿接收; 第二个跳变沿发送
    for(n=0;n<8;n++){
        Spi_Rcv_Data <<1;
        SCK_D(0);
        if(MISO_PIN)
            Spi_Rcv_Data |=1;
        else
            Spi_Rcv_Data &=0xfe;
        SCK_D(1);
    }
    SCK_D(0); //CLOK空闲低
#endif
#if    SPI_CPOL==0 && SPI_CPHA==1    //模式1:时钟空闲低电平 - 第二个跳变沿接收; 第一个跳变沿发送
    for(n=0;n<8;n++){
        Spi_Rcv_Data <<1;
        SCK_D(1);
        if(MISO_PIN)
            Spi_Rcv_Data |=1;
        else
            Spi_Rcv_Data &=0xfe;
        SCK_D(0);
    }
    SCK_D(0); //CLOK空闲低
#endif
#if    SPI_CPOL==1 && SPI_CPHA==0    //模式2:时钟空闲高电平 - 第一个跳变沿接收; 第二个跳变沿发送
    for(n=0;n<8;n++){
        Spi_Rcv_Data <<1;
        SCK_D(1);
        if(MISO_PIN)
            Spi_Rcv_Data |=1;
        else
            Spi_Rcv_Data &=0xfe;
        SCK_D(0);
    }
    SCK_D(1); //CLOK空闲高
#endif
#if    SPI_CPOL==1 && SPI_CPHA==1    //模式3:时钟空闲高电平 - 第二个跳变沿接收; 第一个跳变沿发送
    for(n=0;n<8;n++){
        Spi_Rcv_Data <<1;
        SCK_D(0);
        if(MISO_PIN)
            Spi_Rcv_Data |=1;
        else
            Spi_Rcv_Data &=0xfe;
        SCK_D(1);
    }
    SCK_D(1); //CLOK空闲高
#endif
    return Spi_Rcv_Data;
}

//======================================================
//* @description: 主函数
//* @param        : NULL
//* @return        : NULL
//======================================================
void main(void)
{
    SPI_Init();
    while(1){
        u8 SPI_Rcv_Data =0;
        NCSS_PIN =0;        //片选设备
        SPI_Write(0xff);    //写入数据
        SPI_Rcv_Data =SPI_Read();
        printf("SPI_Rcv_Data = %d\t\n",SPI_Rcv_Data);
        NCSS_PIN =1;        //取消片选
    }
}

 

posted @ 2025-03-15 10:34  panda_w  阅读(44)  评论(0)    收藏  举报