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

📄 at45db041d._c

📁 用ATMEGA16的硬件SPI驱动AT45DB041D
💻 _C
📖 第 1 页 / 共 2 页
字号:

  for(i=0;i<4;i++)//write
  {
    SPI_Write_Byte(Read_Sector_Lockdown_Register[i]);
  }
  for(i=0;i<8;i++)//read
  {
    Sector_Lockdown_Register[i] = SPI_Read_Byte(0);
  }
  Disable_DFLASH();
}
/************************************************************
*写数据到缓冲器(Buffer1或Buffer2)(缓冲器大小为264 bytes)
*BufferX   :选择缓冲器(Buffer1或Buffer2)
*BFA       :Buffer内存地址 0~263
*wData     :要写入的数据
*wDataSize :要写入的数据长度(1~264)
************************************************************/
void DF_Write_to_Buffer(unsigned char BufferX,unsigned int BFA,
                        unsigned char *wData,unsigned int wDataSize)
{
  unsigned int i;

  DF_Check_Busy_State();            //check busy bit

  Enable_DFLASH();

  if(BufferX == Buffer1)  SPI_Write_Byte(Write_Data_to_Buffer1);//0x84
  else                    SPI_Write_Byte(Write_Data_to_Buffer2);//0x87

  //Page Size (264 Bytes)
  //15 don't care bits + 9 addrress
  SPI_Write_Byte(0xFF);                      //8 can't care bits
  SPI_Write_Byte((unsigned char)(BFA>>8));   //7 can't care bits + 1 bit address
  SPI_Write_Byte((unsigned char)BFA);        //address

  for(i=0;i<wDataSize;i++)  SPI_Write_Byte(wData[i]);//写入数据

  Disable_DFLASH();
}
/************************************************************
*读取缓冲器(Buffer1或Buffer2)(缓冲器大小为264 bytes)中的数据
*BufferX   :选择缓冲器(Buffer1或Buffer2)
*BFA       :Buffer内存地址 0~263
*wData     :存放读到的数据
*wDataSize :要写入的数据长度(1~264)
*注意:高速和低速发的操作码和要发送的数据长度不同
************************************************************/
void DF_Read_from_Buffer(unsigned char BufferX,unsigned int BFA,
                         unsigned char *rData,unsigned int rDataLen)
{
  unsigned int i;

  DF_Check_Busy_State();            //check busy bit

  Enable_DFLASH();

  if(BufferX == Buffer1)  SPI_Write_Byte(Read_Data_from_Buffer1);//0xD4 or 0xD1(lower frequency)
  else                    SPI_Write_Byte(Read_Data_from_Buffer2);//0xD6 or 0xD3(lower frequency)

  //Page Size (264 Bytes)
  //15 don't care bits + 9 addrress
  SPI_Write_Byte(0xFF);                      //8 can't care bits
  SPI_Write_Byte((unsigned char)(BFA>>8));   //7 can't care bits
  SPI_Write_Byte((unsigned char)BFA);        //address
  SPI_Write_Byte(0xFF);       				 //1 can't care byte (lower frequency 不用这个字节)

  for(i=0;i<rDataLen;i++)  rData[i] = SPI_Read_Byte(0xFF);//读取数据

  Disable_DFLASH();
}
/************************************************************
*把缓冲器(Buffer1或Buffer2)中的数据写到内存的页中(写整页)
*先擦除再写数据(硬件支持的带擦除写)
*BufferX   :选择缓冲器(Buffer1或Buffer2)
*PA        :内存中页的地址 0~2047
************************************************************/
void DF_Write_Buffer_to_Page(unsigned char BufferX,unsigned int PA)
{
  DF_Check_Busy_State();

  Enable_DFLASH();

  if(BufferX == Buffer1)  SPI_Write_Byte(Write_Buffer1_to_Page_whin_Erase);//0x83
  else                    SPI_Write_Byte(Write_Buffer2_to_Page_whin_Erase);//0x86

  //Page Size (264 Bytes)
  //4 don't care bits + 11 address + 9 don't care bits
  SPI_Write_Byte((unsigned char)(PA>>7));
  SPI_Write_Byte((unsigned char)(PA<<1));
  SPI_Write_Byte(0xFF);                         //8 don't care bits

  Disable_DFLASH();
}
/************************************************************
*读取内存的页(整页)的数据到缓冲器(Buffer1或Buffer2)中
*BufferX   :选择缓冲器(Buffer1或Buffer2)
*PA        :内存中页的地址 0~2047
************************************************************/
void DF_Read_Buffer_from_Page(unsigned char BufferX,unsigned int PA)
{
  DF_Check_Busy_State();

  Enable_DFLASH();

  if(BufferX == Buffer1)  SPI_Write_Byte(Read_Page_to_Buffer1);//0x53
  else                    SPI_Write_Byte(Read_Page_to_Buffer2);//0x55

  //Page Size (264 Bytes)
  //4 don't care bits + 11 address + 9 don't care bits
  SPI_Write_Byte((unsigned char)(PA>>7));
  SPI_Write_Byte((unsigned char)(PA<<1));
  SPI_Write_Byte(0xFF); //8 don't care bits

  Disable_DFLASH();
}
/************************************************************
*将数据写到内存中(自动先写到BUFFER1 OR BURRER2中再将数据写到内存中)
*BufferX   :选择自动先写入的缓冲器(Buffer1或Buffer2)
*PA        :内存中的页地址0~2047
*BA        :从页中的这个地址开始写数据,会自动转到下一页(0~263)
*当写到最后一页的最后一个地址时,会自动转到第一页开始写
*wData     :要写入的数据
*DataLen   :要写入的数据长度
************************************************************/
void Main_Memory_Page_Program_Through_Buffer(unsigned char BufferX,
                                             unsigned int PA,unsigned char BA,
	 						                 unsigned char *wData,unsigned int DataLen)
{
  unsigned char i;
  DF_Check_Busy_State();
  Enable_DFLASH();

  if(BufferX == Buffer1)  SPI_Write_Byte(Main_Memory_Page_Program_Through_Buffer1);//0x82
  else                    SPI_Write_Byte(Main_Memory_Page_Program_Through_Buffer2);//0x85

  //4 bits(don't care bits) + 11 bits(page address)+9(address in the page)
  SPI_Write_Byte((unsigned char)(PA>>7));
  SPI_Write_Byte((unsigned char)((PA<<1)|(BA>>8)));
  SPI_Write_Byte((unsigned char)BA);

  for(i=0;i<DataLen;i++)	SPI_Write_Byte(wData[i]);

  Disable_DFLASH();
}
/************************************************************
*从内存中读取数据到数组rData中(直接读取数据不经过BUFFER1 OR BURRER2)
*PA        :内存中的页地址0~2047
*BA        :从页中的这个地址开始读数据,会自动转到下一页(0~263)
*当读到最后一页的最后一个地址时,会自动转到第一页开始读取
*rData     :存放读到的数据
*DataLen   :要读取的数据长度
*与DF_Continuous_Array_Read一样的功能但与Buffer有关,但不改变Buffer中的数据
************************************************************/
void DF_Main_Memory_Page_Read(unsigned int PA,unsigned char BA,
	 						  unsigned char *rData,unsigned int DataLen)
{
  unsigned char i;
  DF_Check_Busy_State();

  Enable_DFLASH();

  SPI_Write_Byte(Main_Memory_Page_Read_Command);//0xD2

  //4 bits(don't care bits) + 11 bits(page address)+9(address in the page)
  SPI_Write_Byte((unsigned char)(PA>>7));
  SPI_Write_Byte((unsigned char)((PA<<1)|(BA>>8)));
  SPI_Write_Byte((unsigned char)BA);
  //4 don’t care bytes
  for(i=0;i<4;i++)	SPI_Write_Byte(0xFF);

  for(i=0;i<DataLen;i++)  rData[i] = SPI_Read_Byte(0xFF);//读取数据

  Disable_DFLASH();
}
/************************************************************
*从内存中读取数据到数组rData中(直接读取数据不经过BUFFER1 OR BURRER2)
*PA        :内存中的页地址0~2047
*BA        :从页中的这个地址开始读数据,会自动转到下一页(0~263)
*当读到最后一页的最后一个地址时,会自动转到第一页开始读取
*rData     :存放读到的数据
*DataLen   :要读取的数据长度
*与DF_Main_Memory_Page_Read一样的功能但与Buffer无关
************************************************************/
void DF_Continuous_Array_Read(unsigned int PA,unsigned char BA,
	 						  unsigned char *rData,unsigned int DataLen)
{
  unsigned char i;
  DF_Check_Busy_State();

  Enable_DFLASH();

  SPI_Write_Byte(Continuous_Array_Read_Command);//0xE8

  //4 bits(don't care bits) + 11 bits(page address)+9(address in the page)
  SPI_Write_Byte((unsigned char)(PA>>7));
  SPI_Write_Byte((unsigned char)((PA<<1)|(BA>>8)));
  SPI_Write_Byte((unsigned char)BA);
  //4 don’t care bytes
  for(i=0;i<4;i++)	SPI_Write_Byte(0xFF);

  for(i=0;i<DataLen;i++)  rData[i] = SPI_Read_Byte(0xFF);//读取数据

  Disable_DFLASH();
}
/************************************************************
*擦除FLASH全部内容
*not affect sectors that are protected or locked down
************************************************************/
void DF_Chip_Erase(void)
{
  unsigned char Chip_Erase_Command[4]={0xC7,0x94,0x80,0x9A};//整片擦除操作码
  unsigned char i;

  DF_Check_Busy_State();
  Enable_DFLASH();

  for(i=0;i<4;i++)
  {
     SPI_Write_Byte(Chip_Erase_Command[i]);
  }

  Disable_DFLASH();
}
/************************************************************
*DataFlash初始化(其实是初始化驱动FLASH用到的SPI)
************************************************************/
void DataFlash_Init(void)
{
  SPI_Init();
}
/************************************************************
*FLASH复位
************************************************************/
void DF_Reset(void)
{
  SPI_PORT&=~(1<<RESET);	//使能复位
  DF_Delay(100);
  SPI_PORT|=(1<<RESET);     //禁止复位
  DF_Delay(100);
}
/************************************************************
*Test DataFlash
************************************************************/
//Test_Flash_Buffer_to_Buffer
void Test_Flash_Buffer_to_Buffer(void)
{
  unsigned char i;
  unsigned char TestWriteBuffer[10]={1,2,3,4,5,6,7,8,9,10};
  unsigned char TestReadBuffer[10] ={0,0,0,0,0,0,0,0,0,0};

  //写数据到Buffer中
  DF_Write_to_Buffer(Buffer1,0,TestWriteBuffer,10);
  //DF_Delay(10);
  //从Buffer中读取数据
  DF_Read_from_Buffer(Buffer1,0,TestReadBuffer,10);
  //DF_Delay(10);
  
  for(i=0;i<10;i++)//把要写入的和读出的数据写入EEPROM用于比较
  {
    eeprom_write_byte((i+16*0),TestWriteBuffer[i]);
	eeprom_write_byte((i+16*1),TestReadBuffer[i]);
  }
}

