搜索
bottom↓
回复: 100

有感于近日多人寻求AT45DB161D的程序,发布一个AT45DB161D的操作函数库。

[复制链接]

出0入0汤圆

发表于 2007-4-6 22:41:55 | 显示全部楼层 |阅读模式
搜索了一下,坛子里似乎还没有比较全面的操作AT45DB161D的函数库,提到最多的也就是AVR335里的数字录音机应用笔记以及一些零碎的功能函数,所以决定发布自己写的AT45DB161D的操作函数库,给需要的人参考一下,也希望大家来纠错和添加功能。编译测试软件环境:winavr 20060421,硬件:M16+AT45DB161D-TU。



因为大年三十晚上和大年初一都在调试这个程序,所以就有了本坛的猪年第一帖,呵呵……



本库包含以下功能函数,函数名已经相当清楚了,就不介绍相应功能了,如果还不清楚请下载附件,里面有更详细的函数功能介绍:



void write_SPI (unsigned char data);

void DF_format (void);

void DF_page_earse (unsigned int page);

void DF_write_page (unsigned int page);

void DF_read_page (unsigned int page);

void DF_mm_read_page unsigned int page);

unsigned char DF_read_reg (void);

void DF_wait_busy (void);

void DF_mm_to_buf (unsigned char buffer,unsigned int page);

unsigned char DF_read_buf (unsigned char buffer,unsigned int start_address,unsigned int length);

unsigned char DF_write_buf (unsigned char buffer,unsigned int start_address,unsigned int length);

void DF_buf_to_mm (unsigned char buffer,unsigned int page);







涉及以下DATAFLASH操作:



#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 // 页删除(每页512/528字节)

#define SECTOR_ERASE 0x7C // 扇区擦除(每扇区128K字节)

#define READ_STATE_REGISTER 0xD7 // 读取状态寄存器



需要提醒大家注意的是:



1、写入时一定要查询状态寄存器的忙碌标志,否则后续指令无效,外部的BUSY管脚反映的状态,并不能作为写入的参考,当初就是在这个地方卡了3天时间。



2、AVR335提供的ICC和IAR的例程,也许时序上有些问题,直接在WINAVR里照搬是会出问题的,很多东西还是要根据DATASHEET来做,DATASHEET一遍看不懂,也要硬着头皮看10次8次,床头放一份,车子里放一份,办工桌上放一份,得空就反复看,直到有一天云散日出,一切都OK了,这就是我的学习方法,跟大家共勉,呵呵……



3、上个月发现有人照抄我在机器人坛公布的电路投稿到某电子刊物出版,心里颇感矛盾,这个世界需要更多无私的开源精神,同时无私开源也需要大家参与支持,如果大家都把开源的东西拿来获利,不尊重别人的劳动,搞得大家都心凉了,谁又来继续维持这种开源精神呢?





点击此处下载AT45DB161D操作库函数

出0入0汤圆

 楼主| 发表于 2007-4-6 22:53:09 | 显示全部楼层
还忘了提醒大家几点:



1、直到批号为0645的片子,chip erase指令还是不可靠的,这在datasheet 52页有描述。



2、芯片的页大小寄存器只能写一次(OTP),如果配置为每页512字节后就再也不能写回每页528字节了。



3、网上很多例程是旧版的161B的程序,跟161D操作指令有不少差别,ATMEL已经不建议使用这些旧指令了,移植的时候注意对照DATASHEET修改过来。

出0入0汤圆

发表于 2007-4-6 23:07:53 | 显示全部楼层
虽然看了一遍一遍又一遍,可还是没看懂,先下下来保存再学习。

出0入0汤圆

发表于 2007-4-7 08:04:57 | 显示全部楼层
我们是以收藏为快乐之本,以学习为娱乐目的,收藏->学习.改进。

出0入0汤圆

发表于 2007-4-7 09:32:27 | 显示全部楼层
谢谢gxlujd 彩虹大哥!

   

  "很多东西还是要根据DATASHEET来做,DATASHEET一遍看不懂,也要硬着头皮看10次8次,床头放一份,车子里放一份,办工桌上放一份,得空就反复看,直到有一天云散日出,一切都OK了,这就是我的学习方法"



   我也是硬着头皮看,看个几十次也差不多了.有感于一个同事说的一句话"NND,中国的翻译都干嘛去了?"

