/*************************************
*文件名称:w25x16_spi.c
*
*功能描述:访问和写入数据到闪存w25x16
*
*建立日期:2016-03-16
*
* w25x16
*共8192页*256字节/页=2097152字节
*2097152字节/512个扇区=4096字节/扇区
*
*Block(块)-->Sector(扇区)-->Page(页)-->256(字节)
* 32 512 8192
*************************************/

.H文件的定义

#define W25X16_CS PORTA_OUT(2)   //片选信号

/* w25x16指令 */
#define W25X16_WRITE_ENABLE 0x06
#define W25X16_WRITE_DISABLE 0x04
#define W25X16_READ_DATA 0x03
#define W25X16_READ_QUICK 0x0b
#define W25X16_READ_DOUBLE 0x3b
#define W25X16_READ_STATUS_REG 0x05
#define W25X16_WRITE_STATUS_REG 0x01
#define W25X16_PAGE_PROGRAM 0x02
#define W25X16_SECTOR_ERASE 0x20
#define W25X16_BLOCK_ERASE 0xd8
#define W25X16_CHIP_ERASE 0xc7
#define W25X16_POWER_OFF 0xb9
#define W25X16_POWER_ON 0xab
#define W25X16_DEVICE_ID 0x90
#define W25X16_JEDEC_ID 0x9f
#define W25X16_MANUFACTDEVICE_ID 0x90

.C文件的函数

初始化SPI接口

/*************************************
*文件名称:w25x16_spi.c
*
*功能描述:访问和写入数据到闪存w25x16
*
*建立日期:2016-03-16
*
*FLASH设备名称:w25x16
*共8192页*256字节/页=2097152字节
*2097152字节/512个扇区=4096字节/扇区
*
*Block(块)-->Sector(扇区)-->Page(页)-->256(字节)
* 32 512 8192
*************************************/ mySPI.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256; //分频
mySPI.SPI_CPHA =SPI_CPHA_2Edge; //第2个跳变沿数据被采样
mySPI.SPI_CPOL =SPI_CPOL_High; //空闲状态为高电平
mySPI.SPI_CRCPolynomial =; //CRC值计算
mySPI.SPI_DataSize =SPI_DataSize_8b; //以1个byte为单位
mySPI.SPI_Direction =SPI_Direction_2Lines_FullDuplex; //双线双向全双工
mySPI.SPI_FirstBit =SPI_FirstBit_MSB; //数据传输从MSB位开始
mySPI.SPI_Mode =SPI_Mode_Master; //设置为主SPI模式
mySPI.SPI_NSS =SPI_NSS_Soft; //NSS信号由软件控制 SPI_Init(SPI1,&mySPI);
SPI_Cmd(SPI1, ENABLE); //使能SPI外设

读取FLASH的ID

u16 w25x16_spi_read_id(void)
{
u16 temp=;
W25X16_CS=; w25x16_spi_read_write_byte(W25X16_DEVICE_ID); //发送指令
w25x16_spi_read_write_byte(0x00);
w25x16_spi_read_write_byte(0x00);
w25x16_spi_read_write_byte(0x00);
temp|=w25x16_spi_read_write_byte(0xff)<<; //送0xff,读取数据
temp|=w25x16_spi_read_write_byte(0xff);
W25X16_CS=; return temp;
}

SPI的读写操作

/*读取一个字节的数据
//_data:要写入的数据
//SPI特性:如果要得到一个数据,则取返回值;如果要写入一个数据,则忽略返回的数据.
*/
u8 w25x16_spi_read_write_byte(u8 _data)
{
u8 temp=; //如果发送区是空的,则最多尝试100次就返回错误
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE == RESET))
{
if(temp++>)
return ;
} SPI_I2S_SendData(SPI1,_data);
temp=; //如果接收区是空的,则最多尝试100次就返回错误
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET)
{
if(temp++>)
return ;
} return SPI_I2S_ReceiveData(SPI1);
}

读取FLASH指定位置的数据

/*读取FLASH中指定位置的数据
//_data :数据存储数组
//_readaddr:要开始读取的flash地址,此地址分3次写入,每次写入8位
//_datasize:要读取的数据大小
*/
void w25x16_spi_read(u8* _data,u32 _readaddr,u16 _datasize)
{
u16 i;
W25X16_CS=;
w25x16_spi_read_write_byte(W25X16_READ_DATA); //发送读数据命令,忽略返回的数据
w25x16_spi_read_write_byte((u8)((_readaddr)>>)); //右移16位,但只取低8位,因为有U8的强制转换
w25x16_spi_read_write_byte((u8)((_readaddr)>>)); //右移8位,还是只取低8位,因为有U8的强制转换
w25x16_spi_read_write_byte((u8)((_readaddr))); //将地址的低8位写入s
for(i=;i<_datasize;i++)
{
_data[i]=w25x16_spi_read_write_byte(0xff); //写空数据,得到指定长度的数据
}
W25X16_CS=;
}

