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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!