找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3493|回复: 1
收起左侧

W25Q128驱动程序

[复制链接]
ID:130230 发表于 2021-10-28 16:26 | 显示全部楼层 |阅读模式
#define W25Q128_NUM       0xEF4018 /* FALSH型号 */
#define W25CMD_JEDEC_ID      0x9F
#define W25CMD_WERITE_ENABLE 0x06
#define W25CMD_READ_STATUS   0x05 /* 读状态寄存器 用来判断busy */
#define W25CMD_SECTOR_ERASE  0x20
#define W25CMD_PAGE_PROGRAM  0x02

#define W25_PAGE_SIZE        256

static void W25Q128WriteEnable(void);
static u8 WaitW25Idle(void);
static void AlignmentWrite (u8 *buff, u32 addr, u16 len);

/* 读取芯片ID */
u32 W25Q128ReadId(void)
{
    u8 tempH, tempM, tempL;
    SPI2_CSN_SELECT();
    (void)Spi2WriteByte(W25CMD_JEDEC_ID);
    (void)Spi2ReadByte(&tempH);
    (void)Spi2ReadByte(&tempM);
    (void)Spi2ReadByte(&tempL);
    SPI2_CSN_RELASE();
    return (U32)((tempH << 16) | (tempM << 8) | tempL);
}

/* 扇区擦除 */
void W25EraseSector(u32 addr)
{
    W25Q128WriteEnable();
    (void)WaitW25Idle();
    SPI2_CSN_SELECT();
    (void)Spi2WriteByte(W25CMD_SECTOR_ERASE);
    (void)Spi2WriteByte((u8)(addr >> 16));
    (void)Spi2WriteByte((u8)(addr >> 8));
    (void)Spi2WriteByte((u8)addr);
    SPI2_CSN_RELASE();
    (void)WaitW25Idle();
}

/* 按页写入 */
void W25PageWrite( u8 *buff, u32 addr, u16 len)
{
    W25Q128WriteEnable();
    (void)WaitW25Idle();
    SPI2_CSN_SELECT();
    (void)Spi2WriteByte(W25CMD_PAGE_PROGRAM);
    (void)Spi2WriteByte((u8)(addr >> 16));
    (void)Spi2WriteByte((u8)(addr >> 8));
    (void)Spi2WriteByte((u8)addr);
    while(len--)
    {
        (void)Spi2WriteByte(*buff);
        buff++;
    }
    SPI2_CSN_RELASE();
    (void)WaitW25Idle();
}

/* 对齐写入一定长度的数据 */
static void AlignmentWrite (u8 *buff, u32 addr, u16 len)
{
    u8 numOfPage   = len / W25_PAGE_SIZE;
    u8 numOfLeave  = len % W25_PAGE_SIZE;
    if (numOfPage == 0) /* 数据长度不满1页 */
    {
        W25PageWrite(buff, addr, W25_PAGE_SIZE);
        return ;
    }
    while(numOfPage--)
    {
        W25PageWrite(buff, addr, W25_PAGE_SIZE);
        buff += W25_PAGE_SIZE;
        addr += W25_PAGE_SIZE;
    }
    if (numOfLeave == 0)
    {
        return;
    }
    W25PageWrite(buff, addr, numOfLeave);
}

/* 非对齐写入一定长度的数据 */
static void UnAlignmentWrite (u8 *buff, u32 addr, u16 len)
{
    u8 numOfPage   = len / W25_PAGE_SIZE;
    u8 numOfLeave  = len % W25_PAGE_SIZE;
    u8 unAlignmentLen = W25_PAGE_SIZE - (addr % W25_PAGE_SIZE); /* 写完这个长度的数据之后就可以对齐写入了*/

    if (numOfPage == 0)
    {
        if (numOfLeave > unAlignmentLen)
        {
            W25PageWrite(buff, addr, unAlignmentLen);
            buff += unAlignmentLen;
            addr += unAlignmentLen;
            W25PageWrite(buff, addr, numOfLeave - unAlignmentLen);
        }
        else
        {
            W25PageWrite(buff, addr, len);
        }
        return ;
    }
    W25PageWrite(buff, addr, unAlignmentLen); /* 写入不对齐的部分 */
    len -= unAlignmentLen;
    buff += unAlignmentLen;
    addr += unAlignmentLen;
    AlignmentWrite(buff, addr, len);
}

/* 写使能 */
static void W25Q128WriteEnable(void)
{
    SPI2_CSN_SELECT();
    (void)Spi2WriteByte(W25CMD_WERITE_ENABLE);
    SPI2_CSN_RELASE();
}

/*
等待芯片空闲
return : 0失败 1成功
*/
static u8 WaitW25Idle(void)
{
    u8 temp;
    u8 retryCnt = 0;
    SPI2_CSN_SELECT();
    do {
        (void)Spi2WriteByte(W25CMD_READ_STATUS);
        (void)Spi2ReadByte(&temp);
        if (++retryCnt == 250)
        {
            return 0;
        }
    }while(temp & 0x01);
    SPI2_CSN_RELASE();
    return 1;
}


评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:38683 发表于 2023-3-15 10:39 | 显示全部楼层
刚好用到,先谢了!
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表