MM32F3273G8P火龙果开发板MindSDK开发教程18

MM32F3273G8P火龙果开发板MindSDK开发教程18 -sfud库的移植 1、sfud简介

SFUD (Serial Flash Universal Driver) 串行 Flash 通用驱动库 推荐查看官方文档:一款使用 JEDEC SFDP 标准的串行 (SPI) Flash 通用驱动库

2、实验设备

主控:MM32F3273G8P火龙果开发板 spi flash : W25Q32 使用SPI2。(PB12 PB13 PB14 PB15)

3、SPI初始化

在移植sfud之前,我们先初始化spi2,用读取函数,读取一下w25q32的manufacturer_id值,如果能正常读取,说明我们的设备没有问题,spi初始化也正常,然后再来移植sfud库。 初始化gpio的函数如下: CS采用软件控制的方式,读写之前拉低,读写结束拉高。

static bool SPI_GpioConfig(void){ /* gpio. */ GPIO_Init_Type gpio_init; /* PB12 - SPI_CS. */ gpio_init.Pins = GPIO_PIN_12; gpio_init.PinMode = GPIO_PinMode_Out_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_init); GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_15); GPIO_SetBits(GPIOB, gpio_init.Pins); /* PB13 - SPI_SCK. */ gpio_init.Pins = GPIO_PIN_13; gpio_init.PinMode = GPIO_PinMode_AF_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_init); GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_5); /* PB14 - SPI_MISO. */ gpio_init.Pins = GPIO_PIN_14; gpio_init.PinMode = GPIO_PinMode_In_PullUp; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_init); GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_5); /* PB15 - SPI_MOSI. */ gpio_init.Pins = GPIO_PIN_15; gpio_init.PinMode = GPIO_PinMode_AF_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_init); GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_5); return true;}

SPI初始化函数:

bool SPI_Config(void){ SPI_GpioConfig(); /* Setup SPI module. */ SPI_Master_Init_Type spi_init; spi_init.ClockFreqHz = CLOCK_APB1_FREQ; spi_init.BaudRate = 400000u; spi_init.XferMode = SPI_XferMode_TxRx; spi_init.PolPha = SPI_PolPha_Alt1; spi_init.DataWidth = SPI_DataWidth_8b; spi_init.LSB = false; spi_init.AutoCS = true; SPI_InitMaster(SPI2, &spi_init); /* Enable SPI. */ SPI_Enable(SPI2, true); return true;}

注意SPI_PolPha_Alt1其实就是spi mode0,这里的定义怪怪的。

spi时钟初始化:

/* GPIOB. */RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOB, true);RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOB);/* SPI2. */RCC_EnableAPB1Periphs(RCC_APB1_PERIPH_SPI2, true);RCC_ResetAPB1Periphs(RCC_APB1_PERIPH_SPI2);

读取函数:(写入一个读取一个)

static void SPI_WriteReadOnebyte(uint8_t w_data,uint8_t *r_data){ while ( SPI_STATUS_TX_FULL & SPI_GetStatus(SPI2) ) {} SPI_PutData(SPI2, w_data); while (0u == (SPI_STATUS_RX_DONE & SPI_GetStatus(SPI2)) ) {} *r_data = SPI_GetData(SPI2);}void SPI_WriteReadData(uint8_t *w_data,uint8_t *r_data,int len){ GPIO_WriteBit(GPIOB,GPIO_PIN_12,0); while (len) { SPI_WriteReadOnebyte(*w_data++,r_data++); len--; } GPIO_WriteBit(GPIOB,GPIO_PIN_12,1);}

读取 manufacturer_id函数

#define CMD_JEDEC_ID 0x9f#define CMD_MANUFACURER_ID 0x90static void w25q32_read_manufacturer_id(uint16_t *id){ uint8_t tx_data[6] = {CMD_MANUFACURER_ID ,0,0,0,0,0}; uint8_t rx_data[6] = {0}; SPI_WriteReadData(tx_data,rx_data,6);*id = (rx_data[4]spi.user_data = NULL; flash->retry.delay = retry_delay_100us; flash->retry.times = 60u * 10000u; return result;} 5、sfud的使用

调用官方的demo

static void sfud_demo(uint32_t addr, size_t size, uint8_t *data){ sfud_err result = SFUD_SUCCESS; const sfud_flash *flash = sfud_get_device_table() + 0; size_t i; /* prepare write data */ for (i = 0; i < size; i++) { data[i] = i; } /* erase test */ result = sfud_erase(flash, addr, size); if (result == SFUD_SUCCESS) { printf("Erase the %s flash data finish. Start from 0x%08X, size is %ld. ", flash->name, addr, size); } else { printf("Erase the %s flash data failed. ", flash->name); return; } /* write test */ result = sfud_write(flash, addr, size, data); if (result == SFUD_SUCCESS) { printf("Write the %s flash data finish. Start from 0x%08X, size is %ld. ", flash->name, addr, size); } else { printf("Write the %s flash data failed. ", flash->name); return; } /* read test */ result = sfud_read(flash, addr, size, data); if (result == SFUD_SUCCESS) { printf("Read the %s flash data success. Start from 0x%08X, size is %ld. The data is: ", flash->name, addr, size); printf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F "); for (i = 0; i < size; i++) {if (i % 16 == 0){ printf("[%08X] ", addr + i); } printf("%02X ", data[i]); if (((i + 1) % 16 == 0) || i == size - 1) { printf(" "); } } printf(" "); } else { printf("Read the %s flash data failed. ", flash->name); } /* data check */ for (i = 0; i < size; i++) { if (data[i] != i % 256) { printf("Read and check write data has an error. Write the %s flash data failed. ", flash->name); break; } } if (i == size) { printf("The %s flash test is success. ", flash->name); }}

main函数调用:

static uint8_t data [256] = {0};int main(void){BOARD_InitBootClocks(); // ³õʼ»¯Ê±ÖÓBOARD_InitDebugConsole();BOARD_UserKeyInit();LED_Init();BOARD_TIM6_Init();// for mutilbutton initbutton_init(&btn1, read_button_GPIO, 0, btn1_id);button_attach(&btn1, PRESS_DOWN, BTN1_PRESS_DOWN_Handler);button_attach(&btn1, PRESS_UP, BTN1_PRESS_UP_Handler);button_start(&btn1);BOARD_TIM7_Init();BOARD_Delay1Ms(1000);printf("Board Init Success ");sfud_init();sfud_demo(0,256,data);while(1){}} 6、现象

烧录后打印如下:

7、代码

代码下载


比丘资源网 » MM32F3273G8P火龙果开发板MindSDK开发教程18

发表回复

提供最优质的资源集合

立即查看 了解详情