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片选SSrcu_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作为SCKrcu_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作为MISOgpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_14);// PB15作为MOSIgpio_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;
}