GD32f103系列教程—(SPI非DMA方式软件实现篇)

2023-12-15 11:41:11

一般单片机中配置一个SPI接口或者IIC等所有的通信接口套路都是固定的。

1.使能时钟

????????使能芯片上SPI模块的时钟

????????使能与SPI模块相连接的IO口的时钟,使能io口复用的时钟,因此程序为:

rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_SPI0);

2.配置IO口功能

SPI0

?

PA4—CS

PA5—SCK

PA6—MISO

PA7—MOSI

SPI1

?

?

PB12—CS

PB13—SCK

PB14—MISO

PB15—MOSI

SPI2

?

?

PB3—SCK

PB4—MISO

PB5—MOSI

PC9—Program

PA2—Done

PA3—INIT

PC6—RST

根据SPI协议,CS、MOSI为输出,MISO为输入,此处我的CS软件进行单独控制,不让硬件自动控制。

配置IO端口的状态,比如是推挽输出,还是浮空输入等,其次是IO口的速率

?gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7);

?gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6);

?gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);

3.配置SPI模块的具体设置

主要配置参数:

单双工,模式0123,传输字节高低位优先,主从模式,一次传输的字节长度,通信速率?

spi_parameter_struct spi_init_struct; ? ? ? ? ? ? ? ? ?// 定义一个SPI相关的结构体,用于配置SPI参数

? ? spi_i2s_deinit(SPI0); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 关闭SPI0,进行初始化前的清理操作

? ? spi_struct_para_init(&spi_init_struct); ? ? ? ? ? ? ? ?// 初始化spi_init_struct结构体,设置默认参数

? ? spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; // 配置SPI传输模式为全双工

? ? spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; // 配置SPI时钟极性和相位,时钟极性为低电平,时钟相位为第二个边沿

? ? spi_init_struct.nss = SPI_NSS_SOFT; ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 配置SPI片选信号使用软件控制

? ? spi_init_struct.endian = SPI_ENDIAN_MSB; // 配置SPI数据传输的字节顺序为最高位优先

? ? switch (model)

? ? {

? ? case 1: spi_init_struct.device_mode = SPI_MASTER; // 配置SPI工作模式为主模式

? ? ? ? break;

? ? case 0: spi_init_struct.device_mode = SPI_SLAVE; // 配置SPI工作模式为从模式

? ? ? ? break;

? ? default:

? ? ? ? return _FAIL;

? ? ? ? break;

? ? }

? ? switch (data_length)

? ? {

? ? case 8: spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; // 配置SPI数据帧大小为8位

? ? ? ? break;

? ? ?case 16: ?spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT; // 配置SPI数据帧大小为16位

? ? ? ? break;

? ? default:

? ? ? ? return _FAIL;

? ? ? ? break;

? ? }

? ? switch (clock_rate)

? ? {

? ? case 48:spi_init_struct.prescale = SPI_PSC_2; // 配置SPI预分频值,设置SPI时钟速率为96MHz / 2 = 48MHz

? ? ? ? break;

? ? case 24:spi_init_struct.prescale = SPI_PSC_4; // 配置SPI预分频值,设置SPI时钟速率为96MHz / 4 = 24MHz

? ? ? ? break;

? ? case 12:spi_init_struct.prescale = SPI_PSC_8; // 配置SPI预分频值,设置SPI时钟速率为96MHz / 8 = 12MHz

? ? ? ? break;

? ? case 6:spi_init_struct.prescale = SPI_PSC_16; // 配置SPI预分频值,设置SPI时钟速率为96MHz / 16 = 6MHz

? ? ? ? break;

? ? case 3:spi_init_struct.prescale = SPI_PSC_32; // 配置SPI预分频值,设置SPI时钟速率为96MHz / 32 = 3MHz

? ? ? ? break;

? ? default:

? ? ? ? ?return _FAIL;

? ? ? ? break;

? ? }

? ? spi_init(SPI0, &spi_init_struct); ? ? ? ?// 使用配置好的spi_init_struct结构体初始化SPI0

#if SPI_CRC_ENABLE

? ? spi_crc_polynomial_set(SPI0, 7);

? ? spi_crc_on(SPI0);

#endif

? ? spi_enable(SPI0);

4.传输数据

根据SPI协议,在写数据的时候可以同时进行读数据。

u16_t spi0_read_write_byte(u16_t data)
{
    u16_t ret;
    
    while (RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE))
        ;
    
    spi_i2s_data_transmit(SPI0, data);
    while (RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE))
        ;
    ret = spi_i2s_data_receive(SPI0);
    return ret;
}

?总的程序可以关注微信公众软件喵回复GD32F103SPI

文章来源:https://blog.csdn.net/m0_37755481/article/details/135010320
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。