等待FLASH忙信号

/*  等待忙信号  */
void w25x16_spi_wait_busy(void)
{
//寄存器第一位如果还是1,则继续等待,直到0为止
while((w25x16_spi_read_sr()&0x01)==0x01); //w25x16_spi_read_sr()&0x01:取结果的第一位数值
}

写入指定位置的数据

/*  写入指定地址的数据  */
//_data :要写入的数据
//_writeaddr:要写入的地址
//_datasize :要写入的数据大小
void w25x16_spi_write_page(u8* _data,u32 _writeaddr,u16 _datasize)
{
u16 i;
W25X16_CS=;
w25x16_spi_write_enable();
w25x16_spi_read_write_byte(W25X16_PAGE_PROGRAM); //发送指令
w25x16_spi_read_write_byte((u8)((_writeaddr)>>));
w25x16_spi_read_write_byte((u8)((_writeaddr)>>));
w25x16_spi_read_write_byte((u8)_writeaddr);
for(i=;i<_datasize;i++)
w25x16_spi_read_write_byte(_data[i]); W25X16_CS=;
w25x16_spi_wait_busy(); //等待完成操作
}
/**************************************
//根据扇区编号写入数据
//_sectorid:删除编号
//一个扇区有16页,每页256字节.一个扇区共16*256=4096字节
//用页编程模式,每次编程256字节,如果要写4096字节,则要连续编程16次
**************************************/
void w25x16_spi_write_by_sectorid(u16 _sectorid,u8* _data,u32 _datasize)
{
u8 i,write_pages_num; //要写入的满页面的数量,一个页面256字节
u32 write_addr=_sectorid*; //要写入的flash首地址 write_pages_num=_datasize/; //要写入的满页面数量 //首先擦除该删除的数据,擦除后数据为0xff
w25x16_spi_erase_sector(_sectorid); //写入满页的数据
for(i=;i<write_pages_num;i++)
{
w25x16_spi_write_page(((u8*)(_data+i*)),write_addr+i*,); //每次写满256个字节,满页的写入数据
} //写入剩余的数据,如果数据小于256,则直接写入
w25x16_spi_write_page(((u8*)(_data + write_pages_num*)),write_addr + write_pages_num*,_datasize - write_pages_num*); }
/*擦除指定的扇区数据
//_sector_id:扇区编号 0~511
*/
void w25x16_spi_erase_sector(u32 _sector_id)
{
u32 sector_addr=_sector_id*;
w25x16_spi_write_enable();
w25x16_spi_wait_busy();
W25X16_CS=;
myspi_read_write_byte(W25X16_SECTOR_ERASE); //送扇区擦除指令
myspi_read_write_byte((u8)((sector_addr)>>)); //右移16位,用u8强制转换,取D23-D16
myspi_read_write_byte((u8)((sector_addr)>>)); //右移8位,用u8强制转换,取D15-D8
myspi_read_write_byte((u8)sector_addr); //用u8强制转换,取D7-D0
W25X16_CS=;
w25x16_spi_wait_busy();
}