//Test_Flash_Page_to_Page
void Test_Flash_Page_to_Page(void)
{
  unsigned char i;
  unsigned char TestWriteBuffer[10]={10,9,8,7,6,5,4,3,2,1};
  unsigned char TestReadBuffer[10] ={0,0,0,0,0,0,0,0,0,0};
  //将数据写到内存中(自动先写到BUFFER1 OR BURRER2中再将数据写到内存中)
  Main_Memory_Page_Program_Through_Buffer(Buffer1,0,0,TestWriteBuffer,10);
  //DF_Delay(10);
  //从内存中读取数据到数组rData中(直接读取数据不经过BUFFER1 OR BURRER2)
  DF_Main_Memory_Page_Read(0,0,TestReadBuffer,10);
  //DF_Delay(10);
  
  for(i=0;i<10;i++)//把要写入的和读出的数据写入EEPROM用于比较
  {
    eeprom_write_byte((i+16*2),TestWriteBuffer[i]);
	eeprom_write_byte((i+16*3),TestReadBuffer[i]);
  }
}

//Test_Flash_Buffer_Page_to_Page
void Test_Flash_Buffer_Page_to_Page(void)
{
  unsigned char i;
  unsigned char TestWriteBuffer[10]={1,2,3,4,5,6,7,8,9,10};
  unsigned char TestReadBuffer[10] ={0,0,0,0,0,0,0,0,0,0};
  //写数据到Buffer中
  DF_Write_to_Buffer(Buffer1,0,TestWriteBuffer,10);
  //DF_Delay(10);
  //将Buffer中的数据写到DataFlash中
  DF_Write_Buffer_to_Page(Buffer1,0);
  //DF_Delay(10);
  
  //读出DataFlash中的数据
  //DF_Main_Memory_Page_Read(0,0,TestReadBuffer,10);
  DF_Continuous_Array_Read(0,0,TestReadBuffer,10);
  //DF_Delay(10);
  for(i=0;i<10;i++)//把要写入的和读出的数据写入EEPROM用于比较
  {
    eeprom_write_byte((i+16*4),TestWriteBuffer[i]);
	eeprom_write_byte((i+16*5),TestReadBuffer[i]);
  }
}

