(实测可用)GD32F303RCT6开发板移植RT-Thread操作系统(SPI Flash读写存储信息W25Q16)

本文介绍了如何在GD32F303RCT6开发板上移植RT-Thread操作系统,包括选择BSP、修改芯片配置、设置Debug串口和Flash下载模式。接着详细阐述了添加W25QSPI驱动的过程,涉及线程创建、驱动函数编写和头文件声明。最后,配置了KEIL软件的下载选项以确保程序正确下载到开发板,并展示了串口打印的验证结果,证明W25QSPI芯片读写成功。
摘要由CSDN通过智能技术生成

 一、开发板平台简介:

1、开发板资源简介

(1)开发板主芯片型号:GD32F303RCT6

(2)开发板主芯片封装:LQFP-64_10x10x05P

(3)开发板主芯片内核:ARM® Cortex®-M4

(4)开发板主芯片主频:120MHz

(5)开发板主芯片Flash大小:256KB

(6)开发板主芯片RAM大小:48KB

2、Debug调试串口简介

        串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。

(1)我们选用的GD32F303RCT6开发板串口0已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得安装CH340G驱动)。

(2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。

二、快速上手RT-Thread

1、选择合适的BSP

(1)我们这里选择GD32303E-EVAL BSP驱动进行移植。可通过如下参考链接下载bsp:

GD32303E-EVALhttps://github.com/RT-Thread/rt-thread/tree/master/bsp/gd32303e-eval

(2)下载上述bsp后就可以在开发板上进行移植尝试了。

2、移植BSP

        已下载的GD32303E-EVEL BSP工程文件,是使用 GD32F303ZET6 作为主控制器的,想要移植到我们的GD32F303RCT6开发板上,需要进行简单的修改,如下:

(1)找到gd32f303-bsp文件,并打开项目。

​​​

 (2)选择options for target-->选择GD32F303RC芯片。

​​​

(3)选择对应的下载器,我这里使用的是jlink ,并选择SWD下载模式。

​​​

(4) 设置Flash Download下载模式。

​​​

(5)那么接下来重点来了,直接下载的代码在GD32F303RCT6是无法运行的,因为GD32F303ZET6的RAM大小为64K,但是GD32F303RCT6的RAM大小为48K。此处需要在board.h头文件中把RAM大小(GD32_SRAM_SIZE)修改为48,如下所示:

​​​

 (6)修改后,重新编译下载,即可通过Debug串口看到打印的log信息。

​​​

三、添加w25q SPI线程

1、新建线程并启动

在components.c文件中,找到rt_application_init(void)函数,并添加新建rtc时钟线程的声明。

rt_thread_t zyxc_w25q_thread;
    zyxc_w25q_thread=rt_thread_create("w25q", zyxc_w25q_thread_entry, RT_NULL,1024, 28, 20);	//创建SPI线程
    if(zyxc_w25q_thread!= RT_NULL)
    {
        rt_thread_startup(zyxc_w25q_thread);
    }

​​​

2、添加w25q SPI驱动函数

(1)新建zyxc_w25q.c并添加所需的头文件。

#include "zyxc_w25q.h"
#include "gd32f30x.h"
#include <string.h>
#include <rtthread.h>

(2)打开zyxc_rtc.c文件,并在其中编写w25q函数执行语句,如下所示:

/********************************************
*函数名称:void zyxc_w25q_thread_entry(void *parameter)
*函数功能:空闲线程
*备注:用于看门狗、指示灯等空闲操作
********************************************/
void zyxc_w25q_thread_entry(void *parameter)
{

    uint32_t flash_id = 0;
    uint16_t i = 0;
    uint8_t  tx_buffer[TX_BUFFER_SIZE];
    uint8_t  rx_buffer[TX_BUFFER_SIZE];
    uint8_t  is_successful = 0;
		uint8_t  count=0;
    /* configure SPI0 GPIO and parameter */
    spi_flash_init();
    /* GD32303E-EVAL-V1.0 Start up */
    rt_kprintf("\n\r###############################################################################\n\r");
    rt_kprintf("\n\rGD32303E-EVAL-V1.0 System is Starting up...\n\r");
    rt_kprintf("\n\rGD32303E-EVAL-V1.0 Flash:%dK\n\r",*(__IO uint16_t*)(0x1FFFF7E0));
    /* get chip serial number */
    get_chip_serial_num();

    /* printf CPU unique device id */
    rt_kprintf("\n\rGD32303E-EVAL-V1.0 The CPU Unique Device ID:[%X-%X-%X]\n\r",int_device_serial[2],int_device_serial[1],int_device_serial[0]);

    rt_kprintf("\n\rGD32303E-EVAL-V1.0 SPI Flash:GD25Q16 configured...\n\r");

    /* get flash id */
    flash_id = spi_flash_read_id();

    rt_kprintf("\n\rThe Flash_ID:0x%X\n\r",flash_id);

    /* flash id is correct */
    if(flash_id!=0xFFFFFFFF) {
        rt_kprintf("\n\r\n\rWrite to tx_buffer:\n\r\n\r");

        /* printf tx_buffer value */
        for(i = 0; i < BUFFER_SIZE; i ++) {
            tx_buffer[i] = i;
            rt_kprintf("0x%02X ",tx_buffer[i]);

            if(15 == i%16)
                rt_kprintf("\n\r");
        }

        rt_kprintf("\n\r\n\rRead from rx_buffer:\n\r");

        /* erases the specified flash sector */
        spi_flash_sector_erase(FLASH_WRITE_ADDRESS);
        /* write tx_buffer data to the flash */
        spi_flash_buffer_write(tx_buffer,FLASH_WRITE_ADDRESS,TX_BUFFER_SIZE);

        rt_thread_delay(10);

        /* read a block of data from the flash to rx_buffer */
        spi_flash_buffer_read(rx_buffer,FLASH_READ_ADDRESS,RX_BUFFER_SIZE);
        /* printf rx_buffer value */
        for(i = 0; i <= 255; i ++) {
            rt_kprintf("0x%02X ", rx_buffer[i]);
            if(15 == i%16)
                rt_kprintf("\n\r");
        }

        if(ERROR == memory_compare(tx_buffer,rx_buffer,256)) {
            rt_kprintf("Err:Data Read and Write aren't Matching.\n\r");
            is_successful = 1;
        }

        /* spi flash test passed */
        if(0 == is_successful) {
            rt_kprintf("\n\rSPI-GD25Q16 Test Passed!\n\r");
        }
    } else {
        /* spi flash read id fail */
        rt_kprintf("\n\rSPI Flash: Read ID Fail!\n\r");
    }

    while(1)
    {
        rt_thread_delay(5);
    }

}

(3)新建zyxc_w25q.h头文件并声明调用函数。

/*!
    \file  gd25qxx.h
    \brief the header file of SPI flash gd25qxx driver

    \version 2021-03-23, V2.0.0, demo for GD32F30x
*/

/*
    Copyright (c) 2021, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this 
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice, 
       this list of conditions and the following disclaimer in the documentation 
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors 
       may be used to endorse or promote products derived from this software without 
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
*/

#ifndef GD25QXX_H
#define GD25QXX_H

#include "gd32f30x.h"

#define  SPI_FLASH_PAGE_SIZE       0x100
#define  SPI_FLASH_CS_LOW()        gpio_bit_reset(GPIOB, GPIO_PIN_12)
#define  SPI_FLASH_CS_HIGH()       gpio_bit_set(GPIOB, GPIO_PIN_12)
#define BUFFER_SIZE                    256
#define TX_BUFFER_SIZE                 BUFFER_SIZE
#define RX_BUFFER_SIZE                 BUFFER_SIZE

#define  VERSION_ID                    "1.0.0"

#define  FLASH_WRITE_ADDRESS           0x000000
#define  FLASH_READ_ADDRESS            FLASH_WRITE_ADDRESS

/* initialize SPI0 GPIO and parameter */
void spi_flash_init(void);
/* erase the specified flash sector */
void spi_flash_sector_erase(uint32_t sector_addr);
/* erase the entire flash */
void spi_flash_bulk_erase(void);
/* write more than one byte to the flash */
void spi_flash_page_write(uint8_t* pbuffer,uint32_t write_addr,uint16_t num_byte_to_write);
/* write block of data to the flash */
void spi_flash_buffer_write(uint8_t* pbuffer,uint32_t write_addr,uint16_t num_byte_to_write);
/* read a block of data from the flash */
void spi_flash_buffer_read(uint8_t* pbuffer,uint32_t read_addr,uint16_t num_byte_to_read);
/* read flash identification */
uint32_t spi_flash_read_id(void);
/* initiate a read data byte (read) sequence from the flash */
void spi_flash_start_read_sequence(uint32_t read_addr);
/* read a byte from the SPI flash */
uint8_t spi_flash_read_byte(void);
/* send a byte through the SPI interface and return the byte received from the SPI bus */
uint8_t spi_flash_send_byte(uint8_t byte);
/* send a half word through the SPI interface and return the half word received from the SPI bus */
uint16_t spi_flash_send_halfword(uint16_t half_word);
/* enable the write access to the flash */
void spi_flash_write_enable(void);
/* poll the status of the write in progress (wip) flag in the flash's status register */
void spi_flash_wait_for_write_end(void);

void get_chip_serial_num(void);
ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length);
void zyxc_w25q_thread_entry(void *parameter);
#endif /* GD25QXX_H */

(4)在components.c文件中包含头文件#include "zyxc_w25q.h"。

四、配置KEIL软件下载选项

(1)点击“options for target”——Debug——Jlink/J-TRACE cortex(小编这里用到下载器是

GD32 Jlink OB下载器)——settings——选择SW看到右侧有Device Name即下载器找到了对应的GD32F303RCT6芯片。

​​

 (2)选择Flash Download下载模式,这里端子了擦除整片芯片,以及下载程序后自动复位(Reset and run)。

​​

 (3)下载完成后,打开串口助手,即可看到w25q flash芯片读写OK。

如下所示:

 

备注:看到GD32F303RCT6开发板上LED1、LED2、LED3、LED4每隔1S闪烁一次,此功能为额外添加的idle空闲功能,用于提示开发板系统正常工作。

​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式ZYXC

谢爷的赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值