GD32 SPI驱动代码

1.0 软件驱动NOR FLASH

MOSI:主机发送,从机接收

MISO:主机接收,从机发送

CS:表示的是片选信号


 2.0 宏定义各个引脚

// 片选
#define SET_SPI_NSS()		gpio_bit_set(GPIOE,GPIO_PIN_2)
#define CLR_SPI_NSS()		gpio_bit_reset(GPIOE_GPIO_PIN_2)

// SPI引脚电平
#define SET_SPI_SCK()		gpio_bit_set(GPIOB,GPIO_PIN_13)
#define CLR_SPI_SCK()		gpio_bit_reset(GPIOB,GPIO_PIN_13)

// 主机输出从机输出
#define READ_SPI_MISO() 	gpio_input_bit_get(GPIOB,CPIO_PIN_14)

// 主机输出从机输入
#define SET_SPI_MOSI()		gpio_bit_set(GPIOB,GPIO_PIN_15)
#define CLR_SPI_MOSI()		gpio_bit_reset(GPIOB,GPIO_PIN_15)

3.0 SPI 初始化

static void SPI_Init(void)
{
		// GPIO 初始化
		GPIO_Init();
		// 片选信号设置为高电平
	   	SET_SPI_NSS();
		// 时钟信号设置为低电平
		CLR_SPI_SCK();
		
}

NOR FLASH支持两种模式,此处使用的是模式0

4.0 SPI 起始信号和结束信号

// 起始信号:片选信号从高电平变为低电平
static void SPIStart(void)
{
		CLR_SPI_NSS();
}

// 结束信号:片选信号从低电平变为高电平
static void SPIStop(void)
{
		SET_SPI_NSS();
}

5.0 SPI 读写字节

此处并没有使用延时,SPI总线的时钟频率是很快的,并且不需要额外的增加延时的函数

// SPI读写一个字节的数据
static uint8_t SPIReadWriteByte(uint8_t sendData)
{
	uint8_t rcvData = 0;
	uint8_t i = 0;
	
	for(i = 0; i < 8; i++)
	{
		if((sendData & 0x80))
		{
			SET_SPI_MOSI();
		}
		else
		{
			CLR_SPI_MOSI();
		}
		sendData <<= 1;
		SET_SPI_SCK();
		rcvData <<= 1;
		rcvData |= READ_SPI_MISO();
		CLR_SPI_SCK();
	}
		return rcvData;
}

6.0 完整代码

#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include "gd32f30x.h"
#include "delay.h"


#define SET_SPI_NSS()		gpio_bit_set(GPIOE,GPIO_PIN_2)
#define CLR_SPI_NSS()		gpio_bit_reset(GPIOE,GPIO_PIN_2)

#define SET_SPI_SCK()		gpio_bit_set(GPIOB,GPIO_PIN_13)
#define CLR_SPI_SCK()		gpio_bit_reset(GPIOB,GPIO_PIN_13)

#define READ_SPI_MISO()     gpio_input_bit_get(GPIOB, GPIO_PIN_14) 

#define SET_SPI_MOSI()		gpio_bit_set(GPIOB,GPIO_PIN_15)
#define CLR_SPI_MOSI()		gpio_bit_reset(GPIOB,GPIO_PIN_15)


static void GPIO_Init()
{
		// PE2片选SS
		rcu_periph_clock_enable(RCU_GPIOE);
		gpio_init(GPIOE,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_2);
		gpio_bit_set(GPIOE,GPIO_PIN_2);
	
		// PB13作为SCK
		rcu_periph_clock_enable(RCU_GPIOB);
		gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_2);
		gpio_bit_set(GPIOE,GPIO_PIN_2);
	
		// PB14作为MISO
		gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_14);
		
		// PB15作为MOSI
		gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_15);
		gpio_bit_set(GPIOB,GPIO_PIN_15);
		
};


static void SPI_Init(void)
{
		// GPIO 初始化
		GPIO_Init();
		// 片选信号设置为高电平
	   	SET_SPI_NSS();
		// 时钟信号设置为低电平
		CLR_SPI_SCK();	
}

// 起始信号:片选信号从高电平变为低电平
static void SPIStart(void)
{
		CLR_SPI_NSS();
}

// 结束信号:片选信号从低电平变为高电平
static void SPIStop(void)
{
		SET_SPI_NSS();
}

// SPI读写一个字节的数据
static uint8_t SPIReadWriteByte(uint8_t sendData)
{
	uint8_t rcvData = 0;
	uint8_t i = 0;
	
	for(i = 0; i < 8; i++)
	{
		if((sendData & 0x80))
		{
			SET_SPI_MOSI();
		}
		else
		{
			CLR_SPI_MOSI();
		}
		sendData <<= 1;
		SET_SPI_SCK();
		rcvData <<= 1;
		rcvData |= READ_SPI_MISO();
		CLR_SPI_SCK();
	}
		return rcvData;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值