写一个w25q256的spi驱动程序
时间: 2024-03-08 10:46:51 浏览: 63
W25Qxx驱动,适用于q64、q128、q256等,c语言实现,已验证
以下是一个简单的W25Q256的SPI驱动程序的示例,仅供参考:
```c
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "spi.h"
//W25Q256指令定义
#define W25Q256_CMD_WRITE_ENABLE 0x06
#define W25Q256_CMD_WRITE_DISABLE 0x04
#define W25Q256_CMD_READ_STATUS_REG1 0x05
#define W25Q256_CMD_READ_DATA 0x03
#define W25Q256_CMD_WRITE_DATA 0x02
#define W25Q256_CMD_ERASE_SECTOR 0x20
#define W25Q256_CMD_ERASE_BLOCK 0xD8
#define W25Q256_CMD_ERASE_CHIP 0xC7
#define W25Q256_CMD_POWER_DOWN 0xB9
#define W25Q256_CMD_POWER_UP 0xAB
//W25Q256状态寄存器定义
#define W25Q256_STATUS_BUSY 0x01
#define W25Q256_STATUS_WEL 0x02
/**
* @brief 初始化 SPI 接口
*/
void w25q256_spi_init(void)
{
//初始化 SPI 总线
spi_init();
}
/**
* @brief 写使能
*/
static void w25q256_write_enable(void)
{
uint8_t cmd = W25Q256_CMD_WRITE_ENABLE;
spi_cs_low(); //使能片选
spi_write(&cmd, sizeof(cmd)); //发送指令
spi_cs_high(); //禁用片选
}
/**
* @brief 写禁止
*/
static void w25q256_write_disable(void)
{
uint8_t cmd = W25Q256_CMD_WRITE_DISABLE;
spi_cs_low(); //使能片选
spi_write(&cmd, sizeof(cmd)); //发送指令
spi_cs_high(); //禁用片选
}
/**
* @brief 读取状态寄存器1
* @return 状态寄存器1的值
*/
static uint8_t w25q256_read_status_reg1(void)
{
uint8_t cmd = W25Q256_CMD_READ_STATUS_REG1;
uint8_t status = 0;
spi_cs_low(); //使能片选
spi_write(&cmd, sizeof(cmd)); //发送指令
spi_read(&status, sizeof(status)); //读取寄存器值
spi_cs_high(); //禁用片选
return status;
}
/**
* @brief 等待W25Q256空闲
*/
static void w25q256_wait_busy(void)
{
while (w25q256_read_status_reg1() & W25Q256_STATUS_BUSY); //等待忙标志位清零
}
/**
* @brief 读取数据
* @param addr 读取数据的起始地址
* @param data 存放读取的数据缓冲区
* @param len 读取数据的长度
*/
void w25q256_read_data(uint32_t addr, uint8_t *data, uint32_t len)
{
uint8_t cmd[4];
cmd[0] = W25Q256_CMD_READ_DATA;
cmd[1] = (addr >> 16) & 0xFF;
cmd[2] = (addr >> 8) & 0xFF;
cmd[3] = addr & 0xFF;
spi_cs_low(); //使能片选
spi_write(cmd, sizeof(cmd)); //发送指令
spi_read(data, len); //读取数据
spi_cs_high(); //禁用片选
}
/**
* @brief 写入数据
* @param addr 写入数据的起始地址
* @param data 存放写入的数据缓冲区
* @param len 写入数据的长度
*/
void w25q256_write_data(uint32_t addr, const uint8_t *data, uint32_t len)
{
uint32_t i = 0;
uint8_t cmd[4];
w25q256_write_enable(); //写使能
cmd[0] = W25Q256_CMD_WRITE_DATA;
cmd[1] = (addr >> 16) & 0xFF;
cmd[2] = (addr >> 8) & 0xFF;
cmd[3] = addr & 0xFF;
spi_cs_low(); //使能片选
spi_write(cmd, sizeof(cmd)); //发送指令
spi_write(data, len); //写入数据
spi_cs_high(); //禁用片选
w25q256_wait_busy(); //等待操作完成
w25q256_write_disable(); //写禁止
}
/**
* @brief 擦除扇区
* @param addr 擦除扇区的起始地址
*/
void w25q256_erase_sector(uint32_t addr)
{
uint8_t cmd[4];
w25q256_write_enable(); //写使能
cmd[0] = W25Q256_CMD_ERASE_SECTOR;
cmd[1] = (addr >> 16) & 0xFF;
cmd[2] = (addr >> 8) & 0xFF;
cmd[3] = addr & 0xFF;
spi_cs_low(); //使能片选
spi_write(cmd, sizeof(cmd)); //发送指令
spi_cs_high(); //禁用片选
w25q256_wait_busy(); //等待操作完成
w25q256_write_disable(); //写禁止
}
/**
* @brief 擦除块
* @param addr 擦除块的起始地址
*/
void w25q256_erase_block(uint32_t addr)
{
uint8_t cmd[4];
w25q256_write_enable(); //写使能
cmd[0] = W25Q256_CMD_ERASE_BLOCK;
cmd[1] = (addr >> 16) & 0xFF;
cmd[2] = (addr >> 8) & 0xFF;
cmd[3] = addr & 0xFF;
spi_cs_low(); //使能片选
spi_write(cmd, sizeof(cmd)); //发送指令
spi_cs_high(); //禁用片选
w25q256_wait_busy(); //等待操作完成
w25q256_write_disable(); //写禁止
}
/**
* @brief 擦除整个芯片
*/
void w25q256_erase_chip(void)
{
uint8_t cmd = W25Q256_CMD_ERASE_CHIP;
w25q256_write_enable(); //写使能
spi_cs_low(); //使能片选
spi_write(&cmd, sizeof(cmd)); //发送指令
spi_cs_high(); //禁用片选
w25q256_wait_busy(); //等待操作完成
w25q256_write_disable(); //写禁止
}
/**
* @brief 控制W25Q256进入掉电模式
*/
void w25q256_power_down(void)
{
uint8_t cmd = W25Q256_CMD_POWER_DOWN;
spi_cs_low(); //使能片选
spi_write(&cmd, sizeof(cmd)); //发送指令
spi_cs_high(); //禁用片选
}
/**
* @brief 控制W25Q256退出掉电模式
*/
void w25q256_power_up(void)
{
uint8_t cmd = W25Q256_CMD_POWER_UP;
spi_cs_low(); //使能片选
spi_write(&cmd, sizeof(cmd)); //发送指令
spi_cs_high(); //禁用片选
//W25Q256需要一定时间从掉电模式恢复,需要等待
delay_ms(10);
}
```
由于不同的硬件平台和SPI接口实现有所不同,上述代码仅供参考。在使用时,请根据实际情况进行相应的修改。
阅读全文