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

📄 at45db161d.c

📁 使用atmel128对45db161读写程序加LM2009R大液晶显示
💻 C
字号:
/************************************************
  flash 读写程序
  
  2008年6月20日
 
*************************************************/
#include "2008.h"

#define DF_PAGE_SIZE 528
#define DF_READ_BUFFER 0
#define DF_WRITE_BUFFER 1

#define MM_PAGE_TO_B1_XFER  0x53  //主存储器页到缓存区转移命令(缓冲区1 53H 缓冲区2 55H)
// main memory page to buffer 2 transfer
#define MM_PAGE_TO_B2_XFER  0x55  //主存储器页到缓存区转移命令(缓冲区1 53H 缓冲区2 55H)
// buffer 1 to main memory page program with built-in erase
#define B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83
// buffer 2 to main memory page program with built-in erase
#define B2_TO_MM_PAGE_PROG_WITH_ERASE 0x86
// buffer 1 read
#define BUFFER_1_READ 0xd1 //0xD4
// buffer 2 read
#define BUFFER_2_READ 0xd3 //0xD6
// buffer 1 write 
#define BUFFER_1_WRITE 0x84
// buffer 2 write 
#define BUFFER_2_WRITE 0x87


#define STATUS_REGISTER  0xD7


#define UNSELECT_CHIP  PORTB |= 0x10;
#define SELECT_CHIP    PORTB &= 0xef;