访问FLASH设备-W25X16的更多相关文章

  1. 【驱动】Flash设备驱动基础·NOR·NAND

    Flash存储器 ——>Flash存储器是近几年来发展最快的存储设备,通常也称作闪存.Flash属于EEPROM(电可擦除可编程只读存储器),是一类存取速度很高的存储器. ——>它既有RO ...

  2. Ionic2学习笔记(9):访问本地设备

    作者:Grey 原文地址: http://www.cnblogs.com/greyzeng/p/5559927.html               Ionic2提供了访问本地设备的方法,但是需要安装 ...

  3. win10添加打印机--无法访问指定设备,路径或文件。。

    win10添加打印机无法访问指定设备,路径或文件..后来发现很多按钮点击多说无法访问指定设备,路径或文件.. 解决添加打印机问题: 在搜索栏中搜索:print (从这里添加) 彻底解决: 添加环境变量 ...

  4. ubuntu 下root用户无法访问声音设备的解决方案

    原因:root用户没有对pulsaudio的访问权限,而且pulsaudio默认是不能在root下自动启动解决办法: 一.修改自动启动:编辑 gedit /etc/default/pulseaudio ...

  5. Java访问USB设备

    最近在用Java访问RDing设备,使用的是Java HID API.使用过程中发现一个问题,由于是嵌入式小白,不知道如何向USB设备发送report.于是想到可以看看自带的软件如何访问USB的.找到 ...

  6. vs2015使用Apache Cordova用JavaScript来访问本地设备的功能,比如摄像头、加速计

    看到下面这张图就代表着我VS2015 跨平台Moblie开发工具安装成功了. 上周安装成功后本想一睹跨平台开发的乐趣,可是一直找不到合适的入口.这周又来捯饬一下结果发现了一个入口.于是来写一个Hell ...

  7. ubuntu下virtualbox 共享文件夹 & 访问USB设备

    在Ubuntu 12.04 上为Virtualbox 启用USB 设备支持 Ubuntu安装虚拟机,实现文件和USB的共享 Ubuntu下virtualbox 虚拟xp 访问USB设备

  8. 管理员技术(二): 访问练习用虚拟机、 命令行基础技巧 、 挂载并访问光盘设备、ls列表及文档创建、复制删除移动

    一.访问练习用虚拟机 目标: 学会在教学环境中访问练习用虚拟机,主要完成以下事项: 1> 快速重置教学虚拟机环境       2> 通过“虚拟系统管理器”访问虚拟机       3> ...

  9. Linux应用可通过USB访问Android设备-Chrome OS 75版发布

    导读 谷歌已经为支持的Chromebook设备发布了Chrome OS 75操作系统,这是一个主要版本,增加了各种新功能,最新安全补丁和其他改进. 对于大多数Chromebook设备,Chrome O ...

随机推荐

  1. 在linux上搭建本地yum源

    准备yum仓库的光盘镜像IOS文件: 设置光驱加载本地磁盘的yum仓库的光盘镜像文件: 在linux的命令行输入setup命令打开设置窗口,选择"System Service": ...

  2. 转!!URL和URI区别

    URI,URL,URN 从上面的那幅图可以看出来,一共有三个不同的概念URI,URL,URN.这讨论这样的问题时,最好的方法就是回到原点啊,这里我们在RFC 3986: Uniform Resourc ...

  3. IE, FireFox, Opera 浏览器支持CSS实现Alpha半透明的方法

    这个世界变化很快,IE8也快出来了,它将不在支持以前{filter:alpha(opacity=50);}的私有属性,转而支持更规范的私有属性-ms-filter: “progid:DXImageTr ...

  4. 在Linux或者Unix下打开,每一行都会出多出^M这样的字符

    Windows上写好的文件,在Linux或者Unix下打开,每一行都会出多出^M这样的字符,这是因为Windows与*nix的换行符不同所致,我们看看文件格式有什么不同. 在Linux下查看文件格式: ...

  5. SCCM日志存放路径

    sccm有一些比较重要的日志大家可能经常需要查看.下面是一些比较常用的日志文件的存放位置. 客户端日志文件: 日志位于服务器端 SMS_CCM\Logs 文件夹中 日志位于客户端 %Windir%\S ...

  6. 项目二:使用机器学习(SVM)进行基因预测

    SVM软件包 LIBSVM -- A Library for Support Vector Machines(本项目所用到的SVM包)(目前最新版:libsvm-3.21,2016年7月8日) C-S ...

  7. assert的用处

    ASSERT函数是用于调试中,也就是说在你的代码中当是Debug的时候它完成对参数的判断,如果是TRUE则什么都不做,如果是FALSE则弹出一个程序中断对话框提示程序出现错误.在Release版本中它 ...

  8. linux gcc 编译动态类库(.so)和静态类库(.a)

    linux gcc 编译动态类库(.so)和静态类库(.a) 我的编译环境 ubuntu desktop 16.04 一:测试代码 测试有3个文件:AB.h,AB.c,test.c //AB.h vo ...

  9. linux笔记:linux常用命令-网络命令

    网络命令:ping(测试网络连通性) 网络命令:ifconfig(查看和设置网卡信息) 注意:在查看网卡信息时,直接输入ifconfig命令即可. 网络命令:last(列出目前和过去登入系统的用户信息 ...

  10. @ExceptionHandler

    @Controller public class AccessController { /** * 异常页面控制 * * @param runtimeException * @return */ @E ...