出0入0汤圆

发表于 2007-4-7 10:51:03 | 显示全部楼层
谢谢啦!

出0入0汤圆

发表于 2007-4-7 11:59:14 | 显示全部楼层
彩虹大哥的贴一定要顶!

出0入0汤圆

 楼主| 发表于 2007-4-7 12:16:01 | 显示全部楼层
谢谢大家捧场,说到翻译,其实并不是我们想象中的过了某级就能把技术文档翻译好的,我曾经和过了6级的英语专业学生合作翻译一些技术文档,但是发现我不在他们几乎没法工作。他们口语相当厉害,可以直接跟老外无障碍交流的,却不知如何翻译二极管、三极管这些科技英语的专有名词,所以要想翻译好英语的技术文档,非得要电子和英语都很厉害的人才能单独完成。

出0入0汤圆

发表于 2007-4-8 11:30:26 | 显示全部楼层
谢谢彩虹,我下了。

出0入0汤圆

发表于 2007-4-8 17:04:22 | 显示全部楼层
at45db161d我读到状态字了,我是用51的。搞了半天。头痛。

出0入0汤圆

发表于 2007-4-8 17:05:55 | 显示全部楼层
不用去理复位脚。

出0入0汤圆

发表于 2007-4-8 21:57:34 | 显示全部楼层
多谢谢彩虹了,红橙黄绿蓝靛紫

出0入0汤圆

发表于 2007-4-23 16:56:28 | 显示全部楼层
谢谢楼主,下来慢慢研究.

出0入0汤圆

发表于 2007-4-23 23:08:29 | 显示全部楼层
谢谢彩虹

出0入0汤圆

发表于 2007-4-24 07:17:09 | 显示全部楼层
头疼,头疼啊!10M的真不太好用(不会用)!!!

出0入0汤圆

发表于 2007-4-24 07:40:23 | 显示全部楼层
Atmel早就有了很全面的DataFlash的函数了。支持Supports 512Kbit - 64Mbit所有DataFlash。在AVRButterFly里呢。我用过了,很好用。不过.h文件里的命令有些是旧的,应该改成新的。剪切了一部分头文件。需要的自己去atmel下载吧。在avr单片机版面里的 Application Notes 搜索 AVR065。

/*

        Last change:  RM   17 Jan 2001   20:15

*/



//*****************************************************************************

//

//      COPYRIGHT (c) ATMEL Norway, 1996-2001

//

//      The copyright to the document(s) herein is the property of

//      ATMEL Norway, Norway.

//

//      The document(s) may be used  and/or copied only with the written

//      permission from ATMEL Norway or in accordance with the terms and

//      conditions stipulated in the agreement/contract under which the

//      document(s) have been supplied.

//

//*****************************************************************************

//

//  File........: DATAFLASH.C

//

//  Author(s)...: ATMEL Norway

//

//  Target(s)...: All AVRs with built-in HW SPI

//

//  Description.: Functions to access the Atmel AT45Dxxx dataflash series

//                                  Supports 512Kbit - 64Mbit

//

//  Revisions...:

//

//  YYYYMMDD - VER. - COMMENT                                       - SIGN.

//

//  20011017 - 1.00 - Beta release                                  -  RM

//  20011017 - 0.10 - Generated file                                -  RM

//  20031009          port to avr-gcc/avr-libc                      - M.Thomas

//

//*****************************************************************************





//Function definitions

void DF_SPI_init (void);

unsigned char DF_SPI_RW (unsigned char output);

unsigned char Read_DF_status (void);

void Page_To_Buffer (unsigned int PageAdr, unsigned char BufferNo);

unsigned char Buffer_Read_Byte (unsigned char BufferNo, unsigned int IntPageAdr);

void Buffer_Read_Str (unsigned char BufferNo, unsigned int IntPageAdr, unsigned int No_of_bytes, unsigned char *BufferPtr);

void Buffer_Write_Enable (unsigned char BufferNo, unsigned int IntPageAdr);

void Buffer_Write_Byte (unsigned char BufferNo, unsigned int IntPageAdr, unsigned char Data);

void Buffer_Write_Str (unsigned char BufferNo, unsigned int IntPageAdr, unsigned int No_of_bytes, unsigned char *BufferPtr);

