.h
#ifndef __SPI_H
#define __SPI_H
#include "systick.h"
// SPI0
// PA4>>SPI0_NSS
// PA5>>SPI0_SCK
// PA7>>SPI0_MOSI
// PA6>>SPI0_MISO
// SPI1
// PA12>>SPI1_NSS
// PA13>>SPI1_SCK
// PA15>>SPI1_MOSI
// PA14>>SPI1_MISO
// a20216S
#define a_NSS_HIGH (GPIO_BOP(GPIOA) = BIT(4))
#define a_NSS_LOW (GPIO_BC(GPIOA) = BIT(4))
#define a_WAIT_END a_delay_us(30)
#define a_20216S_PAGE0 (0xA0)
#define a_20216S_PAGE1 (0xA1)
#define a_20216S_PAGE2 (0xA2)
#define a_20216S_PAGE3 (0xA3)
#define a_20216S_PAGE4 (0xA4)
#define HEAD_ADDRESS (0x00)
#define OFFSET_ADDRESS (0x2)
#define REGISTER_ADDRESS (0x33)
#define a_ERASE_DATA (0xff)
#define SPI_ERROR (1)
void a_spi_gpio_init(void);
void a_spi_parameter_init(void);
/* spi data transmission */
a_U8 a_spi_transmit_byte(a_U8 data);
/* register data erase */
a_U8 a_spi_erase_data(void);
/* single register write operation */
a_U8 a_spi_write(a_U8 page_x, a_U8 register_addr, a_U8 data);
/* single register read operation*/
a_U8 a_spi_read(a_U8 page_x, a_U8 register_addr, a_U8 data);
/* multiple register write operation */
a_U8 a_spi_write_bytes(a_U8 page_x, a_U8 register_addr, a_U8 data_size, a_U8 *data);
/* multiple register read operation*/
a_U8 a_spi_read_bytes(a_U8 page_x, a_U8 register_addr, a_U8 data_size, a_U8 *data);
#endif
.c
#include "a_spi.h"
/* gpio init */
void a_spi_gpio_init(void)
{
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_SPI0);
// PA4-->SPI0_NSS
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
// PA5-->SPI0_SCK
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
// PA6-->SPI0_MISO
gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
// PA7-->SPI0_MOSI
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
// idle state
gpio_bit_reset(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
}
/* spi init */
void a_spi_parameter_init(void)
{
spi_parameter_struct spi_parameter_init_struct;
spi_parameter_init_struct.device_mode = SPI_MASTER;
spi_parameter_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_parameter_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
spi_parameter_init_struct.nss = SPI_NSS_SOFT;
spi_parameter_init_struct.endian = SPI_ENDIAN_MSB;
spi_parameter_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spi_parameter_init_struct.prescale = SPI_PSC_256;
spi_init(SPI0, &spi_parameter_init_struct);
spi_enable(SPI0);
// register data erase
a_spi_erase_data();
}
/* spi data transmission */
a_U8 a_spi_transmit_byte(a_U8 data)
{
a_U8 receive_data = 0x00;
// check TBE non empty
a_U8 timeout = 0;
while (spi_i2s_flag_get(SPI0, I2C_FLAG_TBE) == RESET) {
if ((timeout++) == 1000) {
return SPI_ERROR;
}
}
spi_i2s_data_transmit(SPI0, data);
// check RBNE non empty
timeout = 0;
while (spi_i2s_flag_get(SPI0, I2C_FLAG_RBNE) == RESET) {
if ((timeout++) == 1000) {
return SPI_ERROR;
}
}
receive_data = i2c_data_receive(SPI0);
return receive_data;
}
/* register data erase */
a_U8 a_spi_erase_data(void)
{
a_spi_transmit_byte(a_ERASE_DATA);
}
/* single register write operation */
a_U8 a_spi_write(a_U8 page_x, a_U8 register_addr, a_U8 data)
{
a_U8 i = 0;
a_NSS_LOW;
a_spi_transmit_byte(page_x);
a_spi_transmit_byte(register_addr++);
a_spi_transmit_byte(data);
a_WAIT_END;
a_NSS_HIGH;
a_WAIT_END;
}
/* single register read operation*/
a_U8 a_spi_read(a_U8 page_x, a_U8 register_addr, a_U8 data)
{
a_U8 i = 0;
a_NSS_LOW;
a_spi_transmit_byte(page_x + 1);
a_spi_transmit_byte(register_addr++);
a_spi_transmit_byte(data);
a_WAIT_END;
a_NSS_HIGH;
}
/* multiple register write operation */
a_U8 a_spi_write_bytes(a_U8 page_x, a_U8 register_addr, a_U8 data_size, a_U8 *data)
{
a_U8 i = 0;
a_NSS_LOW;
a_spi_transmit_byte(page_x);
for (i = 0; i < data_size; i++) {
a_spi_transmit_byte(register_addr++);
a_spi_transmit_byte(data[i]);
}
a_WAIT_END;
a_NSS_HIGH;
a_WAIT_END;
}
/* multiple register read operation*/
a_U8 a_spi_read_bytes(a_U8 page_x, a_U8 register_addr, a_U8 data_size, a_U8 *data)
{
a_U8 i = 0;
a_NSS_LOW;
a_spi_transmit_byte(page_x + 1);
for (i = 0; i < data_size; i++) {
a_spi_transmit_byte(register_addr++);
a_spi_transmit_byte(data[i]);
}
a_WAIT_END;
a_NSS_HIGH;
}
.main
#include "a_system_config.h"
#include "gd32f30x_gpio.h"
#include "systick.h"
#include "gd32f30x_it.h"
#include "stdio.h"
#include "a_usart.h"
#include "a_spi.h"
int main(void)
{
// 系统时钟
systick_config();
//USART0 init
a_usart_init();
a_spi_gpio_init();
a_spi_parameter_init();
while (1) {
a_U8 a_empty_data = 0xff;
a_U8 a_writ_data = 0x07;
a_U8 a_empty_buff[2] = {0xff, 0xff};
a_U8 a_write_buff[2] = {0x07,0x14};
/* single register read/write operation */
a_spi_write(a_20216S_PAGE1, REGISTER_ADDRESS, a_writ_data);
a_spi_read(a_20216S_PAGE1, REGISTER_ADDRESS, a_empty_data);
/* multiple register read/write operation */
a_spi_write_bytes(a_20216S_PAGE0, HEAD_ADDRESS, OFFSET_ADDRESS, a_write_buff);
a_spi_read_bytes(a_20216S_PAGE0, HEAD_ADDRESS, OFFSET_ADDRESS, a_empty_buff);
// a_NSS_LOW;
// a_spi_transmit_byte(0xA0);
// a_spi_transmit_byte(0x00);
// a_spi_transmit_byte(0x45);
// a_delay_us(30);
// a_NSS_HIGH;
//
// a_delay_1s;
//
// a_NSS_LOW;
// a_spi_transmit_byte(0xA1);
// a_spi_transmit_byte(0x00);
// a_spi_transmit_byte(0x02);
// a_delay_us(30);
// a_NSS_HIGH;
// a_delay_1s;
}