uint g_CurReadPage;//当前读的页地址
uint g_CurReadByte;//当前读的字节(页中地址)
uint g_CurWritePage;//当前写的页地址
uint g_CurWriteByte;//当前写的字节地址(页中地址)
//====================================================================
void df_init(void)
{
	//MISO设置为输入,上拉电阻关闭,其它默认为1
	//PORTB |= _BV(FLASH_SCK)|_BV(FLASH_MOSI)|_BV(FLASH_CS)|_BV(PB2);	
	//PORTB |=  1    2   4   0
	PORTB |= 0x17;
	/*
		注:使用AVR单片机SPI口,并用作主器件时SS引脚(ATMEGA8中PB2)要拉高或设置成输出!
	*/
	//SCK,MOSI和CS端口对应脚设置为输出
	//DDRB |= _BV(FLASH_SCK)|_BV(FLASH_MOSI)|_BV(FLASH_CS);                            
	//DDRB |=  1     2  4 
	DDRB |= 0X16;  //配置为输出
	// SPI中断禁止, SPI使能, master模式, MSB 前,  SPI 模式 3, SCK频率Fcl/4
	//SPCR = _BV(SPE)|_BV(MSTR)|_BV(CPHA)|_BV(CPOL);//|_BV(SPR1)|_BV(SPR0);
	SPCR = 0x5c;   //SPI控制寄存器
	
}
//======================================================================
//写初始化功能函数,addr为打开后读到的初始地址
void df_write_open(uint addr)
{
	g_CurWritePage=addr/DF_PAGE_SIZE;
	g_CurWriteByte=addr%DF_PAGE_SIZE;
	load_page_to_buffer(g_CurWritePage,DF_WRITE_BUFFER);
}
//======================================================================
//读初始化功能函数,addr为打开后读到的初始地址
void df_read_open(uint addr)
{
	g_CurReadPage=addr/DF_PAGE_SIZE;
	g_CurReadByte=addr%DF_PAGE_SIZE;
	load_page_to_buffer(g_CurReadPage,DF_READ_BUFFER);
}
//=======================================================================
//读主存储器指定页到读缓冲区(BUFFER1)
void load_page_to_buffer(uint page,uint buffer)
{
	SELECT_CHIP;
	
	if(buffer == DF_READ_BUFFER)            //=0
		spi_write(MM_PAGE_TO_B1_XFER);   //0x53 
	else
		spi_write(MM_PAGE_TO_B2_XFER); //0x55
	spi_write((uint)(page >> 6));
	spi_write((uint)(page << 2));
	spi_write(0x00);
	
	UNSELECT_CHIP; 
	
	df_wait_busy();
}
//=======================================================================
//从SPI口输出一字节数据
uint spi_write(uint data)
{
	SPDR = data;
	while(!(SPSR & 0x80)); //判断 SPIF
	return SPDR;
}
//=======================================================================
//检测并等待器件忙状态,8引脚封闭器件没有 RDY/BUSY引脚 为些通过读状态寄存器来检测忙状态
void df_wait_busy(void)
{
	SELECT_CHIP;
	spi_write(STATUS_REGISTER);
	while(1)
	{
		if(spi_write(0) & 0x80) //读取的最高位0时器件忙
			break;
	}
	UNSELECT_CHIP;
}
//=======================================================================
void df_write(uint *buf,uint size)  //buf 源数据  size 写多少个字节
{
	uint temp;
	
	if((g_CurWriteByte + size) > DF_PAGE_SIZE) //如果当前页未写空间不够size字节
	{
		//写当前页剩余空间的数据
		temp=DF_PAGE_SIZE - g_CurWriteByte;
		write_buffer(g_CurWriteByte,buf,temp); //将数据写入写缓冲区
		//保存当前页
		write_page_from_buffer(g_CurWritePage,DF_WRITE_BUFFER);
		g_CurWritePage++;
		load_page_to_buffer(g_CurWritePage,DF_WRITE_BUFFER);
		
		//写入到下一页对应缓冲区
		g_CurWriteByte=size-temp;
		write_buffer(0,buf+temp,g_CurWriteByte);
	}
	else
	{
		write_buffer(g_CurWriteByte,buf,size);
		g_CurWriteByte+=size;
		
		//缓冲已满,写入到主存储区
		if(g_CurWriteByte==DF_PAGE_SIZE)
		{
			g_CurWriteByte=0;
			write_page_from_buffer(g_CurWritePage,DF_WRITE_BUFFER);
			g_CurWritePage++;
			load_page_to_buffer(g_CurWritePage,DF_WRITE_BUFFER);			
		}
	} 	
}
//========================================================================
//将数据写入写缓冲区2  命令 0x87
void write_buffer(uint addr,uint *data,uint size)
{
	uint i;
	SELECT_CHIP;
	spi_write(BUFFER_2_WRITE);
	spi_write(0x00);       //写入缓冲区地址15位无关位              
	spi_write((uint)(addr>>8));   //写入缓冲区地址
	spi_write((uint)addr); //写入缓冲区地址  总共写了三个字节地址 24位 15位无关位 
	for(i=0;i<size;i++)      
		spi_write(data[i]);  //写数据
		                 
	UNSELECT_CHIP;
}
//========================================================================
//将写缓冲区内容写入到主存储器中指定页
void write_page_from_buffer(uint page,uint buffer)
{
	SELECT_CHIP;
	
	if(buffer == DF_WRITE_BUFFER) 
		spi_write(B2_TO_MM_PAGE_PROG_WITH_ERASE);  //0x86 
	else
		spi_write(B1_TO_MM_PAGE_PROG_WITH_ERASE);  //0x83
	spi_write((uint)(page>>6));  //2个无关位,12位页地址 PA11~PA0 与10个无关位
	spi_write((uint)(page<<2));
	spi_write(0x00);  // don't cares
	
	UNSELECT_CHIP;
	
	df_wait_busy();
}
//========================================================================
void df_write_close(void)
{
	write_page_from_buffer(g_CurWritePage,DF_WRITE_BUFFER); //缓冲区内容写入到主存储器
}
//========================================================================
void df_read_close(void)
{
	;//此处不做任何处理
}
//========================================================================
void df_read(uint *buf,uint size)
{
	uint temp;
	
	if((g_CurReadByte + size) > DF_PAGE_SIZE) //如果当前页未读取数据不够size字节
	{
		//读当前页剩余数据
		temp=DF_PAGE_SIZE - g_CurReadByte;
		read_buffer(g_CurReadByte,buf,temp);
		
		//装入下一页
		load_page_to_buffer(++g_CurReadPage,DF_READ_BUFFER);
		
		//从下一页读剩余数据
		g_CurReadByte=size-temp;
		read_buffer(0,buf+temp,g_CurReadByte);
	}
	else			//如果当前页数据有size字节
	{
		read_buffer(g_CurReadByte,buf,size);
		g_CurReadByte+=size;
		
		//如果当前页数据已全部读完
		if(g_CurReadByte==DF_PAGE_SIZE)
		{
			load_page_to_buffer(++g_CurReadPage,DF_READ_BUFFER);
			g_CurReadByte=0;			
		}
	} 
}
//========================================================================
//从读缓冲区读数据
void read_buffer(uint addr,uint *data,uint size)
{
	uint i;
	
	SELECT_CHIP;
	
	spi_write(BUFFER_1_READ);
	spi_write(0x00);                        
	spi_write((uint)(addr>>8));
	spi_write((uint)addr); 
	for(i=0;i<size;i++)      
		data[i]=spi_write(0);
		                 
	UNSELECT_CHIP;	
}
//========================================================================
void Read_Page(uint page,uint page_address, uint *buf,uint size) //page 页地址, page_address 页内地址, buf 数据 , size 多少个字节
{
    load_page_to_buffer(page,DF_READ_BUFFER); // 将主存储器指定的页内容读到缓冲区
    read_buffer(page_address,buf,size);       //从读缓冲区读数据
}
//========================================================================
void Write_page(uint page, uint page_address, uint *buf,uint size)  //page 页地址, page_address 页内地址, buf 数据 , size 多少个字节
{ 
    load_page_to_buffer(page,DF_WRITE_BUFFER);	// 将主存储器指定的页内容读到缓冲区
    write_buffer(page_address,buf,size);        //将数据写入写缓冲区
    write_page_from_buffer(page,DF_WRITE_BUFFER); //将缓冲区内容写入到主存储器中指定页中
}
//========================================================================
void Page_Scrape(uint page)  //page 要擦除的页
{
  SELECT_CHIP;
	spi_write(0x81);  //页擦除
	spi_write((uint)(page>>6));  //2个无关位,12位页地址 PA11~PA0 与10个无关位
	spi_write((uint)(page<<2));
	spi_write(0x00);  // don't cares
	
	UNSELECT_CHIP;
	
	df_wait_busy();
}
//========================================================================

⌨️ 快捷键说明

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