|
【liklon玩GD32F350】四、SPI0读写spiflash
[复制链接]
在后续的开发中要用到一个spiflash,就开始调试GD32的SPI功能。目前GD提供的这个板子资源真的是少,应该说是除了MCU就木有啥了。找来一个空板焊上spiflash,接线:
- SPI0 PA5(CLK)&PA6(MISO)&PA7(MOSI) PA4(CS)
复制代码
在调试SPI前先确定焊的FLASH是否可以用,则使用了IO口模拟SPI确定没有问题后再进行调试,因此在代码中做了如下条件编译:
- /**
- * SPI0 PA5(CLK)&PA6(MISO)&PA7(MOSI) PA4(CS)
- */
- #if USE_SPI0
- gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_5);
- gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_6);
- gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_7);
- gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_5);
- gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5);
-
- gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6);
-
- gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7);
- gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
- #else
- gpio_mode_set(F_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, F_CLK_PIN);
- gpio_output_options_set(F_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, F_CLK_PIN);
- gpio_mode_set(F_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, F_MI_PIN);
- gpio_mode_set(F_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, F_MO_PIN);
- gpio_output_options_set(F_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, F_MO_PIN);
- gpio_bit_reset(F_PORT, F_CLK_PIN);
- gpio_bit_reset(F_PORT, F_MO_PIN);
- #endif
- gpio_mode_set(F_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, F_CS_PIN);
- gpio_output_options_set(F_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, F_CS_PIN);
- gpio_bit_set(F_PORT, F_CS_PIN);
复制代码
利用模拟SPI是成功读写FLASH,那么开始调试GD32的SPI0。
1)使能SPI0时钟:
- rcu_periph_clock_enable(RCU_SPI0);
复制代码
2)配置IO,上文已经贴出代码。
3)配置SPI0(目前暂时未使用DMA)
- void spi0_init()
- {
- #if USE_SPI0
- spi_parameter_struct spi_parameter =
- {
- .device_mode = SPI_MASTER,
- .trans_mode = SPI_TRANSMODE_FULLDUPLEX,
- .frame_size = SPI_FRAMESIZE_8BIT,
- .nss = SPI_NSS_SOFT,
- .endian = SPI_ENDIAN_MSB,
- .clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE,
- .prescale = SPI_PSC_2
- };
-
- spi_init(SPI0, &spi_parameter);
- spi_enable(SPI0);
- #endif
- }
复制代码
4)SPI0读写函数(这里遇到过坑)
在使用标准库时要调用库中函数习惯性的直接看H文件,那么可以看到如下两个接口:
- /* SPI transmit data */
- void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data);
- /* SPI receive data */
- uint16_t spi_i2s_data_receive(uint32_t spi_periph);
复制代码
如果你认为分别调用这两个接口是完成写和读,那么就入坑了。调试后发现需要这么写:
- uint8_t spi0_rw_byte(uint8_t ch)
- {
- uint16_t tmp;
- while(spi_i2s_flag_get(SPI0, SPI_FLAG_TBE) == RESET);
- spi_i2s_data_transmit(SPI0, ch);
- while(spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE) == RESET);
- tmp = spi_i2s_data_receive(SPI0);
- return ((uint8_t)(tmp & 0xff));
- }
复制代码
SPI调试好后,写好SPIFLASH的驱动,那么就测试...
- uart_init();
- uart1_write((uint8_t *)"hello world\n\r", 13);
-
- spi0_init();
- flash_erase_xsector(0x0, 1);
- flash_write_buf((uint8_t *)"liklon gd32f350", 0, 15);
- flash_read_buf(tmp_table, 0, 15);
- uart1_write(tmp_table, 15);
- while(1)
- {
- }
复制代码
写入“liklon gd32f350”然后读出打印:
看到打印的字符串是预期效果,应该是成功了。
|
|