void Buffer_To_Page (unsigned char BufferNo, unsigned int PageAdr);

void Cont_Flash_Read_Enable (unsigned int PageAdr, unsigned int IntPageAdr);



// *****************************[ End Of DATAFLASH.H ]*****************************

出0入0汤圆

发表于 2007-4-24 09:11:13 | 显示全部楼层
能给个具体详细的网址吗?找不到呀.

出0入0汤圆

发表于 2007-4-26 08:18:36 | 显示全部楼层
在这里呢:



http://www.atmel.com/dyn/products/app_notes.asp?family_id=607



找AVR065

出0入0汤圆

发表于 2007-4-26 08:50:58 | 显示全部楼层
AVR065:是以下的这些内容呀,不是at45db161呀.

AVR065: LCD Driver for the STK502 and AVR Butterfly (18 pages, revision C, updated 02/06)

In applications where user interaction is required it is often useful to be able to display information to the user. The ATmega169 is a MCU with integrated LCD driver. It can control up to 100 LCD segments. The ATmega169 is therefore, an obvious choice when designing applications that requires both an efficient MCU and an LCD.

出0入0汤圆

 楼主| 发表于 2007-4-26 09:05:14 | 显示全部楼层
AVR065: LCD Driver for the STK502 and AVR Butterfly



怎么不见楼上说的文件?何况2001年的库,肯定不能正常操作现在新的flashdata,AVR335那个数码录音机是2004年的文件版本,都还是不能正常操作AT45DB161D的,不信编译一下AVR335的程序试试就知道了。

出0入0汤圆

发表于 2007-4-26 11:23:37 | 显示全部楼层
呵呵,搞错了。上传了我用的dataflash文件。在AVRButterFly里的,我有所修改。写操作没有仔细测试。



点击此处下载armok01152059.rar

出0入0汤圆

发表于 2007-10-9 10:43:39 | 显示全部楼层
没想到这里有那么多资料,真是太好了。

出0入0汤圆

发表于 2007-11-12 15:44:25 | 显示全部楼层
早知道这里有现成的,昨天搞了一天,
下面是我写的程序
http://www.chipart.cn/cam8x/dataflash.asp

出0入12汤圆

发表于 2007-11-12 17:53:16 | 显示全部楼层
多谢彩虹

出0入0汤圆

发表于 2007-12-30 14:51:06 | 显示全部楼层
要用到45db321,呵呵。来down个程序参考一下。谢谢大家。:)

出0入0汤圆

发表于 2008-2-10 20:50:52 | 显示全部楼层
谢谢楼主的资料。有如下问题:

在直接读取主存储器页出来到buf的函数中,命令是什么?文中没有定义。  MAIN_MEMORY_PAGE_READ  ??

//以直接读取方式读取指定的主存储器页数据(页地址范围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 = SPDR;
        }
        DF_DESELECT_1;
       
        DF_SPI_OFF;
}

根据AT45DB041B的程序,我将这个命令按0xE8 对待,但是结果不成功。??请帮忙!谢谢!

出0入0汤圆

发表于 2008-2-11 08:45:15 | 显示全部楼层
谢谢!多谢!

出0入0汤圆

发表于 2008-3-25 22:37:23 | 显示全部楼层
彩虹大哥,我刚学AVR单片机的C语言,您可以把AT45DB161D的完整读写程序给我参考一下吗?包括主函数,谢谢您了。
我邮箱cheny@asimco-byc.com 我QQ729925930,我想向您请教一些问题,万分感谢!

出0入0汤圆

发表于 2008-3-28 09:33:15 | 显示全部楼层
这里有比较完整的
http://218.16.124.207/bbs/bbs_content.jsp?bbs_sn=927887&bbs_page_no=1&search_mode=3&search_text=mirrorok&bbs_id=1000

出0入0汤圆

发表于 2008-4-26 18:11:37 | 显示全部楼层
"很多东西还是要根据DATASHEET来做,DATASHEET一遍看不懂,也要硬着头皮看10次8次,床头放一份,车子里放一份,办工桌上放一份,得空就反复看,直到有一天云散日出,一切都OK了,这就是我的学习方法"

有同感,收藏了。

出0入0汤圆

发表于 2008-4-26 21:09:35 | 显示全部楼层
牛人真多呀,写法也正规……
先收藏一哈,没准啥时候要用上。
谢谢彩虹、zsmbj、芯艺等热心肠的筒子。

