📄 at45db041.c
字号:
#define FLASH_GLOBAL
#include "includes.h"
/*********************************************************************************************************
FLASH器件采用的是大容量闪烁存储器AT45D041,它采用串行方式传送数据,时钟频率可高达20MHz, 并采用单5V电源供电。
AT45D041内部由主存储器阵列、两个SRAM数据缓冲区BUFFER1、BUFFER2以及I/0接口组成。
其中主存储器阵列容量为4M Bits,由2048页组成,每页264字节
********************************************************************************************************/
/*********************************************************************************************************
FLASH_CS GPF2
FLASH_SO GPG3 //ARM的输入口
FLASH_SCK GPF3
FLASH_SI GPG0
FLASH_RST GPF4
FLASH_WP GPG2
********************************************************************************************************/
//要重新定义
#define SetFLASH_CS() SetBit(rPDATF,2)
#define ClrFLASH_CS() ClrBit(rPDATF,2)
#define SetFLASH_SO() SetBit(rPDATG,3)
#define ClrFLASH_SO() ClrBit(rPDATG,3)
#define SetFLASH_SCK() SetBit(rPDATF,3)
#define ClrFLASH_SCK() ClrBit(rPDATF,3)
#define SetFLASH_SI() SetBit(rPDATG,0)
#define ClrFLASH_SI() ClrBit(rPDATG,0)
#define SetFLASH_RST() SetBit(rPDATF,4)
#define ClrFLASH_RST() ClrBit(rPDATF,4)
#define SetFLASH_WP() SetBit(rPDATG,2)
#define ClrFLASH_WP() ClrBit(rPDATG,2)
#define TstFLASH_SO() TstBit(rPDATG,3)
//
static void WriteFlash(uint8 dat);
static uint8 ReadFlash(void);
static void WriteBuffer1ToMainMemo(uint16 page);
static void WaitBusy(void);
static void WriteMainMemoToBuffer1(uint16 page);
static void WriteBuffer1(uint16 addr, uint8 num, uint8 *dat);
static void PageWriteMainMemo(uint16 page,uint16 p_addr,uint8 num,uint8 *dat);
static void Write24BitAddr(uint32 b_addr);
static void WriteFlashAddr(uint32 addr);
static uint8 TestFlash(void);
void FlashResumeFactorySet(void);
void UserSetInit(void);
//
/*
void Delay(uint16 dly)
{
while(dly --);
}
*/
/*********************************************************************************************************
** 函数名称: FlashInit
** 功能描述: Flash初始化,对新FALSH作检查及I/O口输入输出的配置
** 输 入: 无
** 输 出: 无
** 说 明:
********************************************************************************************************/
void FlashInit(void)
{
rPCONF = rPCONF & (~(0x3f << 4)) | (0x15 << 4); //F2,F3,F4 输出
rPCONG = rPCONG & (~(0x3)); //G0 ,输入
rPCONG = rPCONG & (~(0x0f << 4)) | (0x05 << 4); //G2,G3 输出
RstFlash();
if(TestFlash() == NEW_FLASH)
{
FlashResumeFactorySet();
}
UserSetInit(); //加载flash中的数据
}
void RstFlash(void)
{
SetFLASH_CS();
SetFLASH_SO();
SetFLASH_SI();
ClrFLASH_RST();
Delay(1000); //Delay(1000)
SetFLASH_RST();
ClrFLASH_SCK();
SetFLASH_WP();
Delay(1000); //Delay(1000)
}
/*********************************************************************************************************
********************************************************************************************************/
uint8 const Pearmain[] = {'p','e','a','r','m','a','i','n'};
uint8 const FactorySet[] = {0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x01,
0x01,0x01,0x01,0x00,0x01,0x01,0x00,0x01,
0x00,0x00,0x02,0x00,0x01,0x01,0x01,0x00,
0x00};
/* 偏移量 20
0 数字变倍允许,默认关闭
....
*/
static uint8 TestFlash(void)
{
uint8 i;
uint8 buf[8];
ReadMainMemo(0,8,buf); //读前8位判断是否是新FLASH
for(i=0;i<8;i++)
{
if(Pearmain[i] != buf[i])
{
break; //不匹配,新FLASH
}
}
if( i < 8)
{
return NEW_FLASH;
}
else
{
return NOT_NEW_FLASH;
}
}
void FlashResumeFactorySet(void)
{
// WriteMainMemo(0,8,(uint8 *)Pearmain);
// WriteMainMemo(20,25,(uint8 *)FactorySet);
}
void UserSetInit(void) //加载flash中的数据
{
}
/*********************************************************************************************************
** 函数名称: ReadMainMemo
** 功能描述: 连续从主储存器中读出num个数据
** 输 入: addr: 主储存器地址
** num: 数据个数,最大255个字节
** dat: 数据缓存区首地址
** 输 出:
**
*******************************************************************************************************/
void ReadMainMemo(uint32 addr, uint8 num, uint8 *dat)
{
uint8 i;
if (num == 0) return;
WaitBusy();
ClrFLASH_CS();
WriteFlash(0xE8); //写命令
WriteFlashAddr(addr);
for (i = 0; i < 4; i++) { //32位无效码
WriteFlash(0);
}
for (i = 0; i < num; i++) {
*(dat+i) = ReadFlash();
}
SetFLASH_CS();
}
/*********************************************************************************************************
** 函数名称: WriteMainMemo
** 功能描述: 连续从主储存器中写入num个数据
** 输 入: addr: 主储存器地址
** num: 数据个数,最大255个字节
** dat: 数据缓存区首地址
** 输 出:
**
*******************************************************************************************************/
void WriteMainMemo(uint32 addr, uint8 num ,uint8 *dat)
{
uint16 page,p_addr;
uint8 n;
// SetFLASH_WP();
if (num == 0) {
// ClrFLASH_WP();
return;
}
p_addr = addr % 264; //9位,页内字节
page = addr / 264; //片内页数
//判断是否要分页
if ((p_addr + num) > 264) {
n = 264 - p_addr;
PageWriteMainMemo(page,p_addr,n,dat);
num = num + p_addr - 264;
PageWriteMainMemo(page+1,0,num,dat+n);
}
else {
PageWriteMainMemo(page,p_addr,num,dat);
}
// ClrFLASH_WP();
}
//
/*
功能 :檫除块内数据,1块为8页
入口参数:block 指定块,0~255块,共2048页
出口参数:无
void EraseBlock(uint8 block) {
uint32 b_addr;
WaitBusy();
ClrFLASH_CS();
Delay(5);
WriteFlash(0x50); //写命令
b_addr = (uint32)(block)<<12;
Write24BitAddr(b_addr);
SetFLASH_CS();
}
*/
/*********************************************************************************************************
** 函数名称: PageWriteMainMemo
** 功能描述: 页内连续写入num个数据,不支持分页操作
** 输 入: page: 主储存器页数
** p_addr: 页内地址
** num: 数据个数,最大255个字节
** dat: 数据缓存区首地址
** 输 出:
**
********************************************************************************************************/
static void PageWriteMainMemo(uint16 page,uint16 p_addr,uint8 num,uint8 *dat)
{
if (num == 0) return;
if ((p_addr + num) > 264) num = 264 - p_addr;
WaitBusy();
ClrFLASH_CS();
WriteMainMemoToBuffer1(page);
WaitBusy();
WriteBuffer1(p_addr, num, dat);
WriteBuffer1ToMainMemo(page);
SetFLASH_CS();
}
//
static uint8 ReadFlash(void)
{
uint8 i,dat;
dat = 0;
for (i = 0; i < 8; i++) {
dat <<= 1;
SetFLASH_SCK();
if (TstFLASH_SO()) {
dat |= 1;
}
ClrFLASH_SCK();
}
ClrFLASH_SO();
return dat;
}
static void WriteFlash(uint8 dat)
{
uint8 i;
ClrFLASH_SI();
for (i = 0; i < 8; i++) {
if (dat >= 0x80) {
SetFLASH_SI(); //FLASH_SI = (bit)(dat & 0x80);
}
else {
ClrFLASH_SI();
}
dat <<= 1;
SetFLASH_SCK();
ClrFLASH_SCK();
}
ClrFLASH_SI(); //使FLASH_SI处于确定的状态。
}
//写buffer1
static void WriteBuffer1(uint16 addr, uint8 num, uint8 *dat)
{
uint8 i;
ClrFLASH_CS();
WriteFlash(0x84); //写命令
Write24BitAddr(addr); //与合成的24位地址一致
for (i = 0; i < num; i++) {
WriteFlash(*(dat+i));
}
SetFLASH_CS();
}
/*
static void ReadBuffer1(uint16 addr,uint8 num,uint8 *dat) {
uint8 i;
ClrFLASH_CS();
Delay(5);
WriteFlash(0xD4); //写命令
Write24BitAddr(addr); //与合成的24位地址一致
WriteFlash(0);
for (i = 0; i < num; i++) {
*(dat+i) = ReadFlash();
}
SetFLASH_CS();
}
*/
static void WriteBuffer1ToMainMemo(uint16 page)
{
uint32 b_addr;
ClrFLASH_CS();
WriteFlash(0x83); //写命令
b_addr = (uint32)(page)<<9;
Write24BitAddr(b_addr);
SetFLASH_CS();
}
static void WaitBusy(void)
{
uint8 dat;
ClrFLASH_CS();
WriteFlash(0xD7); //写命令
do {
dat = ReadFlash();
}while(dat < 0x80);
SetFLASH_CS();
}
static void WriteMainMemoToBuffer1(uint16 page) {
uint32 b_addr;
ClrFLASH_CS();
WriteFlash(0x53); //写命令
b_addr = (uint32)(page)<<9;
Write24BitAddr(b_addr);
SetFLASH_CS();
}
static void Write24BitAddr(uint32 b_addr)
{
uint8 dat[3],i;
for (i = 0; i < 3; i++) {
dat[i] = b_addr & 0xff;
b_addr >>= 8;
}
for (i = 0; i < 3; i++) {
WriteFlash(dat[2-i]);
}
}
static void WriteFlashAddr(uint32 addr)
{
uint32 m;
uint16 k;
k = addr % 264; //9位,页内字节
m = addr / 264; //片内页数
m = k + (m << 9); //合成24位地址
Write24BitAddr(m);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -