SPI四种模式代码

#include "stdio.h"
 
/***************************************************
Mode0:CPOL=0,CPHA=0 常用  空闲SCK=0 数据采样是在上升沿
Mode1:CPOL=0,CPHA=1 空闲SCK=0 数据采样是在下降沿
Mode2:CPOL=1,CPHA=0 空闲SCK=1 数据采集是在下降沿
Mode3:CPOL=1,CPHA=1 常用 空闲SCK=1 数据采样是在上升沿
***************************************************/
 
/*SPI 配置*/
#define SPI_MODE  0
#define SPI_DELAY 10
#define SPI_CS(x)
#define SPI_SCLK(x)
#define SPI_MOSI(x)         //对SDI
#define SPI_MISO()    1     //对SDO
 
 
void my_spi_delayus(unsigned int i)
{
    /*按照需求填写us级别延时*/
}
 
void my_spi_GpioInit(void)
{
    /*GPIO初始化*/
    /*建议上拉模式*/
}
 
void my_spi_senddata(unsigned char dat)
{
    unsigned char i=0;
#if SPI_MODE==0
    for(i=0;i<8;i++)
    {
        SPI_SCLK(0);//空闲是0
        if(dat&0x80)//准备好数据
            SPI_MOSI(1);
        else
            SPI_MOSI(0);
        dat<<=1;
        SPI_SCLK(1);//产生上升沿发送数据
        my_spi_delayus(SPI_DELAY);
    }
    SPI_SCLK(0);
#elif MODE==1  //空闲SCK=0 数据采样是在下降沿
    for(i=0;i<8;i++)
    {
        SPI_SCLK(1);
        if(dat&0x80)
            SPI_MOSI(1);
        else
            SPI_MOSI(0);
        dat<<=1;
        SPI_SCLK(0);
        my_spi_delayus(SPI_DELAY);
    }
#elif MODE==2   //空闲SCK=1 数据采集是在下降沿
    for(i=0;i<8;i++)
    {
        SPI_SCLK(1);
        if(dat&0x80)
            SPI_MOSI(1);
        else
            SPI_MOSI(0);
        dat<<=1;
        SPI_SCLK(0);
        my_spi_delayus(SPI_DELAY);
    }
    SPI_SCLK(1);
#elif MODE==3     //常用 空闲SCK=1 数据采样是在上升沿
    for(i=0;i<8;i++)
    {
       my_spi_delayus(SPI_DELAY);
       SPI_SCLK(0);
       if(dat&0x80)
            SPI_MOSI(1);
        else
            SPI_MOSI(0);
        dat<<=1;
        SPI_SCLK(1);
    }
#endif
}
 
 
unsigned char my_spi_readdata(void)
{
    unsigned char i=0,dat=0;
#if SPI_MODE==0  //空闲SCK=0 数据接收是在下沿
    for(i=0;i<8;i++)
    {
        SPI_SCLK(0);
        dat<<=1;
        if(SPI_MISO())
            dat|=0x01;
        else
            dat&=0xfe;
        SPI_SCLK(1);
        my_spi_delayus(SPI_DELAY);
    }
    SPI_SCLK(0);
    return dat;
#elif SPI_MODE==1  //空闲SCK=0 数据接收是上升降沿
    for(i=0;i<8;i++)
     {
      SPI_SCLK(1);
       dat<<=1;
      if(SPI_MISO())
          dat|=0x01;
      else
          dat&=0xfe;
      SPI_SCLK(0);
      my_spi_delayus(SPI_DELAY);
     }
      return dat;
#elif SPI_MODE==2  //空闲SCK=1 数据接收是在上升沿
    for(n=0;n<8;n++)
    {
     SPI_SCLK(1);
     dat<<=1;
     if(SPI_MISO())
         dat|=0x01;
     else
         dat&=0xfe;
     SPI_SCLK(0);
     my_spi_delayus(SPI_DELAY);
    }
     return dat;
#elif SPI_MODE==3  //空闲SCK=1 数据接收是在下降沿
    for(n=0;n<8;n++)
    {
     SPI_SCLK(0);
     dat<<=1;
     if(SPI_MISO())
         dat|=0x01;
     else
         dat&=0xfe;
     SPI_SCLK(1);
     my_spi_delayus(SPI_DELAY);
    }
     return dat;
#endif
}
 
 
unsigned char my_spi_swap(unsigned char dat)
{
    unsigned char i=0,redat=0;
#if SPI_MODE==0  //空闲SCK=0 数据发送是在上升沿,接收下降
    for(i=0;i<8;i++)
    {
        if(dat&0x80)
            SPI_MOSI(1);
        else
            SPI_MOSI(0);
        dat<<=1;
        SPI_SCLK(1);
        my_spi_delayus(SPI_DELAY);
        SPI_SCLK(0);
        redat<<=1;
        if(SPI_MISO())
            redat|=0x01;
        else
            redat&=0xfe;
    }
    return redat;
#elif SPI_MODE==1  //空闲SCK=0 数据发送是在下降沿,接收上升  
    for(i=0;i<8;i++)
    {
        SPI_SCLK(1);
        redat<<=1;
        if(SPI_MISO())
            redat|=0x01;
        else
            redat&=0xfe;
        if(dat&0x80)
            SPI_MOSI(1);
        else
            SPI_MOSI(0);
        dat<<=1;
        SPI_SCLK(0);
        my_spi_delayus(SPI_DELAY);
    }
    return redat;
#elif SPI_MODE==2   //空闲SCK=1 数据发送是在下降沿,上升接收
    for(i=0;i<8;i++)
    {
        if(dat&0x80)
            SPI_MOSI(1);
        else
            SPI_MOSI(0);
        dat<<=1;
        SPI_SCLK(0);
        my_spi_delayus(SPI_DELAY);
        SPI_SCLK(1);
        redat<<=1;
        if(SPI_MISO())
            redat|=0x01;
        else
            redat&=0xfe;
    }
    return redat;
#elif SPI_MODE==3  //空闲SCK=1 数据发送是在上升沿,下降接收
    for(i=0;i<8;i++)
    {
        SPI_SCLK(0);
        redat<<=1;
        if(SPI_MISO())
            redat|=0x01;
        else
            redat&=0xfe;
        if(dat&0x80)
            SPI_MOSI(1);
        else
            SPI_MOSI(0);
        dat<<=1;
         SPI_SCLK(1);
         my_spi_delayus(SPI_DELAY);
    }
    return redat;
#endif
}

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是SPI的DMA模式初始化代码,供参考: ```c // 假设SPI1的时钟已经开启 // 假设DMA1的时钟已经开启 // 初始化SPI1 SPI_InitTypeDef spi_init; spi_init.SPI_Direction = SPI_Direction_2Lines_FullDuplex; spi_init.SPI_Mode = SPI_Mode_Master; spi_init.SPI_DataSize = SPI_DataSize_8b; spi_init.SPI_CPOL = SPI_CPOL_Low; spi_init.SPI_CPHA = SPI_CPHA_1Edge; spi_init.SPI_NSS = SPI_NSS_Soft; spi_init.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; spi_init.SPI_FirstBit = SPI_FirstBit_MSB; spi_init.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &spi_init); SPI_Cmd(SPI1, ENABLE); // 初始化DMA1的通道2 DMA_InitTypeDef dma_init; dma_init.DMA_DIR = DMA_DIR_PeripheralToMemory; dma_init.DMA_BufferSize = 32; dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable; dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma_init.DMA_Mode = DMA_Mode_Normal; dma_init.DMA_Priority = DMA_Priority_High; dma_init.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel2, &dma_init); // 配置DMA1的通道2,使其从SPI1的数据寄存器中读取数据 DMA_Cmd(DMA1_Channel2, DISABLE); DMA_DeInit(DMA1_Channel2); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(SPI1->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rx_buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 32; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel2, &DMA_InitStructure); // 配置SPI1的DMA接收模式 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE); // 启动DMA1的通道2 DMA_Cmd(DMA1_Channel2, ENABLE); ``` 以上代码中,使用了DMA1的通道2作为SPI1的DMA接收通道。其中,rx_buffer是一个接收数据的缓冲区,大小为32字节。在实际使用时,需要根据具体的应用场景进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值