⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at45db321.c

📁 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 + -