本文最后修改时间:2022年01月08日 10:45
一、本节简介
本节以simple_peripheral工程为例,介绍如何使用SPI读写W25Q80(外部flash)。
二、实验平台
1)CC2640R2F平台
①协议栈版本:CC2640R2 SDK v1.40.00.45
②编译软件:CCS7.3.0.00019
③硬件平台:香瓜CC2640R2F开发板
④仿真器:香瓜XDS100V3下载器
2)外设
①板载在香瓜CC2640R2F开发板底板上的芯片:W25Q80
三、版权声明
1)作者:甜甜的大香瓜
2)声明:喝水不忘挖井人,转载请注明出处。
3)纠错/业务合作:897503845@qq.com
4)香瓜BLE之CC2640R2F群:557278427
5)本文出处:原创连载资料《简单粗暴学蓝牙5》
6)完整开源资料下载地址(电脑端打开):
7)香瓜CC2640R2F开发板购买链接:
https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4023-16963296339.8.21bfc58419sWKt&id=558653143169
四、实验前提
1、在进行本文步骤前,请先阅读以下章节:
1)《简单粗暴学蓝牙5》的“第一章至第四章”章节。
2、在进行本文步骤前,请先实现以下章节:
1)《简单粗暴学蓝牙5》的“第三章 软件的安装及使用”章节。
五、基础知识
1、W25Q80是什么?
答: W25Q80是winbond(华邦)公司出的8M bit(也就是1MB)的flash芯片。同系列常用的型号还有W25Q16(16Mb=2MB)、W25Q32(32Mb=4MB)等。
2、W25Q80的基本信息?
答:
如上图,W25Q80一次可写256字节、可4K字节扇区擦除、32K或者64K块擦除、整片擦除。
使用的是SPI接口、2.7V~3.6V电压范围,香瓜购买的是8-pin SOIC 208-mil封装。
如上图,W25Q80的厂商ID是0xEF,设备ID是0x13。这个用于初始化时识别flash芯片用。
六、硬件原理
1、W25Q80芯片引脚图
如上图,W25Q80一共8个脚,其中GND和VCC供电3.3V(范围在2.7V~3.6V)即可,其他4个SPI引脚DO(输出)、DI(输入)、CLK(时钟)、CS(片选)。
WP(写保护)、HOLD(保持输入)这两个引脚本文并没有用到,且“/WP”中的“/”是低电平有效的意思,所以我们本文将WP和HOLD两引脚拉高到VCC即可。
2、W25Q80与香瓜CC2640R2F开发板的对应关系
W25Q80引脚 |
香瓜CC2640R2F开发板引脚 |
引脚1(/CS) |
DIO_30 |
引脚2(DO) |
DIO_8 |
引脚3(/WP) |
置高到VCC |
引脚4(GND) |
GND |
引脚5(DI) |
DIO_9 |
引脚6(CLK) |
DIO_10 |
引脚7(/HOLD) |
置高到VCC |
引脚6(VCC) |
3.3V |
3、硬件原理图
七、实验步骤
1、编写并添加自定义的W25Q80驱动
1)写一个驱动GUA_ExtFlash.c(存放在“……
\simplelink_cc2640r2_sdk_1_40_00_45\examples\rtos\CC2640R2_LAUNCHXL\ble5stack\simple_peripheral\src\app\GUA“路径下)
//********************************************************************** //name: GUA_ExtFlash.c //introduce: 外部flash驱动 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group: 香瓜BLE之CC2640R2F(557278427) //shop: opengua.taobao.com //changetime: 2021.08.02 //********************************************************************** #include “string.h” #include <ti/devices/cc26x0r2/driverlib/Ssi.h> #include <ti/drivers/spi/SPICC26XXDMA.h> #include <ti/drivers/dma/UDMACC26XX.h> #include <ti/drivers/SPI.h> #include “GUA_ExtFlash.h” /*********************宏定义************************/ //SPI引脚 #define GUA_CC2640R2_SPI0_MISO IOID_8 #define GUA_CC2640R2_SPI0_MOSI IOID_9 #define GUA_CC2640R2_SPI0_CLK IOID_10 #define GUA_CC2640R2_SPI0_CSN PIN_UNASSIGNED #define GUA_Spi_flash_CS IOID_30 //SPI片选开关宏 #define GUA_FLASH_CS_ON 0 #define GUA_FLASH_CS_OFF 1 /* Instruction codes */ #define GUA_BLS_CODE_PROGRAM 0x02 /**< Page Program */ #define GUA_BLS_CODE_READ 0x03 /**< Read Data */ #define GUA_BLS_CODE_READ_STATUS 0x05 /**< Read Status Register */ #define GUA_BLS_CODE_WRITE_ENABLE 0x06 /**< Write Enable */ #define GUA_BLS_CODE_SECTOR_ERASE 0x20 /**< Sector Erase */ #define GUA_BLS_CODE_MDID 0x90 /**< Manufacturer Device ID */ #define GUA_BLS_CODE_DP 0xB9 /**< Power down */ #define GUA_BLS_CODE_RDP 0xAB /**< Power standby */ /* Erase instructions */ #define GUA_BLS_CODE_ERASE_4K 0x20 /**< Sector Erase */ #define GUA_BLS_CODE_ERASE_32K 0x52 #define GUA_BLS_CODE_ERASE_64K 0xD8 #define GUA_BLS_CODE_ERASE_ALL 0xC7 /**< Mass Erase */ /* Bitmasks of the status register */ #define GUA_BLS_STATUS_SRWD_BM 0x80 #define GUA_BLS_STATUS_BP_BM 0x0C #define GUA_BLS_STATUS_WEL_BM 0x02 #define GUA_BLS_STATUS_WIP_BM 0x01 #define GUA_BLS_STATUS_BIT_BUSY 0x01 /**< Busy bit of the status register */ /* Part specific constants */ #define GUA_BLS_PROGRAM_PAGE_SIZE 256 #define GUA_BLS_ERASE_SECTOR_SIZE 4096 /* Manufacturer IDs */ #define GUA_MF_MACRONIX 0xC2 #define GUA_MF_WINBOND 0xEF typedef enum GUA_CC2640R2_SPIName { GUA_CC2640R2_SPI0 = 0, GUA_CC2640R2_SPICOUNT } GUA_CC2640R2_SPIName; SPICC26XXDMA_Object GUA_spiCC26XXDMAObjects[GUA_CC2640R2_SPICOUNT]; //SPI速度4M #define GUA_SPI_BIT_RATE 4000000 //flash每页大小4K #define GUA_EXT_FLASH_PAGE_SIZE 4096 /*********************内部变量************************/ const SPICC26XXDMA_HWAttrsV1 GUA_spiCC26XXDMAHWAttrs[GUA_CC2640R2_SPICOUNT] = { { .baseAddr = SSI0_BASE, .intNum = INT_SSI0_COMB, .intPriority = ~0, .swiPriority = 0, .powerMngrId = PowerCC26XX_PERIPH_SSI0, .defaultTxBufValue = 0, .rxChannelBitMask = 1<<UDMA_CHAN_SSI0_RX, .txChannelBitMask = 1<<UDMA_CHAN_SSI0_TX, .mosiPin = GUA_CC2640R2_SPI0_MOSI, .misoPin = GUA_CC2640R2_SPI0_MISO, .clkPin = GUA_CC2640R2_SPI0_CLK, .csnPin = GUA_CC2640R2_SPI0_CSN } }; const SPI_Config GUA_SPI_config[GUA_CC2640R2_SPICOUNT] = { { .fxnTablePtr = &SPICC26XXDMA_fxnTable, .object = &GUA_spiCC26XXDMAObjects[GUA_CC2640R2_SPI0], .hwAttrs = &GUA_spiCC26XXDMAHWAttrs[GUA_CC2640R2_SPI0] }, }; const uint_least8_t GUA_SPI_count = GUA_CC2640R2_SPICOUNT; static PIN_Config GUA_BoardFlashPinTable[] = { GUA_Spi_flash_CS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MIN, /* Ext. flash chip select */ PIN_TERMINATE }; static PIN_Handle GUA_hFlashPin = NULL; static PIN_State GUA_pinState; // Supported flash devices static GUA_ExtFlashInfo_t GUA_flashInfo[] = { { .manfId = GUA_MF_MACRONIX, // Macronics .devId = 0x15, // MX25R1635F .deviceSize = 0x200000 // 2 Mbyte (16 Mbit) }, { .manfId = GUA_MF_MACRONIX, // Macronics .devId = 0x14, // MX25R8035F .deviceSize = 0x100000 // 1 Mbyte (8 Mbit) }, { .manfId = GUA_MF_WINBOND, // WinBond .devId = 0x13, // W25Q80DV .deviceSize = 0x100000 // 1 Mbyte (8 Mbit) }, { .manfId = GUA_MF_WINBOND, // WinBond .devId = 0x12, // W25X40CL .deviceSize = 0x080000 // 512 Kbyte (4 Mbit) }, |