STM32 模拟SPI

软件模拟SPI通讯
(1) CKPOL (Clock Polarity) = CPOL = POL = Polarity = (时钟)极性
(2) CKPHA (Clock Phase) = CPHA = PHA = Phase = (时钟)相位
(3) SCK=SCLK=SPI的时钟
(4) Edge=边沿,即时钟电平变化的时刻,即上升沿(rising edge)或者下降沿(falling edge)

soft_spi.h

#ifndef __SOFT_SPI_H
#define __SOFT_SPI_H

#include "main.h"

#ifndef HIGH
#define HIGH                1
#endif /* HIGH */

#ifndef LOW
#define LOW                 0
#endif /* LOW */

#define SPI_SCK(x)			HAL_GPIO_WritePin(SPI6_SCK_GPIO_Port,SPI6_SCK_Pin,(GPIO_PinState)x)
#define SPI_MOSI(x)			HAL_GPIO_WritePin(SPI6_MOSI_GPIO_Port,SPI6_MOSI_Pin,(GPIO_PinState)x)
#define SPI_MISO			HAL_GPIO_ReadPin(SPI6_MISO_GPIO_Port,SPI6_MISO_Pin)

uint8_t write_spi_byte(uint8_t Byte);
uint8_t read_spi_byte(void);

#endif /* __BSP_SPI_H */

soft_spi.c

#include "soft_spi.h"

#define WAIT_TIME		2

/*
 * MODE 0:CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,数据采样是在第 1个边沿,	\
 * 			也就是 SCLK由低电平到高电平的跳变,所以数据采样是在上升沿,数据发送是在下降沿。

 * MODE 1:CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,数据发送是在第 2个边沿,	\
 * 			也就是 SCLK由高电平到低电平的跳变,所以数据采样是在下降沿,数据发送是在上升沿。

 * MODE 2:CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,数据采集是在第 1个边沿,	\
 * 			也就是 SCLK由高电平到低电平的跳变,所以数据采集是在下降沿,数据发送是在上升沿。

 * MODE 3:CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,数据发送是在第 2个边沿,	\
 * 			也就是 SCLK由低电平到高电平的跳变,所以数据采集是在上升沿,数据发送是在下降沿。
*/
#define _CPOL     1
#define _CPHA     1

/************************************************
函数名称 : SPI_Delay_us
功    能 : 软件毫秒延时
参    数 : Count ---- 次数
返 回 值 : 无
*************************************************/
static void spi_delay_us( uint32_t Count )
{
    delay_us(Count);
}

#if (0 == _CPOL && 0 == _CPHA) /* ----- MODE 0 ----- */
/************************************************
函数名称 : Write_SPI_Byte
功    能 : SPI写读一个字节
参    数 : Byte ---- 数据
返 回 值 : Byte ---- 数据
*************************************************/
uint8_t write_spi_byte( uint8_t Byte )
{
	uint8_t i;
	
	for(i = 0;i < 8;i++)
	{
		SPI_SCK(LOW);
		spi_delay_us(WAIT_TIME);       // 空等待
		
	#if 0
        SPI_MOSI((Byte & 0x80) >> 7);
		
	#else
		if(Byte & 0x80)
		{
			SPI_MOSI(HIGH);
		}
		else
		{
			SPI_MOSI(LOW);
		}
		
	#endif
		Byte <<= 1;
		spi_delay_us(WAIT_TIME);       // 空等待
		SPI_SCK(HIGH);
		spi_delay_us(WAIT_TIME);       // 空等待
		Byte |= SPI_MISO;
	}
	
	SPI_SCK(LOW);
	
	return Byte;
}

/************************************************
函数名称 : Read_SPI_Byte
功    能 : SPI只读一个字节
参    数 : 无
返 回 值 : temp ---- 数据
*************************************************/
uint8_t read_spi_byte(void)
{
	uint8_t i;
	uint8_t temp = 0;
	
	for(i = 0;i < 8;i++)
	{
		SPI_SCK(LOW);
		spi_delay_us(WAIT_TIME);       // 空等待
		temp <<= 1;
		
	#if 1
		temp |= SPI_MISO;
		
	#else
		if(SPI_MISO)
		{
			temp++;
		}
		
	#endif
		SPI_SCK(HIGH);
		spi_delay_us(WAIT_TIME);       // 空等待
	}

	SPI_SCK(LOW);

	return temp;
}

#elif (0 == _CPOL && 1 == _CPHA) /* ----- MODE 1 ----- */
/************************************************
函数名称 : Write_SPI_Byte
功    能 : SPI写读一个字节
参    数 : Byte ---- 数据
返 回 值 : Byte ---- 数据
*************************************************/
uint8_t write_spi_byte( uint8_t Byte )
{
	uint8_t i;

	SPI_SCK(LOW);
	
	for(i = 0;i < 8;i++)
	{
		SPI_SCK(HIGH);
		spi_delay_us(WAIT_TIME);       // 空等待
		
	#if 0
        SPI_MOSI((Byte & 0x80) >> 7);
		
	#else
		if(Byte & 0x80)
		{
			SPI_MOSI(HIGH);
		}
		else
		{
			SPI_MOSI(LOW);
		}
		
	#endif
		Byte <<= 1;
		spi_delay_us(WAIT_TIME);       // 空等待
		SPI_SCK(LOW);
		spi_delay_us(WAIT_TIME);       // 空等待
		Byte |= SPI_MISO;
	}
	
	return Byte;
}

