📄 flash.c
字号:
#include "Flash.h"
#ifdef _USE_ONCHIP_FLASH
/*
*************************************************************************************
* 片上FLASH操作
*************************************************************************************
*描述: 擦除片上FLASH的一段
*说明: 擦除一段
*************************************************************************************
*/
void FlashEraseBlock(int address)
{
char *Ptr = (char*)(address&0xFF00);
_DINT();
FCTL2 = FWKEY+FSSEL0+FN0; //设为主时钟,4分频状态
FCTL3 = FWKEY; // LOCK=1,复位锁定标志
//等待忙标志复位
while (FCTL3&1) _NOP();
FCTL1 = FWKEY+ERASE; //设置片擦除状态
*Ptr = 0; //启动擦除操作
while (FCTL3&1) _NOP(); //等待擦除完毕
FCTL1 = FWKEY;
_EINT();
}
void FlashWriteBlock(int dest, int source, int len)
{
int i;
char *DPtr = (char*)dest;
char *SPtr = (char*)source;
FlashEraseBlock(dest);
FCTL1 = FWKEY + WRT;
for (i=0;i<len;i++)
{
*DPtr++ = *SPtr++;
}
FCTL1 = FWKEY;
}
#endif
#ifdef _USE_SERIAL_FLASH
void Init_Spi()
{
P3DIR |= (BIT0+BIT1+BIT3); //定义p3.0 为片选信号,初始为高
P3DIR &= ~BIT2; // SPI
P3OUT |=BIT0;
}
/***********************************************************
对SPI接口存储器的操做
***********************************************************/
//写字节
void spi_bytewrite(uchar data)
{
uchar i;
for(i=0; i<8; i++)
{
if(data & BIT7)
{SPIMO_1;_NOP();}
else
{SPIMO_0; _NOP();}
SPICLK_1;
_NOP();
_NOP();
SPICLK_0;
data <<= 1;
}
}
//读字节
uchar spi_byteread(void)
{
uchar abyte=0,i;
for (i=0; i<8; i++)
{
abyte <<= 1;
if (SPIDATA_IN) abyte += 1;
SPICLK_1;
_NOP();
_NOP();
SPICLK_0;
}
return abyte;
}
//写flash写使能锁存器
void spi_wren(void)
{
SPI_EN;
spi_bytewrite(WREN);
SPI_DIS;
}
//读flash状态寄存器
uchar spi_rdsr(void)
{
uchar tempdata;
SPI_EN;
spi_bytewrite(RDSR);
tempdata = spi_byteread();
SPI_DIS;
return tempdata;
}
//spi数据写操作
void Spi_Write(ulong addr,uchar data)
{
uchar st;
spi_wren(); //写使能
SPI_EN;
spi_bytewrite(PROGRAM);
spi_bytewrite(addr >> 16); //写高字节地址
spi_bytewrite(addr >> 8); //写中字节地址
spi_bytewrite(addr); //写低字节地址
spi_bytewrite(data); //写数据
SPI_DIS;
do
{
st = spi_rdsr();
}while(st & BIT0); //判别写操作是否完成?
}
//spi数据写操作
void Spi_Write_Int(ulong addr,uint data)
{
uchar st;
spi_wren(); //写使能
SPI_EN;
spi_bytewrite(PROGRAM);
spi_bytewrite(addr >> 16); //写高字节地址
spi_bytewrite(addr >> 8); //写中字节地址
spi_bytewrite(addr); //写低字节地址
spi_bytewrite(data); //写数据
spi_bytewrite(data>>8); //写数据
SPI_DIS;
do
{
st = spi_rdsr();
}while(st & BIT0); //判别写操作是否完成?
}
//做一个FLASH的基地址
//做一个FLASH的首地址
void Spi_Write_Blk(ulong addr,uint len, uchar *data)
{
uint idx;
for (idx=0;idx<len;idx++)
{
Spi_Write(addr+idx,*(data+idx));
}
}
//spi数据读操作
uchar Spi_Read(ulong addr)
{
uchar data;
SPI_EN;
spi_bytewrite(READ);
spi_bytewrite(addr>>16); //写高字节地址
spi_bytewrite(addr >> 8); //写中字节地址
spi_bytewrite(addr); //写低字节地址
data = spi_byteread(); //读数据
SPI_DIS;
return data;
}
//spi数据读操作
uint Spi_Read_Int(ulong addr)
{
uint data;
SPI_EN;
spi_bytewrite(READ);
spi_bytewrite(addr>>16); //写高字节地址
spi_bytewrite(addr >> 8); //写中字节地址
spi_bytewrite(addr); //写低字节地址
data = spi_byteread(); //读数据
data += spi_byteread()<<8; //读数据
SPI_DIS;
return data;
}
void Spi_Read_Blk(ulong addr,uint len, uchar *data)
{
uint idx;
for (idx=0;idx<len;idx++)
{
*(data+idx) = Spi_Read(addr+idx);
}
}
//flash整片擦除
void Spi_Chip_Erase(void)
{
uchar temp;
temp =SR & GIE;//保存中断状态
SR &= ~GIE; //关闭中断,
spi_wren();
SPI_EN;
spi_bytewrite(CERASE); //启动片擦除
SPI_DIS;
SR |= temp; //如果中断开着的打开闭着的仍然闭着
Delay(20);
do
{
temp = spi_rdsr();
}
while(temp & BIT0); //判别擦除是否完成
}
//flash块擦除
void Spi_Sector_Erase(ulong addr)
{
uchar temp;
temp =SR & GIE;//保存中断状态
SR &= ~GIE; //关闭中断,
spi_wren();
SPI_EN;
spi_bytewrite(SERASE); //写入块擦除指令
spi_bytewrite(addr >> 16); //启动擦除
spi_bytewrite(addr >> 8);
spi_bytewrite(addr);
SPI_DIS;
SR |= temp; //如果中断开着的打开闭着的仍然闭着
Delay(20);
do
{
temp = spi_rdsr();
}while((temp & BIT0) != 0); //判别擦除是否完成
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -