模拟SPI

注:参考各类网上博客,出处已不清,若有网友指出,感激不尽,并尽快进行添加出处。

C文件

#include "softspi.h"

#ifdef SOFT_SPI
sspi_t sspi;
#endif

void softspi_init(sspi_t *spi_periph)
{
    spi_periph->mod = PL_HIGH_PH_2EDGE;//PL_HIGH_PH_2EDGE       //PL_LOW_PH_1EDGE

/*************************************************/
#ifdef SOFT_SPI//SPI引脚配置
   
#endif

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

    /* 引脚设置 */
    sspi.spi_miso_port = SDO_GPIO_Port;
    sspi.spi_miso_pin = SDO_Pin;
    sspi.spi_mosi_port = SDI_GPIO_Port;
    sspi.spi_mosi_pin = SDI_Pin;
    sspi.spi_nss_port = CS_GPIO_Port;
    sspi.spi_nss_pin = CS_Pin;
    sspi.spi_sclk_port = SCL_GPIO_Port;
    sspi.spi_sclk_pin = SCL_Pin;

    if (spi_periph->mod == PL_LOW_PH_1EDGE || spi_periph->mod == PL_LOW_PH_2EDGE)
    {
        line_low(sspi.spi_nss_port, sspi.spi_nss_pin);
    }
    else
    {
        line_high(sspi.spi_nss_port, sspi.spi_nss_pin);
    }
}
static void clk_head(sspi_t *spi_periph)
{
    if (spi_periph->mod == PL_LOW_PH_1EDGE || spi_periph->mod == PL_LOW_PH_2EDGE)
    {
        line_high(sspi.spi_nss_port, sspi.spi_nss_pin);
    }
    else
    {
        line_low(sspi.spi_nss_port, sspi.spi_nss_pin);
    }
}
static void clk_tail(sspi_t *spi_periph)
{
    if (spi_periph->mod == PL_LOW_PH_1EDGE || spi_periph->mod == PL_LOW_PH_2EDGE)
    {
        line_low(sspi.spi_nss_port, sspi.spi_nss_pin);
    }
    else
    {
        line_high(sspi.spi_nss_port, sspi.spi_nss_pin);
    }
}

static void softspi_send_and_receive_bit(sspi_t *spi_periph, uint8_t *buf, uint8_t *rxbuf)
{
    uint8_t i = 0;
    uint8_t data_tmp = *buf;

    *rxbuf = 0x00;
    for (i = 0; i < 8; i++)
    {
        *rxbuf <<= 1;
        if (spi_periph->mod == PL_LOW_PH_1EDGE || spi_periph->mod == PL_HIGH_PH_1EDGE)
        {
            if (data_tmp & 0x80)
            {
                line_high(sspi.spi_mosi_port, sspi.spi_mosi_pin);
            }
            else
            {
                line_low(sspi.spi_mosi_port, sspi.spi_mosi_pin);
            }
            if (Gpio_GetInputIO(sspi.spi_miso_port, sspi.spi_miso_pin))
            {
                *rxbuf |= 0x01;
            }
            else
            {
                *rxbuf |= 0x00;
            }
            delay1us(2);
            clk_head(spi_periph);
            delay1us(2);
        }
        else
        {
            clk_head(spi_periph);
            delay1us(2);
            if (data_tmp & 0x80)
            {
                line_high(sspi.spi_mosi_port, sspi.spi_mosi_pin);
            }
            else
            {
                line_low(sspi.spi_mosi_port, sspi.spi_mosi_pin);
            }
            if (Gpio_GetInputIO(sspi.spi_miso_port, sspi.spi_miso_pin))
            {
                *rxbuf |= 0x01;
            }
            else
            {
                *rxbuf |= 0x00;
            }
            delay1us(2);
        }
        data_tmp = data_tmp << 1;
        clk_tail(spi_periph);
        delay1us(2);
    }
}

void softspi_send_and_receive(sspi_t *spi_periph, uint8_t *buf, uint8_t *rxbuf, uint8_t size)
{
    while (size != 0)
    {
        softspi_send_and_receive_bit(spi_periph, buf, rxbuf);
        buf++;
        rxbuf++;
        size--;
    }
}

H文件

#ifndef __SORFSPI_H_
#define __SORFSPI_H_

#include "main.h"

#define SOFT_SPI 1

// #define line_high(port, pin) Gpio_WriteOutputIO(port, pin, 1)
// #define line_low(port, pin) Gpio_WriteOutputIO(port, pin, 0)
#define line_high(port, pin) HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET)
#define line_low(port, pin) HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET)

enum spi_mode
{
    PL_LOW_PH_1EDGE = 0,
    PL_HIGH_PH_1EDGE,
    PL_LOW_PH_2EDGE,
    PL_HIGH_PH_2EDGE
};

typedef struct softspi
{
    GPIO_TypeDef* spi_mosi_port;
    uint16_t spi_mosi_pin;
    GPIO_TypeDef* spi_miso_port;
    uint16_t spi_miso_pin;
    GPIO_TypeDef* spi_sclk_port;
    uint16_t spi_sclk_pin;
    GPIO_TypeDef* spi_nss_port;
    uint16_t spi_nss_pin;
    enum spi_mode mod;
} sspi_t;

extern sspi_t sspi;

void softspi_init(sspi_t *spi_periph);
void softspi_send_and_receive(sspi_t *spi_periph, uint8_t *buf, uint8_t *rxbuf, uint8_t size);

#endif
posted on 2024-01-31 14:15  Nowonder  阅读(15)  评论(0编辑  收藏  举报