/************************************************
函数名称 : Read_SPI_Byte
功    能 : SPI只读一个字节
参    数 : 无
返 回 值 : temp ---- 数据
*************************************************/
uint8_t read_spi_byte(void)
{
	uint8_t i;
	uint8_t temp = 0;

	SPI_SCK(LOW);
	
	for(i = 0;i < 8;i++)
	{
		SPI_SCK(HIGH);
		spi_delay_us(WAIT_TIME);       // 空等待
		temp <<= 1;
		
	#if 1
		temp |= SPI_MISO;
		
	#else
		if(SPI_MISO)
		{
			temp++;
		}
		
	#endif
		SPI_SCK(LOW);
		spi_delay_us(WAIT_TIME);       // 空等待
	}
	
	return temp;
}

#elif (1 == _CPOL && 0 == _CPHA) /* ----- MODE 2 ----- */
/************************************************
函数名称 : Write_SPI_Byte
功    能 : SPI写读一个字节
参    数 : Byte ---- 数据
返 回 值 : Byte ---- 数据
*************************************************/
uint8_t write_spi_byte( uint8_t Byte )
{
	uint8_t i;
	
	for(i = 0;i < 8;i++)
	{
		SPI_SCK(HIGH);
		spi_delay_us(WAIT_TIME);       // 空等待
		
	#if 0
        SPI_MOSI((Byte & 0x80) >> 7);
		
	#else
		if(Byte & 0x80)
		{
			SPI_MOSI(HIGH);
		}
		else
		{
			SPI_MOSI(LOW);
		}
		
	#endif
		Byte <<= 1;
		spi_delay_us(WAIT_TIME);       // 空等待
		SPI_SCK(LOW);
		spi_delay_us(WAIT_TIME);       // 空等待
		Byte |= SPI_MISO;
	}
	
	SPI_SCK(HIGH);
	
	return Byte;
}

/************************************************
函数名称 : Read_SPI_Byte
功    能 : SPI只读一个字节
参    数 : 无
返 回 值 : temp ---- 数据
*************************************************/
uint8_t read_spi_byte(void)
{
	uint8_t i;
	uint8_t temp = 0;
	
	for(i = 0;i < 8;i++)
	{
		SPI_SCK(HIGH);
		spi_delay_us(WAIT_TIME);       // 空等待
		temp <<= 1;
		
	#if 1
		temp |= SPI_MISO;
		
	#else
		if(SPI_MISO)
		{
			temp++;
		}
		
	#endif
		SPI_SCK(LOW);
		spi_delay_us(WAIT_TIME);       // 空等待
	}

	SPI_SCK(HIGH);

	return temp;
}

#elif (1 == _CPOL && 1 == _CPHA) /* ----- MODE 3 ----- */
/************************************************
函数名称 : Write_SPI_Byte
功    能 : SPI写读一个字节
参    数 : Byte ---- 数据
返 回 值 : Byte ---- 数据
*************************************************/
uint8_t write_spi_byte( uint8_t Byte )
{
	uint8_t i;

	SPI_SCK(HIGH);
	
	for(i = 0;i < 8;i++)
	{
		SPI_SCK(LOW);
		spi_delay_us(WAIT_TIME);       // 空等待
		
	#if 0
        SPI_MOSI((Byte & 0x80) >> 7);
		
	#else
		if(Byte & 0x80)
		{
			SPI_MOSI(HIGH);
		}
		else
		{
			SPI_MOSI(LOW);
		}
		
	#endif
		Byte <<= 1;
		spi_delay_us(WAIT_TIME);       // 空等待
		SPI_SCK(HIGH);
		spi_delay_us(WAIT_TIME);       // 空等待
		Byte |= SPI_MISO;
	}
	
	return Byte;
}

/************************************************
函数名称 : Read_SPI_Byte
功    能 : SPI只读一个字节
参    数 : 无
返 回 值 : temp ---- 数据
*************************************************/
uint8_t read_spi_byte(void)
{
	uint8_t i;
	uint8_t temp = 0;

	SPI_SCK(HIGH);
	
	for(i = 0;i < 8;i++)
	{
		SPI_SCK(LOW);
		spi_delay_us(WAIT_TIME);       // 空等待
		temp <<= 1;
		
	#if 1
		temp |= SPI_MISO;
		
	#else
		if(SPI_MISO)
		{
			temp++;
		}
		
	#endif
		SPI_SCK(HIGH);
		spi_delay_us(WAIT_TIME);       // 空等待
	}
	
	return temp;
}

#endif /* SPI MODE */


/*---------------------------- END OF FILE ----------------------------*/


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值