访问FLASH设备-W25X16
/*************************************
*文件名称: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的更多相关文章
- 【驱动】Flash设备驱动基础·NOR·NAND
Flash存储器 ——>Flash存储器是近几年来发展最快的存储设备,通常也称作闪存.Flash属于EEPROM(电可擦除可编程只读存储器),是一类存取速度很高的存储器. ——>它既有RO ...
- Ionic2学习笔记(9):访问本地设备
作者:Grey 原文地址: http://www.cnblogs.com/greyzeng/p/5559927.html Ionic2提供了访问本地设备的方法,但是需要安装 ...
- win10添加打印机--无法访问指定设备,路径或文件。。
win10添加打印机无法访问指定设备,路径或文件..后来发现很多按钮点击多说无法访问指定设备,路径或文件.. 解决添加打印机问题: 在搜索栏中搜索:print (从这里添加) 彻底解决: 添加环境变量 ...
- ubuntu 下root用户无法访问声音设备的解决方案
原因:root用户没有对pulsaudio的访问权限,而且pulsaudio默认是不能在root下自动启动解决办法: 一.修改自动启动:编辑 gedit /etc/default/pulseaudio ...
- Java访问USB设备
最近在用Java访问RDing设备,使用的是Java HID API.使用过程中发现一个问题,由于是嵌入式小白,不知道如何向USB设备发送report.于是想到可以看看自带的软件如何访问USB的.找到 ...
- vs2015使用Apache Cordova用JavaScript来访问本地设备的功能,比如摄像头、加速计
看到下面这张图就代表着我VS2015 跨平台Moblie开发工具安装成功了. 上周安装成功后本想一睹跨平台开发的乐趣,可是一直找不到合适的入口.这周又来捯饬一下结果发现了一个入口.于是来写一个Hell ...
- ubuntu下virtualbox 共享文件夹 & 访问USB设备
在Ubuntu 12.04 上为Virtualbox 启用USB 设备支持 Ubuntu安装虚拟机,实现文件和USB的共享 Ubuntu下virtualbox 虚拟xp 访问USB设备
- 管理员技术(二): 访问练习用虚拟机、 命令行基础技巧 、 挂载并访问光盘设备、ls列表及文档创建、复制删除移动
一.访问练习用虚拟机 目标: 学会在教学环境中访问练习用虚拟机,主要完成以下事项: 1> 快速重置教学虚拟机环境 2> 通过“虚拟系统管理器”访问虚拟机 3> ...
- Linux应用可通过USB访问Android设备-Chrome OS 75版发布
导读 谷歌已经为支持的Chromebook设备发布了Chrome OS 75操作系统,这是一个主要版本,增加了各种新功能,最新安全补丁和其他改进. 对于大多数Chromebook设备,Chrome O ...
随机推荐
- JavaScript 同名方法的处理
在JS中,如果存在同名同参的方法,它会先调用哪一个?先看两个例子: 例1: <html> <head> <title></title> <scri ...
- gevent中如何实现长轮询
浏览网页时,浏览器会传HTTP 请求到服务器,服务器会根据请求将网页的内容传给浏览器,但是在很多的情况下,使用者会需要看到最新的即时性资讯,例如观看股票市场行情,而在以前只能靠着重新载入网页才能获得最 ...
- OpenCV图像处理中常用函数汇总(1)
//俗话说:好记性不如烂笔头 //用到opencv 中的函数时往往会一时记不起这个函数的具体参数怎么设置,故在此将常用函数做一汇总: Mat srcImage = imread("C:/Us ...
- python 练习 30
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 如果你以前没有接触过面向对象的编程语言,那你 ...
- WebService是什么
Webservice的一个最基本的目的就是提供在各个不同平台的不同应用系统的协同工作能力. 其实WebService并不是什么神秘的东西,它就是一个可以远程调用的类,或者说是组件. 为什么要使用Web ...
- VirtualBox – Error In supR3HardenedWinReSpawn 问题解决办法
转:http://chenpeng.info/html/3510---------VirtualBox – Error In supR3HardenedWinReSpawn---------<h ...
- jquery json 操作(转)
原文:http://www.vososo.com/?p=919 Jquery-json 是 jQuery 的一个插件,可轻松实现对象和 JSON 字符串之间的转换.可序列化 JavaScript 对象 ...
- 用JavaScript操作Media Queries
在响应式(或自适应)设计中要用到Media Queries这个CSS属性,但在某些时候我们需要对Media Queries进行动态操作,这时候可以使用Javascript. 如以下Media Quer ...
- cl.exe
http://blog.csdn.net/happyanger6/article/details/7589016
- [整]C#获得程序路径
// 获取程序的基目录.System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径.System.Diagnostics.Process.Get ...