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

📄 memory.c

📁 at45db161d的C源程序
💻 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 + -