注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
liklon的个人空间 https://home.eeworld.com.cn/space-uid-343627.html [收藏] [复制] [分享] [RSS]
日志

【liklon玩GD32F350】四、SPI0读写spiflash

已有 3431 次阅读2018-9-5 10:41

在后续的开发中要用到一个spiflash,就开始调试GD32的SPI功能。目前GD提供的这个板子资源真的是少,应该说是除了MCU就木有啥了。找来一个空板焊上spiflash,接线:
  1. SPI0  PA5(CLK)&PA6(MISO)&PA7(MOSI)     PA4(CS)
复制代码



在调试SPI前先确定焊的FLASH是否可以用,则使用了IO口模拟SPI确定没有问题后再进行调试,因此在代码中做了如下条件编译:
  1.     /**
  2.      *  SPI0  PA5(CLK)&PA6(MISO)&PA7(MOSI)     PA4(CS)
  3.      */
  4. #if USE_SPI0     
  5.     gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_5);
  6.     gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_6);
  7.     gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_7);
  8.     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_5);
  9.     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5);
  10.    
  11.     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6);
  12.    
  13.     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7);
  14.     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
  15. #else  
  16.     gpio_mode_set(F_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, F_CLK_PIN);
  17.     gpio_output_options_set(F_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, F_CLK_PIN);  
  18.     gpio_mode_set(F_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, F_MI_PIN);
  19.     gpio_mode_set(F_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, F_MO_PIN);
  20.     gpio_output_options_set(F_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, F_MO_PIN);
  21.     gpio_bit_reset(F_PORT, F_CLK_PIN);
  22.     gpio_bit_reset(F_PORT, F_MO_PIN);
  23. #endif
  24.     gpio_mode_set(F_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, F_CS_PIN);
  25.     gpio_output_options_set(F_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, F_CS_PIN);
  26.     gpio_bit_set(F_PORT, F_CS_PIN);
复制代码

利用模拟SPI是成功读写FLASH,那么开始调试GD32的SPI0。
1)使能SPI0时钟:
  1. rcu_periph_clock_enable(RCU_SPI0);
复制代码

2)配置IO,上文已经贴出代码。
3)配置SPI0(目前暂时未使用DMA)
  1. void spi0_init()
  2. {
  3. #if USE_SPI0   
  4.     spi_parameter_struct spi_parameter =
  5.     {
  6.         .device_mode = SPI_MASTER,
  7.         .trans_mode = SPI_TRANSMODE_FULLDUPLEX,
  8.         .frame_size = SPI_FRAMESIZE_8BIT,
  9.         .nss = SPI_NSS_SOFT,
  10.         .endian = SPI_ENDIAN_MSB,
  11.         .clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE,
  12.         .prescale = SPI_PSC_2
  13.     };
  14.    
  15.     spi_init(SPI0, &spi_parameter);
  16.     spi_enable(SPI0);
  17. #endif   
  18. }
复制代码

4)SPI0读写函数(这里遇到过坑
在使用标准库时要调用库中函数习惯性的直接看H文件,那么可以看到如下两个接口:
  1. /* SPI transmit data */
  2. void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data);
  3. /* SPI receive data */
  4. uint16_t spi_i2s_data_receive(uint32_t spi_periph);
复制代码

如果你认为分别调用这两个接口是完成写和读,那么就入坑了。调试后发现需要这么写:
  1. uint8_t spi0_rw_byte(uint8_t ch)
  2. {
  3.     uint16_t tmp;
  4.     while(spi_i2s_flag_get(SPI0, SPI_FLAG_TBE) == RESET);
  5.     spi_i2s_data_transmit(SPI0, ch);
  6.     while(spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE) == RESET);
  7.     tmp = spi_i2s_data_receive(SPI0);
  8.     return ((uint8_t)(tmp & 0xff));
  9. }
复制代码

SPI调试好后,写好SPIFLASH的驱动,那么就测试...
  1.     uart_init();
  2.     uart1_write((uint8_t *)"hello world\n\r", 13);
  3.    
  4.     spi0_init();
  5.     flash_erase_xsector(0x0, 1);
  6.     flash_write_buf((uint8_t *)"liklon gd32f350", 0, 15);
  7.     flash_read_buf(tmp_table, 0, 15);
  8.     uart1_write(tmp_table, 15);
  9.     while(1)
  10.     {

  11.     }
复制代码

写入“liklon gd32f350”然后读出打印:

看到打印的字符串是预期效果,应该是成功了。

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章