AVR单片机SPI口读写AT45DB161D接口程序设计.docx
- 文档编号:23593644
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:14
- 大小:849.46KB
AVR单片机SPI口读写AT45DB161D接口程序设计.docx
《AVR单片机SPI口读写AT45DB161D接口程序设计.docx》由会员分享,可在线阅读,更多相关《AVR单片机SPI口读写AT45DB161D接口程序设计.docx(14页珍藏版)》请在冰豆网上搜索。
AVR单片机SPI口读写AT45DB161D接口程序设计
AVR单片机SPI口读写AT45DB161D接口程序设计
本程序为AVR单片机SPI口访问AT45DB161D提供一组接口函数,通过这一组接口函数可非常容易的完成对AT45DB161D的读写操作
AT45DB161D按页组织和操作(读写擦等等)内部的FLASH存储器,每页为528字节(特殊用途时可通过命令配置成512字节),其内部共集成4096页,
即4096*528=2162688字节。
本程序将为您提供读写这2162688字节存储区的线性操作方法。
使用这些函数,用户可不必考虑AT45DB161D内部的存储
器组织结构,如同读写一个文件一样进行读写操作。
voiddf_init(void);
这是SPI口初始化函数,它必须在所有这些接口函数调用之前得到调用
voiddf_read_open(uint32_taddr);
读操作初始化函数,addr指定接下来的读函数的开始读取位置。
程序内部维护一个当前读取计数器,用户每读一字节该计数器加一
voiddf_write_open(uint32_taddr);
写操作初始化函数,addr指定接下来的写函数的开始写入位置。
程序内部维护一个当前写入计数器,用户每写入一个字节该计数器加一
uint8_tdf_getc(void);
此函数从当前读位置读取一字节后返回,内部的读计数器加一
voiddf_putc(uint8_tc);
此函数向当前写位置写入一字节的数据,并使内部写计数器加一
voiddf_read(uint8_t*buf,uint8_tsize);
此函数从当前读位置读取size个字节的数据到缓冲区buf,并使内部读计数器加size
voiddf_write(uint8_t*buf,uint8_tsize);
此函数从缓冲区buf向当前写位置写入size字节的数据,并使内部写计数器加size
voiddf_read_seek(uint32_taddr);
调整当前读计数器,调用此函数前必须已调用df_read_open
voiddf_write_seek(uint32_taddr);
调整当前写计数器,调用此函数前必须已调用df_write_open
voiddf_read_close(void);
关闭读操作
voiddf_write_close(void);
关闭写操作,所有的写入操作完成后必须调用此函来结束写操作,以便数据能够完整的保存到AT45DB161D主存储器当中
源程序:
/**********************************
AVR单片机SPI口读写at45db161d接口程序
文件名:
dataflash.c
编译:
WinAVR-20070525
芯艺设计室2004-2007版权所有
转载请保留本注释在内的全部内容
WEB:
Email:
********************
**********************************/
#include
#include"at45db161d.h"
#include"dataflash.h"
/*****下面是全局变量定义******/
staticuint16_tg_CurReadPage;//当前读的页地址
staticuint16_tg_CurReadByte;//当前读的字节(页中地址)
staticuint16_tg_CurWritePage;//当前写的页地址
staticuint16_tg_CurWriteByte;//当前写的字节地址(页中地址)
/*****下面是内部调用的接口函数******/
//从SPI口输出一字节数据
staticuint8_tspi_write(uint8_tdata)
{
SPDR=data;
while(!
(SPSR&_BV(SPIF)));
returnSPDR;
}
//检测并等待器件忙状态,8引脚封闭器件没有RDY/BUSY引脚为些通过读状态寄存器来检测忙状态
staticvoiddf_wait_busy(void)
{
SELECT_CHIP;
spi_write(STATUS_REGISTER);
while
(1)
{
if(spi_write(0)&0x80)//读取的最高位0时器件忙
break;
}
UNSELECT_CHIP;
}
//读主存储器指定页到读缓冲区(BUFFER1)
staticvoidload_page_to_buffer(uint16_tpage,uint8_tbuffer)
{
SELECT_CHIP;
if(buffer==DF_READ_BUFFER)
spi_write(MM_PAGE_TO_B1_XFER);
else
spi_write(MM_PAGE_TO_B2_XFER);
spi_write((uint8_t)(page>>6));
spi_write((uint8_t)(page<<2));
spi_write(0x00);
UNSELECT_CHIP;
df_wait_busy();
}
//将写缓冲区内容写入到主存储器中指定页
staticvoidwrite_page_from_buffer(uint16_tpage,uint8_tbuffer)
{
SELECT_CHIP;
if(buffer==DF_WRITE_BUFFER)
spi_write(B2_TO_MM_PAGE_PROG_WITH_ERASE);
else
spi_write(B1_TO_MM_PAGE_PROG_WITH_ERASE);
spi_write((uint8_t)(page>>6));
spi_write((uint8_t)(page<<2));
spi_write(0x00);//don'tcares
UNSELECT_CHIP;
df_wait_busy();
}
//从读缓冲区读数据
staticvoidread_buffer(uint16_taddr,uint8_t*data,uint8_tsize)
{
uint8_ti;
SELECT_CHIP;
spi_write(BUFFER_1_READ);
spi_write(0x00);
spi_write((uint8_t)(addr>>8));
spi_write((uint8_t)addr);
for(i=0;i data[i]=spi_write(0); UNSELECT_CHIP; } //将数据写入写缓冲区 staticvoidwrite_buffer(uint16_taddr,uint8_t*data,uint8_tsize) { uint8_ti; SELECT_CHIP; spi_write(BUFFER_2_WRITE); spi_write(0x00); spi_write((uint8_t)(addr>>8)); spi_write((uint8_t)addr); for(i=0;i spi_write(data[i]); UNSELECT_CHIP; } /*****下面是为外部调用而提供的接口函数******/ voiddf_init(void) { //MISO设置为输入,上拉电阻关闭,其它默认为1 PORTB|=_BV(FLASH_SCK)|_BV(FLASH_MOSI)|_BV(FLASH_CS)|_BV(PB2); //SCK,MOSI和CS端口对应脚设置为输出 DDRB|=_BV(FLASH_SCK)|_BV(FLASH_MOSI)|_BV(FLASH_CS); //SPI中断禁止,SPI使能,master模式,MSB前,SPI模式3,SCK频率Fcl/4 SPCR=_BV(SPE)|_BV(MSTR)|_BV(CPHA)|_BV(CPOL);//|_BV(SPR1)|_BV(SPR0); } //读初始化功能函数,addr为打开后读到的初始地址 voiddf_read_open(uint32_taddr) { g_CurReadPage=addr/DF_PAGE_SIZE; g_CurReadByte=addr%DF_PAGE_SIZE; load_page_to_buffer(g_CurReadPage,DF_READ_BUFFER); } voiddf_write_open(uint32_taddr) { g_CurWritePage=addr/DF_PAGE_SIZE; g_CurWriteByte=addr%DF_PAGE_SIZE; load_page_to_buffer(g_CurWritePage,DF_WRITE_BUFFER); } uint8_tdf_getc(void) { uint8_tc; read_buffer(g_CurReadByte,&c,1); g_CurReadByte++; if(g_CurReadByte==DF_PAGE_SIZE) { g_CurReadPage++; load_page_to_buffer(g_CurReadPage,DF_READ_BUFFER); g_CurReadByte=0; } returnc; } voiddf_putc(uint8_tc) { write_buffer(g_CurWriteByte,&c,1); g_CurWriteByte++; 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); } } voiddf_read(uint8_t*buf,uint8_tsize) { uint8_ttemp; 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; } } } voiddf_write(uint8_t*buf,uint8_tsize) { uint8_ttemp; 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); } } } //调整写指针 voiddf_read_seek(uint32_taddr) { df_read_close(); df_read_open(addr); } //调整读指针 voiddf_write_seek(uint32_taddr) { df_write_close(); df_write_open(addr); } voiddf_read_close(void) { //此处不做任何处理 } voiddf_write_close(void) { write_page_from_buffer(g_CurWritePage,DF_WRITE_BUFFER);//缓冲区内容写入到主存储器 } dataflash.h文件: #ifndefDATAFLASH_H #defineDATAFLASH_H //硬件引脚定义 #defineFLASH_MOSIPB3 #defineFLASH_MISOPB4 #defineFLASH_SCKPB5 #defineFLASH_CSPB1 #defineUNSELECT_CHIPPORTB|=_BV(FLASH_CS) #defineSELECT_CHIPPORTB&=~_BV(FLASH_CS) // #defineDF_PAGE_SIZE528 #defineDF_READ_BUFFER0 #defineDF_WRITE_BUFFER1 #endif 测试电路图和实物照片:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AVR 单片机 SPI 读写 AT45DB161D 接口 程序设计