模拟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