8784|4

57

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【liklon玩GD32F350】四、SPI0读写spiflash [复制链接]

在后续的开发中要用到一个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”然后读出打印:

看到打印的字符串是预期效果,应该是成功了。
此帖出自GD32 MCU论坛

最新回复

楼主用的多少M的时钟频率啊,为什么我读状态寄存器一直都是0XFF?   详情 回复 发表于 2019-11-19 14:26
点赞 关注(2)
 

回复
举报

33

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
楼主你用的是W25X  flash吗??
此帖出自GD32 MCU论坛

点评

是的,华邦的  详情 回复 发表于 2018-10-9 11:07
 
 
 

回复

931

帖子

3

TA的资源

纯净的硅(中级)

板凳
 
收藏学习,谢谢楼主分享经验。
此帖出自GD32 MCU论坛
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(中级)

4
 
linshifaa 发表于 2018-10-4 00:53
楼主你用的是W25X  flash吗??

是的,华邦的
此帖出自GD32 MCU论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

5
 

楼主用的多少M的时钟频率啊,为什么我读状态寄存器一直都是0XFF?

此帖出自GD32 MCU论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表