出0入0汤圆

发表于 2008-4-28 15:19:40 | 显示全部楼层
有个问题请教彩虹兄:

#define DF_STATE       

似乎161D的引脚没有专门指示装态的,是否引脚复用,没有具体的看手册,英文差看不懂

1.SI 2.SCK 3./RST 4./CS 5./WP 6.Vcc 7.GND 8.SO

/WP脚不用的话,是否直接悬空?

另外:
26楼说的问题,我在编译时也发现了,应该是数据手册28页指令表中提到的0xD2H

出0入0汤圆

发表于 2008-4-28 15:23:33 | 显示全部楼层
看了下手册,原来是这样的:TSOP28的第1脚是RDY/BUSY ,我采用的是SOIC8封装的,所以找不到此引脚。

出0入0汤圆

发表于 2008-5-29 21:17:19 | 显示全部楼层
谢谢大家,收下了!

出0入0汤圆

发表于 2008-7-21 08:51:59 | 显示全部楼层
我也是用soc 8 封装的,确实找不到BUSY脚,麻烦问一下该怎么处理比较好?

出0入0汤圆

发表于 2008-7-21 08:53:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-7-29 00:24:04 | 显示全部楼层
TO:35楼】 wellsonkk
"我也是用soc 8 封装的,确实找不到BUSY脚,麻烦问一下该怎么处理比较好?"

读状态寄存器

状态寄存器与RDY/#BUSY都会指示芯片处于忙状态。

出0入0汤圆

发表于 2008-8-10 06:04:50 | 显示全部楼层
好东西

出0入0汤圆

发表于 2008-8-10 08:03:04 | 显示全部楼层
学习

出0入0汤圆

发表于 2008-8-11 01:45:07 | 显示全部楼层
感谢分享!我以前草草地写了一个AT45DB041B的程序,现在可以好好学习一下啦

出0入0汤圆

发表于 2008-8-25 10:55:32 | 显示全部楼层
牛!

出0入0汤圆

发表于 2008-9-5 17:39:57 | 显示全部楼层
谢谢彩虹,谢谢振南,我已经搞定8051读写AT45DB321D了.

出0入0汤圆

发表于 2009-3-9 17:43:23 | 显示全部楼层
看了学了用了不道谢对不起LZ,
真心谢谢了!

出0入0汤圆

发表于 2009-3-12 15:53:42 | 显示全部楼层
再问个相关的问题,就是那个“通过缓冲自动页重写”命令是怎么用的?我一直没看明白。

出0入0汤圆

发表于 2009-3-12 15:55:16 | 显示全部楼层
再问个相关的问题,就是那个“通过缓冲自动页重写”命令是怎么用的?我一直没看明白。

出0入8汤圆

发表于 2009-4-18 13:16:22 | 显示全部楼层
最近要用,mark
谢谢

出0入0汤圆

发表于 2009-4-18 16:27:39 | 显示全部楼层
有感于近日多人寻求AT45DB161D的程序,发布一个AT45DB161D的操作函数库

出0入0汤圆

发表于 2009-4-18 18:01:58 | 显示全部楼层
学习学习!!!

出0入0汤圆

发表于 2009-4-18 19:52:20 | 显示全部楼层
学习。

出0入0汤圆

发表于 2009-4-27 19:39:40 | 显示全部楼层
彩虹的老贴

新看

出0入0汤圆

发表于 2009-5-2 18:58:14 | 显示全部楼层
我再添加两个程序

//选择Buffer后直接写主存
void DF_write_mm(unsigned char buffer,unsigned int page,unsigned int page_offset, int data)
{
        unsigned int i;
        if  ((527-page_offset)>=1)
        {
                DF_SPI_ON;
                DF_wait_busy();
                DF_SELECT_1;
                if (buffer==1)
                        write_SPI(WRITE_TO_MM_BUFFER_1);
                else
                        write_SPI(WRITE_TO_MM_BUFFER_2);
                write_SPI((unsigned char)(page >> 6));
                write_SPI((unsigned char)(page << 2)||(page_offset >> 8));                  
                write_SPI((unsigned char)page_offset);
                write_SPI(data);
                DF_DESELECT_1;
               
        }

}


