📄 at45db321.c
字号:
#include <Mega32.h>
#include "type.h"
#include "45DB321.h"
#include <Delay.h>
unsigned char data[300];
#define WP PORTB.1 //均为高为动.
#define RESET PORTB.0
#define CS PORTB.3 //输出
#define SI PORTB.5 //输出
#define SO PINB.6 //输入,无内部上拉
#define SCK PORTB.7 //输出
//中断方式
static void SPI_Init(void)
{
unsigned char temp=0;
DDRB=0xBB;//MISO输入
PORTB.3=1;
PORTB.0=1; ///RESET商
PORTB.1=1; ///WP商.
SPCR=0Xdf; //SPI充许,主模式,高字节在前,工作模式3,fck/128
temp=SPSR;
temp=SPDR;
SPSR=0;
#asm("sei");//开全局中断.
//中断开0XDF
}
#define FlagSendTrue 1
#define FlagRecTrue 2
unsigned char SPIState=0;//无数据要发送
unsigned char FlashState;//flash忙状态。
unsigned char RecIndex=0;//接收数据计数
unsigned char SendIndex=0;//发送数据个数
unsigned char RecNum=0;
unsigned char SendNum=0;
unsigned char CData[20];//要发的命令
unsigned char CNum=0; //要发送命令数
unsigned char CIndex=0; //
unsigned char *SendPtr;//要发送的数据指针
unsigned char *RecPtr;//要接收的数据指针.
unsigned char Comand=1;
interrupt [SPI_STC] void SPI_Isr(void)
{
//发送完毕进入中断服务函数
#asm("cli");
switch(SPIState)
{
case FlagRecTrue:
if(Comand==1)
{
SendIndex++;
if(SendIndex<CNum)
{
SPDR=CData[SendIndex];//发送下一下命令.
}
else
{
CNum=0; //命令个数清0
SendIndex=0; //计数清0
RecIndex=0;
Comand=0;
}
}
else
{
if((CNum==0)&&(RecIndex<RecNum))
{
RecPtr[RecIndex]=SPDR;
RecIndex++;
}
else
{
SPIState=0;
SendIndex=0;
SendNum=0;
CS=1;
}
}
break;
case FlagSendTrue:
if(Comand==1)
{
CIndex++;
if(CIndex<CNum)
{
SPDR=CData[CIndex];//发送下一下命令.
}
else
{
CNum=0; //命令个数清0
CIndex=0;
Comand=0;
}
}
else
{
if((CNum==0)&&(SendIndex<SendNum))
{
SendPtr[SendIndex]=SPDR;//接收数据
SPDR=0X00;//启动时钟接收下一个。
}
else
{
SPIState=0; //无要发送数据.
RecIndex=0;
RecNum=0;
CS=1;
}
}
break;
case 0x03:
SPDR=CData[1];
CIndex++;
if(CIndex==1)
{
FlashState=SPDR;
CIndex=0;
}
default:
break;
}
#asm("sei");
}
static void AT45_MemoryRead(unsigned int page,unsigned int address,unsigned int num,unsigned char * string)
{
unsigned char temp=0;
CData[0]=0xd2; //发送命令
CData[1]=(uchar)(page>>6); //最高字节地址
temp = (((uchar)page)<<2);
temp = temp|((address>>8)&0x03);
CData[2]=temp; //第2个字节地址
CData[3]=(uchar)address; //第3个字节地址
CData[4]=0x00; //4字节无关位
CData[5]=0x00;
CData[6]=0x00;
CData[7]=0x00;
CNum=8;
RecNum=num; //要接收的个数
RecPtr=string; //把接收数据放入地址.
SPIState=FlagRecTrue; //置接收状态
Comand=1;
CS=0;
SPDR=CData[0]; //启动接收.
CS=1;
IsBusy();
}
static void AT45_MemoryPageWrite(unsigned char buffer_choice,unsigned int page,unsigned int address,unsigned int num,unsigned char *string)
{
unsigned char temp;
if(buffer_choice==1)
{
CData[0]=0x85; //发送命令
}
else
{
CData[0]=0x82; //发送命令
}
CData[1]=(uchar)(page>>6); //最高字节地址
temp = (((uchar)page)<<2);
temp = temp|((address>>8)&0x03);
CData[2]=temp; //第2个字节地址
CData[3]=(uchar)address; //第3个字节地址
CNum=4;
SendIndex=0; //要发送的序号
SendNum=num; //要
SPIState=FlagSendTrue; //置发送标置.
Comand=1;
SendPtr=string;
CS=0;
SPDR=CData[0]; //启动
CS=1;
IsBusy();
}
//擦除一块,连续的8页。
void AT45_EraseBlock(uint block)//Block(0~1023)
{
CData[0]=0x50;
CData[1]=(uchar)(block>>6);
CData[2]=(((uchar)block)<<2);
CData[3]=BYTE_DUMMY;
CS=0;
SPDR=CData[0];
CS=1;
IsBusy();
}
//擦除一页
void AT45_ErasePage(uint page) //page(0~8191)
{
CData[0]=0x81;
CData[0]=(uchar)(page>>6);
CData[0]=(((uchar)page)<<2);
CData[0]=0x00;
CS=0;
SPDR=CData[0];
CS=1;
IsBusy();
}
//复位存储器
static void DataFlashReset(void) //复位存储器
{
RESET=0;
delay_us(15);
RESET=1;
}
static void ReadFlashState(void)
{
CData[0]=0xd7;
CData[1]=0x00;
SPIState=0x03;
CS=0;
SPDR=CData[0]; //启动
CS=1;
}
static void IsBusy(void)
{
ReadFlashState();
while(( FlashState & 0x80 )==0 )
{
delay_ms(1);
ReadFlashState();
}
}
//=================================================================================
void main(void)
{
unsigned char i=0;
PORTA=0Xff;
DDRA=0XFF;
PORTC=0Xff; //采集器
DDRC=0xff; //
PORTD=0xff; //01111010
DDRD=0xff; //01111010
SPI_Init();
//复位
DataFlashReset();
for(i=0;i<100;i++)
{
data[i]=i;
}
AT45_MemoryPageWrite(0,1,0,100,data);
for(i=0;i<100;i++)
{
data[i]=0;
}
AT45_MemoryRead(1,0,100,data);
delay_ms(10);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -