我们要在rtthread studio 开发环境中建立stm32h743xih6芯片的工程。我们使用一块stm32h743及fpga的核心板完成相关实验,核心板如图:
1.建立新工程,选择相应的芯片型号及debug引脚及调试器
2.编译下载,可以看到串口打印正常
3.在工程中打开cubemx,设置串口及时钟,设置内容如上一章节,spi的管脚设置需要参考原理图。
4.打开drv_clk.c更改调试级别后编译下载可以看到打印时钟信息。
5.打开软件包中心,打开spi和sfud框架,如图:
6.保存后,在board.h中打开spi注册,如图:
7.编译下载,发送list device指令查询下设备,如图可以看到有spi设备了
8.在applications文件夹下添加程序,注意,flash片选脚为G10.
这里需要修改为片选引脚
代码如下:
#define SPI_BUS_NAME "spi1"
#define W25Q_SPI_DEVICE_NAME "spi10"
#define W25Q_FLASH_NAME "W25Q512"
//FAL_USING_NOR_FLASH_DEV_NAME
rt_uint8_t wData[4096] = {"SPI bus write data to W25Q512 flash."};
rt_uint8_t rData[4096];
static int rt_hw_spi_flash_init()
{
rt_err_t ree = RT_EOK;
ree = rt_hw_spi_device_attach(SPI_BUS_NAME, W25Q_SPI_DEVICE_NAME, GPIOA, GPIO_PIN_15);
/* 使用 SFUD 探测 spi10 从设备,并将 spi10 连接的 flash 初始化为块设备,名称 W25Q128 */
if (RT_NULL == rt_sfud_flash_probe(FAL_USING_NOR_FLASH_DEV_NAME, W25Q_SPI_DEVICE_NAME))
{
return -RT_ERROR;
}
return ree;
}
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
static void sfud_w25q_sample(void)
{
rt_spi_flash_device_t flash_dev;
sfud_flash_t sfud_dev;
struct rt_device_blk_geometry geometry;
// 1- use sfud api
rt_kprintf("\n 1 - Use SFUD API \n");
sfud_dev = rt_sfud_flash_find_by_dev_name(W25Q_FLASH_NAME);
if(sfud_dev == RT_NULL){
rt_kprintf("sfud can't find %s device.\n", W25Q_FLASH_NAME);
}else{
rt_kprintf("sfud device name: %s, sector_count: %d, bytes_per_sector: %d, block_size: %d.\n",
sfud_dev->name, sfud_dev->chip.capacity / sfud_dev->chip.erase_gran,
sfud_dev->chip.erase_gran, sfud_dev->chip.erase_gran);
if(sfud_erase_write(sfud_dev, 0x002000, sizeof(wData), wData) == SFUD_SUCCESS)
rt_kprintf("sfud api write data to w25q128(address:0x2000) success.\n");
if(sfud_read(sfud_dev, 0x002000, sizeof(rData), rData) == SFUD_SUCCESS)
rt_kprintf("sfud api read data from w25q128(address:0x2000) is:%s\n", rData);
}
// 2- use rt_device api
rt_kprintf("\n 2 - Use rt_device API \n");
flash_dev = (rt_spi_flash_device_t)rt_device_find(W25Q_FLASH_NAME);
if(flash_dev == RT_NULL){
rt_kprintf("rt_device api can't find %s device.\n", W25Q_FLASH_NAME);
}else{
rt_device_open(&flash_dev->flash_device, RT_DEVICE_OFLAG_OPEN);
if(rt_device_control(&flash_dev->flash_device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry) == RT_EOK)
rt_kprintf("spi flash device name: %s, sector_count: %d, bytes_per_sector: %d, block_size: %d.\n",
flash_dev->flash_device.parent.name, geometry.sector_count, geometry.bytes_per_sector, geometry.block_size);
if(rt_device_write(&flash_dev->flash_device, 0x03, wData, 1) > 0)
rt_kprintf("rt_device api write data to w25q128(address:0x3000) success.\n");
if(rt_device_read(&flash_dev->flash_device, 0x03, rData, 1) > 0)
rt_kprintf("rt_device api read data from w25q128(address:0x3000) is:%s\n", rData);
rt_device_close(&flash_dev->flash_device);
}
}
MSH_CMD_EXPORT(sfud_w25q_sample, sfud w25q128 sample);
9.编译下载可以看到打印信息,flash已经被检测到
10.读取下flash数据,可以看到读取成功
可以看到我们就可以通过sfud指令读写flash了。挂载的w25q64可以被正常操作,其余操作指令如下,可以尝试:
sf probe [spi_device] - probe and init SPI flash by given 'spi_device'
sf read addr size - read 'size' bytes starting at 'addr'
sf write addr data1 ... dataN - write some bytes 'data' to flash starting at 'addr'
sf erase addr size - erase 'size' bytes starting at 'addr'
sf status [<volatile> <status>] - read or write '1:volatile|0:non-volatile' 'status'
sf bench - full chip benchmark. DANGER: It will erase full chip!