//直接读内存
unsigned char DF_read_mm(unsigned int page,unsigned int page_offset)
{
        unsigned int i;
        if  ((527-page_offset)>=1)
        {
                DF_SPI_ON;
                DF_wait_busy();
                DF_SELECT_1;
                write_SPI(READ_FROM_MM);               
                write_SPI((unsigned char)(page >> 6));
                write_SPI((unsigned char)(page << 2)||(page_offset >> 8));                  
                write_SPI((unsigned char)page_offset);
                write_SPI(0X00);
                write_SPI(0X00);
                write_SPI(0X00);
                write_SPI(0X00);
                write_SPI(0XFF);
                DF_DESELECT_1;       
        }
    return SPDR;
}

已经测试过了

出0入0汤圆

发表于 2009-5-2 21:49:42 | 显示全部楼层
谢谢彩虹及各位

出0入0汤圆

发表于 2009-5-5 20:11:08 | 显示全部楼层
各位,有测试过彩虹AT45DB161D例子程序的吗?
我现在按彩虹的程序调不通!

出0入0汤圆

发表于 2009-5-8 13:40:45 | 显示全部楼层
有测试过

彩虹的程序是WinAVR 编译的
不过稍改过几点
完全可以转到ICCAVR上

彩虹程序有几个命令没有补充到宏定义中
你自己可以加下

他的的库操作函数是没有问题的

出0入0汤圆

发表于 2009-5-8 15:15:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-17 03:23:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-5-17 06:34:26 | 显示全部楼层
mark.

出0入0汤圆

发表于 2009-5-20 23:32:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-6-12 11:52:24 | 显示全部楼层
标记

出0入0汤圆

发表于 2009-7-31 10:32:45 | 显示全部楼层
要用到 ,谢谢了

出0入0汤圆

发表于 2009-7-31 11:31:13 | 显示全部楼层
正要用这个芯片呢,谢谢

出0入0汤圆

发表于 2009-7-31 11:47:57 | 显示全部楼层
我也在用45db081,可是读出来总是ff,哪位大哥可以给我指导下,qq251597590

出0入0汤圆

发表于 2009-8-6 10:12:24 | 显示全部楼层
记号,慢慢学习

出0入0汤圆

发表于 2009-8-12 20:41:11 | 显示全部楼层
感谢彩虹,希望能够用上。
ST提供的AT45库函数只提供了BUFFER1的读写操作,写太慢了!

出0入0汤圆

发表于 2009-8-16 20:45:33 | 显示全部楼层
记号 慢慢学习

出0入0汤圆

发表于 2009-8-17 01:43:26 | 显示全部楼层
MARK
不知道51的可以用不

出0入0汤圆

发表于 2009-8-17 17:56:35 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-8-25 11:15:21 | 显示全部楼层
谁能给我说说那个地址哪儿怎么理解和操作呀?
为什么参数page 要右移6位,
后面的那个还要右移8位等待,这儿看不明白了
谢谢大侠们,
我QQ:835016072

出0入0汤圆

发表于 2009-10-23 00:03:56 | 显示全部楼层
好东西!

出0入0汤圆

发表于 2009-10-23 10:23:42 | 显示全部楼层
最近正在使用DB161,相信会有很大帮助,先谢过彩虹大哥了!

出0入0汤圆

发表于 2009-10-23 15:46:19 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-2 16:07:48 | 显示全部楼层
彩虹,您好,我下个问

在接收页或者缓存区数据时,为什么都要加上一句
write_SPI(0x00);

比如检查状态寄存器的DF_wait_busy函数中
while((state_reg&0x80) == 0)
        {
                write_SPI(0x00);
                state_reg = SPDR ;
        }

或者在DF_MM_read_page函数中
for (i=0;i<528;i++)
        {
                write_SPI(0x00);
                DF_buffer = SPDR;
        }
请赐教~

出0入0汤圆

发表于 2010-1-21 20:15:17 | 显示全部楼层
用上了,谢谢,这几天打不开,不然早点搞定...

出0入0汤圆

发表于 2010-1-26 15:37:20 | 显示全部楼层
bucuo!

出0入0汤圆

发表于 2010-3-13 15:47:29 | 显示全部楼层
谢谢各位啦!

出0入0汤圆

发表于 2010-3-18 17:38:15 | 显示全部楼层
正需,谢谢!

出0入0汤圆

发表于 2010-3-18 20:27:42 | 显示全部楼层
谢谢啊,准备用

出0入0汤圆

发表于 2010-9-25 18:57:53 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-26 12:15:25 | 显示全部楼层
不错!!!!!!!!!!!!

出0入0汤圆

发表于 2010-9-26 13:09:56 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-1 10:00:37 | 显示全部楼层
mark
好东西

出0入0汤圆

发表于 2010-11-29 14:04:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-14 22:06:09 | 显示全部楼层
感谢彩虹

出0入0汤圆

发表于 2011-4-14 22:11:31 | 显示全部楼层
回复【72楼】agengood
mark
-----------------------------------------------------------------------

同问

出0入0汤圆

发表于 2011-4-14 22:12:32 | 显示全部楼层
回复【73楼】cf753951 风驰骏马
彩虹,您好,我下个问
在接收页或者缓存区数据时,为什么都要加上一句
write_spi(0x00);
比如检查状态寄存器的df_wait_busy函数中
while((state_reg&amp;0x80) == 0)
{
write_spi(0x00);
state_reg = spdr ;
}
或者在df_mm_read_page函数中
for (i=0;i&lt;528;i++)
{
write_spi(0x00);
df_buffer = spdr;
}
请赐教~
-----------------------------------------------------------------------

上面打错了,不好意思。同问这个。

出50入0汤圆

发表于 2011-4-14 22:37:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-14 22:41:06 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-28 11:36:48 | 显示全部楼层
回复【楼主位】gxlujd 彩虹
-----------------------------------------------------------------------

你好  我现在用128L 的io 模拟spi 通讯  可是读出来的状态寄存器 值为0x80  应该为0x9c 才对    我用的是at45db041d     我的spi 模拟的有问题吗

定义
   #define    WP_RESET      PB5
#define    CS            PB6
#define    SCK           PB7
#define    SI            PG3
#define    SO            PG4

/*****************************************
数据端口定义

*****************************************/
#define    DataDDR     DDRG
#define    DataPIN     PING
#define    DataPORT    PORTG

#define  SI_L     {DataDDR|=(1<<SI);DataPORT&=~(1<<SI);}
#define  SI_H     {DataDDR|=(1<<SI);DataPORT|=(1<<SI); }
//#define  SO_L     {Data_DDR|=(1<<SI);Data_PORT&=~(1<<SI);}
//#define  SO_H     {Data_DDR|=(1<<SI);Data_PORT&=~(1<<SI);}
/***************************************
控制端口定义

***************************************/

#define    ContrlDDR     DDRB
#define    ContrlPIN     PINB
#define    ContrlPORT    PORTB

#define    SCK_L  {ContrlDDR|=(1<<SCK);  ContrlPORT&=~(1<<SCK);}
#define    SCK_H  {ContrlDDR|=(1<<SCK);  ContrlPORT|=(1<<SCK);}
#define    CS_L   {ContrlDDR|=(1<<CS);   ContrlPORT&=~(1<<CS); }
#define    CS_H   {ContrlDDR|=(1<<CS);   ContrlPORT|=(1<<CS); }


void   At45db041_init(void)
{
  ContrlDDR|=(1<<WP_RESET);
  ContrlPORT&=~(1<<WP_RESET); //输出低电平 写保护 和复位引脚 低电平
  ContrlDDR|=(1<<CS);         //片选 控制方向寄存器
  ContrlPORT|=(1<<CS);        //片选为高电平
  DataDDR|=(1<<SI);           //数据输入SI
  DataPORT&=~(1<<SI);         //数据输入端口低电平
  DataDDR&=~(1<<SO);          //数据输出SO  方向输出
  DataPORT&=~(1<<SO);         //内部不上拉
   
}

void  SPI_Writebyte(unsigned char dat)
{
  unsigned char i=0;
  for(i=0;i<8;i++)
  {
     SCK_L;  
    if(dat&0x80)
      {
           SI_H;  //PG3 -SI
      }
   else
      {
          SI_L;
      }
         asm("nop");
         
         SCK_H;
     SCK_L;
     asm("nop");
         dat=dat<<1;
    }
       
}

unsigned char  SPI_Readbyte(void)
{
    unsigned char i=0,temp=0;
        DataDDR&=~(1<<SO);  //so 口设为输入
        DataPORT&=~(1<<SO); //so 电阻不上拉
       
        for(i=0;i<8;i++)
        {  
           temp<<=1;  //////------;
           SCK_H;
           if(DataPIN&(1<<SO)) //读数据 ------///////------- PG4
           {
            temp|=0x80;
           }
            SCK_L;
         asm("nop");
         }
           SCK_H;
        return temp;
       
}

/******************************************************************************
* 函数原型:unsigned char AT45DB041B_StatusRegisterRead(void);                *                       
* 名   称:AT45db041d_StatusRegisterRead                                      *
* 功   能:由SPI_SI口读AT45DB041d的状态字                                     *
* 入口参数:无                                                                *
* 出口参数:返回状态字                                                        *
*******************************************************************************/
/*Status Register Format:                                                     */
/*   -----------------------------------------------------------------------  */  
/* | bit7   | bit6   | bit5   | bit4   | bit3   | bit2   | bit1   | bit0   |  */
/* |--------|--------|--------|--------|--------|--------|--------|--------|  */
/* |RDY/BUSY| COMP   |   0    |   1    |   1    |   1    |   X    |   X    |  */
/*   -----------------------------------------------------------------------  */
/* bit7 - 忙标记,0为忙1为不忙。                                              */
/*       当Status Register的位0移出之后,接下来的时钟脉冲序列将使SPI器件继续  */
/*       将最新的状态字节送出。                                               */
/* bit6 - 标记最近一次Main Memory Page和Buffer的比较结果,0相同,1不同。      */
/* bit5                                                                       */
/* bit4                                                                       */
/* bit3                                                                       */
/* bit2 - 这4位用来标记器件密度,对于AT45DB041B,这4位应该是0111,一共能标记  */
/*        16种不同密度的器件。                                                */
/* bit1                                                                       */
/* bit0 - 这2位暂时无效                                                       */
/******************************************************************************/

unsigned char At45db041_Readstatus()
{
unsigned char status=0;
  CS_L;  //片选打开  
SPI_Writebyte(READ_STATE_REGISTER);  //D7H是读取状态的命令字
status=SPI_Readbyte();//读取状态字节
  CS_H; //片选关闭
return status;   

}

/************************************************/
/*                                              */
/*检查状态寄存器最高位是否为忙,并等待空闲      */
/*state_reg                                     */
/************************************************/
unsigned char  DF_wait_busy(void)
{
        unsigned char state_reg=0x00;
        unsigned char i=255;
        while(i)
        {
          state_reg=At45db041_Readstatus() ;//读取的最高位0时器件忙
          if(state_reg&0x80) break;
          i--;
        }
   return i;
}

出0入0汤圆

发表于 2011-4-28 13:20:50 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-28 22:35:55 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-5-4 16:52:03 | 显示全部楼层
回复【楼主位】gxlujd 彩虹
-----------------------------------------------------------------------

make xuexi

出0入0汤圆

发表于 2011-5-6 16:02:24 | 显示全部楼层
我现在用M25PE10,同样是SPI_FLASH,型号不同,操作应该可以借鉴,谢谢为此贴做出贡献的每一位!

出0入0汤圆

发表于 2011-6-13 17:01:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-8 21:23:52 | 显示全部楼层
很好。。有很多资料谢谢楼主。

出0入0汤圆

发表于 2011-8-6 14:14:19 | 显示全部楼层
顶一下

出0入0汤圆

发表于 2011-12-29 10:12:24 | 显示全部楼层
mark!

出0入0汤圆

发表于 2012-4-19 16:08:53 | 显示全部楼层
//读取指定缓冲区指定单元的数据,保存在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;
}

为什么是527-? 那么lenth不是最长是527吗 最后读的不是0-526 少了一个吗?
求解

出0入0汤圆

发表于 2012-4-27 15:51:27 | 显示全部楼层
qjj2858 发表于 2012-4-19 16:08
//读取指定缓冲区指定单元的数据,保存在DF_buffer[]数组中
unsigned char DF_read_buf(unsigned char buff ...

>=应该是0——527一共528个字节

出0入0汤圆

发表于 2012-11-12 00:26:49 | 显示全部楼层
天下无声胜有声

出0入0汤圆

发表于 2012-11-12 07:00:01 | 显示全部楼层
     好东西
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-7 15:10

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表