//Test_Flash_Buffer_Page_to_Page_Buffer
void Test_Flash_Buffer_Page_to_Page_Buffer(void)
{
  unsigned char i;
  unsigned char TestWriteBuffer[10]={10,9,8,7,6,5,4,3,2,1};
  unsigned char TestReadBuffer[10] ={0,0,0,0,0,0,0,0,0,0};

  //写数据到Buffer中
  DF_Write_to_Buffer(Buffer1,0,TestWriteBuffer,10);
  //DF_Delay(10);
  //将Buffer中的数据写到Page中
  DF_Write_Buffer_to_Page(Buffer1,0);
  //DF_Delay(10);
  //从Page中读取数据到Buffer中
  DF_Read_Buffer_from_Page(Buffer1,0);
  //DF_Delay(10);
  //从Buffer中读取数据
  DF_Read_from_Buffer(Buffer1,0,TestReadBuffer,10);
  //DF_Delay(10);
  
  for(i=0;i<10;i++)//把要写入的和读出的数据写入EEPROM用于比较
  {
    eeprom_write_byte((i+16*6),TestWriteBuffer[i]);
	eeprom_write_byte((i+16*7),TestReadBuffer[i]);
  }
}
/************************************************************
*主函数
************************************************************/
void main(void)
{
  unsigned int i;
  unsigned char Temp_Sector_Lockdown_Register[8];
  DF_Delay(1000);
  DDRA =0XFF;
  PORTA=0X01;  //指示灯起始状态

  //FLASH初始化(SPI初始化)
  DataFlash_Init();
  //wait for a moment
  DF_Delay(100);
  //Flash复位
  DF_Reset();

  //读取FLASH内部状态寄存器
  //PORTA=DF_Read_status_Register();

  //读取扇区加锁寄存器
  //DF_Read_Sector_Lockdown_Register(Temp_Sector_Lockdown_Register);
  //for(i=0;i<8;i++)
  //{
  //  eeprom_write_byte(i,Temp_Sector_Lockdown_Register[i]);
  //}

  //取消所有扇区保护
  //if(DF_Cancel_Sector_Protection()) PORTA=0X18;//OK

  //测试FLASH产家ID  读到为0x1F才算正常
  //if(Test_Manufacturer_ID()) PORTA=0x1F;

  //使FLASH进入Deep_Power_Down
  //DF_Deep_Power_Down();

  //使FLASH退出Deep_Power_Down
  //DF_Resume_from_Deep_Power_Down();

  //擦除FLASH全部内容
  //DF_Chip_Erase();

  //测试FLASH读写
  Test_Flash_Buffer_to_Buffer();			//ok
  Test_Flash_Page_to_Page();				//ok
  Test_Flash_Buffer_Page_to_Page();			//ok
  Test_Flash_Buffer_Page_to_Page_Buffer();	//ok
  
  PORTA=0X80;  //程序执行完成状态
  while(1)
  {
    asm("sei");
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -