?? memory.c
字號:
/****************************************************************
* ATMEL的DATAFLASH操作函數庫(FOR AT45DB161D) *
* *
* 作者:gxlujd(彩虹) *
* 最后修改時間:2007年2月18日(大年初一) *
* *
* 感謝www.ouravr.com、阿莫和壇子里的哥們一直以來的熱心幫助 *
* *
* 如果這些資源能幫到你,請保留以上這些信息,同時也請你把自 *
* 己的一些日常積累拿出來分享,這個世界需要更多的無私開源, *
* 別讓金錢和利益蒙住了內心的真誠,謝謝! *
*****************************************************************/
#include <avr/io.h>
#include <util/delay.h>
#include "memory.h"
unsigned char DF_buffer[528];
//往SPI口寫一個字節的數據
void write_SPI(unsigned char data)
{
SPDR = data;
while (!(SPSR & 0x80));
}
//格式化主存儲器(以扇區<0A,0B,1……15>為單位刪除所有頁數據)
void DF_format(void)
{
unsigned char i;
DF_SPI_ON;
DF_wait_busy();
DF_SELECT_1;
write_SPI(SECTOR_ERASE);
write_SPI(0x00);
write_SPI(0x00);
write_SPI(0x00);
DF_DESELECT_1;
DF_wait_busy();
DF_SELECT_1;
write_SPI(SECTOR_ERASE);
write_SPI(0x00);
write_SPI(0x20);
write_SPI(0x00);
DF_DESELECT_1;
for (i=1;i<16;i++)
{
DF_wait_busy();
DF_SELECT_1;
write_SPI(SECTOR_ERASE);
write_SPI(i << 2);
write_SPI(0x00);
write_SPI(0x00);
DF_DESELECT_1;
}
DF_SPI_OFF;
}
//擦除指定的主存儲器頁(地址范圍0-4095)
void DF_page_earse(unsigned int page)
{
DF_SPI_ON;
DF_wait_busy();
DF_SELECT_1;
write_SPI(PAGE_ERASE);
write_SPI((unsigned char)(page >> 6));
write_SPI((unsigned char)(page << 2));
write_SPI(0x00);
DF_DESELECT_1;
DF_SPI_OFF;
}
//將保存在數組DF_buffer[]中的一頁數據寫入第二緩沖區后送入主存儲區
//(先擦除后寫入模式,頁地址范圍0-4095)
void DF_write_page(unsigned int page)
{
unsigned int i;
DF_SPI_ON;
DF_wait_busy();
DF_SELECT_1;
write_SPI(BUFFER_2_WRITE);
write_SPI(0x00);
write_SPI(0x00);
write_SPI(0x00);
for (i=0;i<528;i++)
write_SPI(DF_buffer[i]);
DF_DESELECT_1;
if (page<4096)
{
DF_SELECT_1;
write_SPI(B2_TO_MM_PAGE_PROG_WITH_ERASE);
write_SPI((unsigned char)(page>>6));
write_SPI((unsigned char)(page<<2));
write_SPI(0x00);
DF_DESELECT_1;
DF_wait_busy();
}
DF_SPI_OFF;
}
//將指定主存儲器頁的數據轉入第一緩沖區后讀出,保存在DF_buffer[]數組中
//(頁地址范圍0-4095)
void DF_read_page(unsigned int page)
{
unsigned int i;
DF_SPI_ON;
while(!(DF_STA_PORT & (1<< DF_STATE)));
DF_SELECT_1;
write_SPI(MM_PAGE_TO_B1_XFER);
write_SPI((unsigned char)(page >> 6));
write_SPI((unsigned char)(page << 2));
write_SPI(0x00);
DF_DESELECT_1;
DF_wait_busy();
DF_SELECT_1;
write_SPI(BUFFER_1_READ);
write_SPI(0x00);
write_SPI(0x00);
write_SPI(0x00);
write_SPI(0x00);
for (i=0;i<528;i++)
{
write_SPI(0xFF);
DF_buffer[i] = SPDR;
}
DF_DESELECT_1;
DF_SPI_OFF;
}
//以直接讀取方式讀取指定的主存儲器頁數據(頁地址范圍0-4095)
//void DF_MM_read_page(unsigned int page)
{
unsigned int i;
DF_SPI_ON;
while(!(DF_STA_PORT & (1<< DF_STATE)));
DF_SELECT_1;
write_SPI(MAIN_MEMORY_PAGE_READ);
write_SPI((unsigned char)(page >> 6));
write_SPI((unsigned char)(page << 2));
write_SPI(0x00);
write_SPI(0x00);
write_SPI(0x00);
write_SPI(0x00);
write_SPI(0x00);
for (i=0;i<528;i++)
{
write_SPI(0x00);
DF_buffer[i] = SPDR;
}
DF_DESELECT_1;
DF_SPI_OFF;
}
//讀取狀態寄存器
// bit7 bit6 bit6 bit6 bit6 bit6 bit6 bit6
//RDY/BUSY COMP 1 0 1 1 PROTECT PAGE SIZE
unsigned char DF_read_reg(void)
{
unsigned char temp;
DF_SPI_ON;
DF_SELECT_1;
write_SPI(READ_STATE_REGISTER);
write_SPI(0x00);
write_SPI(0x00);
write_SPI(0x00);
write_SPI(0x00);
temp=SPDR;
DF_DESELECT_1;
DF_SPI_OFF;
return temp;
}
//檢查狀態寄存器最高位是否為忙,并等待空閑
void DF_wait_busy(void)
{
unsigned char state_reg=0x00;
DF_SELECT_1;
write_SPI(READ_STATE_REGISTER);
write_SPI(0x00);
write_SPI(0x00);
write_SPI(0x00);
while((state_reg&0x80) == 0)
{
write_SPI(0x00);
state_reg = SPDR ;
}
DF_DESELECT_1;
}
//將指定主存儲器頁的數據轉入指定緩沖區
void DF_mm_to_buf(unsigned char buffer,unsigned int page)
{
DF_SPI_ON;
DF_wait_busy();
DF_SELECT_1;
if (buffer==1)
write_SPI(MM_PAGE_TO_B1_XFER);
else
write_SPI(MM_PAGE_TO_B2_XFER);
write_SPI((unsigned char)(page >> 6));
write_SPI((unsigned char)(page << 2));
write_SPI(0x00);
DF_DESELECT_1;
DF_SPI_OFF;
}
//讀取指定緩沖區指定單元的數據,保存在DF_buffer[]數組中
unsigned char DF_read_buf(unsigned char buffer,unsigned int start_address,unsigned int length)
{
unsigned int i;
if ((527-start_address)>=length)
{
DF_SPI_ON;
DF_wait_busy();
DF_SELECT_1;
if (buffer==1)
write_SPI(BUFFER_1_READ);
else
write_SPI(BUFFER_2_READ);
write_SPI(0x00);
write_SPI((unsigned char)(start_address >> 8));
write_SPI((unsigned char)start_address);
write_SPI(0x00);
for (i=0;i<length;i++)
{
write_SPI(0xFF);
DF_buffer[i] = SPDR;
}
DF_DESELECT_1;
DF_SPI_OFF;
return 1;
}
else
return 0;
}
//將DF_buffer[]數組中指定長度的數據寫入指定緩沖區
unsigned char DF_write_buf(unsigned char buffer,unsigned int start_address,unsigned int length)
{
unsigned int i;
if ((527-start_address)>=length)
{
DF_SPI_ON;
DF_wait_busy();
DF_SELECT_1;
if (buffer==1)
write_SPI(BUFFER_1_WRITE);
else
write_SPI(BUFFER_2_WRITE);
write_SPI(0x00);
write_SPI((unsigned char)(start_address >> 8));
write_SPI((unsigned char)start_address);
for (i=0;i<length;i++)
write_SPI(DF_buffer[i]);
DF_DESELECT_1;
return 1;
}
else
return 0;
}
//將指定緩沖區中的數據寫入主存儲區的指定頁
void DF_buf_to_mm(unsigned char buffer,unsigned int page)
{
DF_SPI_ON;
DF_wait_busy();
if (page<4096)
{
DF_SELECT_1;
if (buffer==1)
write_SPI(B1_TO_MM_PAGE_PROG_WITH_ERASE);
else
write_SPI(B2_TO_MM_PAGE_PROG_WITH_ERASE);
write_SPI((unsigned char)(page>>6));
write_SPI((unsigned char)(page<<2));
write_SPI(0x00);
DF_DESELECT_1;
}
DF_SPI_OFF;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -