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

📄 at45db041d.c

📁 脱机ISP编程器
💻 C
字号:
/*------------------------------------------------------
Function:	AT45DB041D Driver for AVR
Author:		1.gxlujd
			2.avenbbs
Version:	1.161
Date:		2008-9-21
--------------------------------------------------------*/
/*--------------------------------------------------------------
ATMEL的DATAFLASH操作函数库(FOR AT45DB161D)
作者:gxlujd(彩虹)
最后修改时间:2007年2月18日(大年初一)
感谢www.ouravr.com、阿莫和坛子里的哥们一直以来的热心帮助
--------------------------------------------------------------*/


#include <avr/io.h>
#include <util/delay.h>
//#include <avr/interrupt.h>
#include "AT45DB041D.h"
#include "spi_soft.h"

#define SPI_DF_EN() PORTD&=~(1<<PD2)
#define SPI_DF_DIS() PORTD|=(1<<PD2)

#define DF_BUFFER_SIZE 256

#define BUFFER_1_WRITE 0x84					// 写入第一缓冲区
#define BUFFER_2_WRITE 0x87					// 写入第二缓冲区
#define BUFFER_1_READ 0xD4					// 读取第一缓冲区
#define BUFFER_2_READ 0xD6					// 读取第二缓冲区
#define B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83	// 将第一缓冲区的数据写入主存储器(擦除模式)
#define B2_TO_MM_PAGE_PROG_WITH_ERASE 0x86	// 将第二缓冲区的数据写入主存储器(擦除模式)
#define MM_PAGE_TO_B1_XFER 0x53				// 将主存储器的指定页数据加载到第一缓冲区
#define MM_PAGE_TO_B2_XFER 0x55				// 将主存储器的指定页数据加载到第二缓冲区
#define PAGE_ERASE 0x81						// 页删除(每页256/264字节)
#define SECTOR_ERASE 0x7C					// 扇区擦除(每扇区128K字节)
#define READ_STATE_REGISTER 0xD7			// 读取状态寄存器

extern unsigned char buf[];
#define DF_buffer buf


//格式化主存储器(以扇区<0A,0B,1……15>为单位删除所有页数据)
void DF_format(void)
{
	unsigned char i;
	//DF_SPI_ON;
	
	DF_wait_busy();
	SPI_DF_EN();
	spiSWTransmit(SECTOR_ERASE);
	spiSWTransmit(0x00);
	spiSWTransmit(0x00);
	spiSWTransmit(0x00);
	SPI_DF_DIS();
	
	DF_wait_busy();
	SPI_DF_EN();
	spiSWTransmit(SECTOR_ERASE);
	spiSWTransmit(0x00);
	spiSWTransmit(0x10);
	spiSWTransmit(0x00);
	SPI_DF_DIS();
	
	for (i=1;i<8;i++)
	{
		DF_wait_busy();
		SPI_DF_EN();
		spiSWTransmit(SECTOR_ERASE);
		spiSWTransmit(i << 1);
		spiSWTransmit(0x00);
		spiSWTransmit(0x00);
		SPI_DF_DIS();
	}
	
	//DF_SPI_OFF;
}


//擦除指定的主存储器页(地址范围0-2047)
void DF_page_earse(unsigned int page)
{
	//DF_SPI_ON;
	DF_wait_busy();
	
	SPI_DF_EN();
	spiSWTransmit(PAGE_ERASE);
	spiSWTransmit((unsigned char)(page >> 7));
	spiSWTransmit((unsigned char)(page << 1));
	spiSWTransmit(0x00);
	SPI_DF_DIS();
	//DF_SPI_OFF;
}


//将保存在数组DF_buffer[]中的一页数据写入第二缓冲区后送入主存储区
//(先擦除后写入模式,页地址范围0-2047)
void DF_write_page(unsigned int page)
{
	unsigned int i;
	//DF_SPI_ON;
	
	DF_wait_busy();
	SPI_DF_EN();
	spiSWTransmit(BUFFER_2_WRITE);
	spiSWTransmit(0x00);
	spiSWTransmit(0x00);
	spiSWTransmit(0x00);
	
	for (i=0;i<DF_BUFFER_SIZE;i++)
	{
		unsigned char tmp;
		tmp=DF_buffer[i];
		spiSWTransmit(tmp);
	}
	
	SPI_DF_DIS();
	
	if (page<2048)
	{
		SPI_DF_EN();
		spiSWTransmit(B2_TO_MM_PAGE_PROG_WITH_ERASE);
		spiSWTransmit((unsigned char)(page>>7));
		spiSWTransmit((unsigned char)(page<<1));
		spiSWTransmit(0x00);
		SPI_DF_DIS();
		DF_wait_busy();
	}
	
	//DF_SPI_OFF;
}


//将指定主存储器页的数据转入第一缓冲区后读出,保存在DF_buffer[]数组中
//(页地址范围0-2047)
unsigned char DF_read_page(unsigned int page,unsigned char check)
{
	unsigned int i;
	//DF_SPI_ON;
	//_delay_ms(100);
	//while (!(DF_STA_PORT & (1<< DF_STATE)));
	DF_wait_busy();
	
	SPI_DF_EN();
	
	spiSWTransmit(MM_PAGE_TO_B1_XFER);
	
	spiSWTransmit((unsigned char)(page >> 7));
	
	spiSWTransmit((unsigned char)(page << 1));
	
	spiSWTransmit(0x00);
	
	SPI_DF_DIS();
	
	DF_wait_busy();
	
	SPI_DF_EN();
	
	spiSWTransmit(BUFFER_1_READ);
	
	spiSWTransmit(0x00);
	
	spiSWTransmit(0x00);
	
	spiSWTransmit(0x00);
	
	spiSWTransmit(0x00);
	
	for (i=0;i<DF_BUFFER_SIZE;i++)
	{
		if (check==0)DF_buffer[i] = spiSWTransmit(0xFF);
		else
		{//spiSWTransmit(0xff)
			if (spiSWTransmit(0xFF)!=DF_buffer[i])
			{
				SPI_DF_DIS();
				return 1;
			}
		}
		
		//DF_buffer[i] = SPDR;
	}
	
	SPI_DF_DIS();
	
	return 0;
	//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)));

	SPI_DF_EN();

	spiSWTransmit(MAIN_MEMORY_PAGE_READ);

	spiSWTransmit((unsigned char)(page >> 6));

	spiSWTransmit((unsigned char)(page << 2));

	spiSWTransmit(0x00);

	spiSWTransmit(0x00);

	spiSWTransmit(0x00);

	spiSWTransmit(0x00);

	spiSWTransmit(0x00);

	for (i=0;i<528;i++)
	{
		spiSWTransmit(0x00);
		DF_buffer[i] = SPDR;
	}

	SPI_DF_DIS();

	//DF_SPI_OFF;
}*/


//读取状态寄存器
//	bit7		bit6	bit5	bit4	bit3	bit2	bit1		bit0
//RDY/BUSY		COMP	0		1		1		1		PROTECT		PAGE SIZE
unsigned char DF_read_reg(void)
{
	unsigned char temp=0x55;
	//DF_SPI_ON;
	SPI_DF_EN();
	spiSWTransmit(READ_STATE_REGISTER);
	//spiSWTransmit(0x00);
	//spiSWTransmit(0x00);
	//spiSWTransmit(0x00);
	temp=spiSWTransmit(0x00);
	//temp=SPDR;
	SPI_DF_DIS();
	//DF_SPI_OFF;
	return temp;
}


//检查状态寄存器最高位是否为忙,并等待空闲
void DF_wait_busy(void)
{
	unsigned char state_reg=0x00;
	SPI_DF_EN();
	spiSWTransmit(READ_STATE_REGISTER);
	//spiSWTransmit(0x00);
	//spiSWTransmit(0x00);
	//spiSWTransmit(0x00);
	
	while (!(state_reg&0x80))
	{
		state_reg = spiSWTransmit(0x00);
		//state_reg = SPDR ;
	}
	
	SPI_DF_DIS();
}


//将指定主存储器页的数据转入指定缓冲区
void DF_mm_to_buf(unsigned char buffer,unsigned int page)
{
	//DF_SPI_ON;
	DF_wait_busy();
	SPI_DF_EN();
	
	if (buffer==1)
		spiSWTransmit(MM_PAGE_TO_B1_XFER);
	else
		spiSWTransmit(MM_PAGE_TO_B2_XFER);
		
	spiSWTransmit((unsigned char)(page >> 7));
	
	spiSWTransmit((unsigned char)(page << 1));
	
	spiSWTransmit(0x00);
	
	SPI_DF_DIS();
	
	//DF_SPI_OFF;
}


//读取指定缓冲区指定单元的数据,保存在DF_buffer[]数组中
unsigned char DF_read_buf(unsigned char buffer,unsigned int start_address,unsigned int length)
{
	unsigned int i;
	
	if ((DF_BUFFER_SIZE-1-start_address)>=length)
	{
		//DF_SPI_ON;
		DF_wait_busy();
		SPI_DF_EN();
		
		if (buffer==1)
			spiSWTransmit(BUFFER_1_READ);
		else
			spiSWTransmit(BUFFER_2_READ);
			
		spiSWTransmit(0x00);
		
		spiSWTransmit((unsigned char)(start_address >> 8));
		
		spiSWTransmit((unsigned char)start_address);
		
		spiSWTransmit(0x00);
		
		for (i=0;i<length;i++)
		{
			DF_buffer[i] = spiSWTransmit(0xFF);
			//DF_buffer[i] = SPDR;
		}
		
		SPI_DF_DIS();
		
		//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 ((DF_BUFFER_SIZE-1-start_address)>=length)
	{
		//DF_SPI_ON;
		DF_wait_busy();
		SPI_DF_EN();
		
		if (buffer==1)
			spiSWTransmit(BUFFER_1_WRITE);
		else
			spiSWTransmit(BUFFER_2_WRITE);
			
		spiSWTransmit(0x00);
		
		spiSWTransmit((unsigned char)(start_address >> 8));
		
		spiSWTransmit((unsigned char)start_address);
		
		for (i=0;i<length;i++)
			spiSWTransmit(DF_buffer[i]);
			
		SPI_DF_DIS();
		
		return 1;
	}
	
	else
		return 0;
}


//将指定缓冲区中的数据写入主存储区的指定页
void DF_buf_to_mm(unsigned char buffer,unsigned int page)
{
	//DF_SPI_ON;
	DF_wait_busy();
	
	if (page<2048)
	{
		SPI_DF_EN();
		
		if (buffer==1)
			spiSWTransmit(B1_TO_MM_PAGE_PROG_WITH_ERASE);
		else
			spiSWTransmit(B2_TO_MM_PAGE_PROG_WITH_ERASE);
			
		spiSWTransmit((unsigned char)(page>>7));
		
		spiSWTransmit((unsigned char)(page<<1));
		
		spiSWTransmit(0x00);
		
		SPI_DF_DIS();
	}
	
	//DF_SPI_OFF;
}

⌨️ 快捷键说明

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