标题:
C语言源代码W25M02驱动使用
[打印本页]
作者:
panfeng881112
时间:
2021-6-9 11:32
标题:
C语言源代码W25M02驱动使用
本案例使用的是新唐M451的SPI1驱动W25M02的.
//W25 IC复位
void SpiFlash_Rest(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
//有些地方使用了 16 24 32 位模式 所以这里会重新设置一遍
SPI_SET_DATA_WIDTH(SPI1, 8);//设置SPI为8位模式
au32SourceData = 0xFF;//复位指令
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//选择模具 IChange == 0 或 1
void SpiFlash_IC_Change(u8 IChange)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);//设置SPI为8位模式
//选择模具指令 选择W25M02GV内的两片W25N01GV中的其中一片 然后进行操作
au32SourceData = 0xC2;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = IChange;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//读取IC ID值 一共24位
unsigned int SpiFlash_ReadMidDid(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x9F;//读取ID指令 9F 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
//如果不想更改SPI设置 也可以拆成3个8位来操作
SPI_SET_DATA_WIDTH(SPI1, 24);//设置SPI为24位模式
I2S_CLR_RX_FIFO(SPI1);//清除SPI缓存
// 接收
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
//导出SPI缓存数据
au32DestinationData = SPI_READ_RX(SPI1);
return (au32DestinationData & 0xffffff);
}
//写寄存器1
void SpiFlash_WriteStatusReg1(u8 SRData)
{ unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x01;//写寄存器1指令: 01 A0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xA0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = SRData;;//写寄存器1:数据
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//写状态寄存器2
void SpiFlash_WriteStatusReg2(u8 SRData)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x01;//写寄存器2指令: 01 B0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xB0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = SRData;//写寄存器2:数据
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//读寄存器1
unsigned int SpiFlash_ReadStatusReg1(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x05;//读寄存器1指令: 05 A0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xA0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);
au32SourceData = 0X0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);//导致寄存器1数据
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
return (au32DestinationData & 0xFF);
}
//读寄存器2
unsigned int SpiFlash_ReadStatusReg2(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1); SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x05;//读寄存器2指令: 05 B0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xB0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);
au32SourceData = 0X0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
return (au32DestinationData & 0xFF);
}
//读寄存器3
unsigned int SpiFlash_ReadStatusReg3(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x05;//读寄存器2指令: 05 C0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xC0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);
au32SourceData = 0X0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
return (au32DestinationData & 0xFF);
}
//等待ic空闲
void SpiFlash_WaitReady(void)
{
unsigned int ReturnValue;
do
{ ReturnValue = SpiFlash_ReadStatusReg3();
ReturnValue = ReturnValue & 1;
}while(ReturnValue != 0);
}
//判断是否正在写入IC
void SpiFlash_WaitWEL_1(void)
{
unsigned int ReturnValue;
do
{ ReturnValue = SpiFlash_ReadStatusReg3();
ReturnValue = ReturnValue | 0XFD;
}while(ReturnValue != 0XFF);
}
//擦除一块数据 64页 :64*2048=128k 字节
void SpiFlash_PageErase(u32 StartAddress)
{ unsigned int au32SourceData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x06;//写启用指令 06
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等闲
SpiFlash_WaitWEL_1();
SPI_SET_SS_LOW(SPI1);
au32SourceData = 0xD8;//擦除块 指令 D8 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
//改块64页中任意一页地址
au32SourceData=ADDR_Row_PA15_PA0(StartAddress);
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等闲
}
//擦除功能函数
void SpiFlash_ChipErase(u32 StartAddress)
{
SpiFlash_PageErase(StartAddress);
W25M_STR3=SpiFlash_ReadStatusReg3();//判断是否成功
if(W25M_STR3 & 0x04)//擦除失败
{
//printf("\r\nErase_Error\r\n");
SpiFlash_PageErase(StartAddress);
}
SpiFlash_WaitReady();
}
//写入数据功能函数
//StartAddress1 12~27位: 页地址
//StartAddress1 0~11位:页内数据位置
//ByteCount字节个数
void SpiFlash_WriteData(u8 *DataBuffer, u32 StartAddress1, unsigned int ByteCount)
{
u32 au32SourceData;
unsigned int Counter;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x06;//写启用指令 06
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等闲
SpiFlash_WaitWEL_1();
SPI_SET_SS_LOW(SPI1);
au32SourceData = 0x02;//数据写入IC缓冲区指令 02
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16); au32SourceData=StartAddress1;
au32SourceData = (u16)(au32SourceData&0x7ff);//页内位置
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 8);
for(Counter = 0; Counter < ByteCount; Counter++)//数据写入IC换冲执行过程
{
au32SourceData = DataBuffer[Counter];
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
}
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等闲
SPI_SET_SS_LOW(SPI1);
au32SourceData = 0x10;//换冲导入存储区指令 10 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
au32SourceData=StartAddress1;
au32SourceData = (u16)(au32SourceData>>12);//页地址
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等闲
W25M_STR3=SpiFlash_ReadStatusReg3();//判断是否成功
if(W25M_STR3 & 0x08)//写入失败
{
//printf("\r\nWrite_Error\r\n");
}
SpiFlash_WaitReady();
}
//一页数据导出到IC缓冲区
void SpiFlash_LoadData(u32 StartAddress1)
{
u32 au32SourceData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x13;//页数据读取到缓存指令 13 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
au32SourceData=(u16)(StartAddress1>>12);//页地址
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);
sys_delayms(2);
SpiFlash_WaitReady();//等闲
}
//读出数据功能函数
//StartAddress1 12~27位: 页地址
//StartAddress1 0~11位:页内数据位置
//ByteCount字节个数void SpiFlash_ReadData(u8 *DataBuffer, u32 StartAddress1, unsigned int ByteCount)
{
u32 au32SourceData;
unsigned int au32DestinationData;
unsigned int Counter;
SpiFlash_LoadData(StartAddress1);
W25M_STR3=SpiFlash_ReadStatusReg3();//判断是否成功
if(W25M_STR3 & 0x20)//读取失败
{
//printf("\r\nRead_Load_Error\r\n");
SpiFlash_LoadData(StartAddress1);
W25M_STR3=SpiFlash_ReadStatusReg3();//判断是否成功
if(W25M_STR3 & 0x20)//读取失败
{
//UART1_PUTS(":读取失败\r\n");
}
}
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x03;//读取IC缓冲区数据指令 03
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
au32SourceData=StartAddress1;
au32SourceData = (u16)(au32SourceData&0x7ff);//页内位置
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);//清空SPI缓冲区 准备接收IC缓冲区数据
for(Counter = 0; Counter < ByteCount; Counter++)
{
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);
DataBuffer[Counter] = (u8) au32DestinationData;
}
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();
}
//以下是工程函数的案例
#defineW25PAGE(n)( 4096 * n )
//0 <= n < { 1024(块)*64(页)}
//注意:擦除操作时是擦除整块 SpiFlash_ChipErase(W25PAGE(n))
//拿第一块为例:n=0或n=63都是擦除第一块64个页的存储区
//参数写0并保存
void W25M_write_0(void)
{
u16 i=0;
for(i=0;i<2048;i++)
{W25M_temp[i]=0;}
SpiFlash_ChipErase(W25PAGE(0));SpiFlash_WriteData(W25M_temp, W25PAGE(0),2048);
}
//保存工程参数
void W25M_write_GongChen(void)
{
SpiFlash_ChipErase(W25PAGE(0));
SpiFlash_WriteData(W25M_temp, W25PAGE(0),500);
}
//读取工程参数
void W25M_read_GongChen(void)
{
SpiFlash_ReadData(W25M_temp,W25PAGE(0),500);
}
复制代码
作者:
bobo21
时间:
2023-7-26 10:47
学习中,感谢
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1