请问:at45db081d怎么对page页addr地址写入Nbyte数据?

[复制链接]
4212|4
 楼主| voidx 发表于 2009-12-9 17:06 | 显示全部楼层 |阅读模式
本帖最后由 voidx 于 2009-12-9 17:23 编辑

请问:at45db081d怎么对page页addr地址写入Nbyte数据(只写入,不擦除,其他数据保持不变)?
znmcu 发表于 2009-12-18 15:29 | 显示全部楼层
AT45DB161.c

  1. #include "at45db161.h"
  2. #include "spi.h"
  3. /*******************************************************
  4.         +---------------------------------------+
  5.         | 振南电子 驱动程序模块 AT45DB161  部分 |
  6.         +---------------------------------------+
  7.   此源码版权属 振南 全权享有,如欲引用,敬请署名并告知
  8.         严禁随意用于商业目的,违者必究,后果自负
  9.          振南电子
  10.              ->产品网站 http://www.znmcu.cn/
  11.              ->产品网店 http://shop.znmcu.cn/
  12.              ->产品咨询 QQ:987582714
  13.                MSN:yzn07@126.com
  14.                      WW:yzn07
  15.            
  16. ********************************************************/
  17. /******************************************************************
  18. - 功能描述:读取AT45DB161的状态
  19. - 隶属模块:AT45DB161模块
  20. - 函数属性:内部
  21. - 参数说明:无
  22. - 返回说明:无
  23. - 注:无
  24. ******************************************************************/
  25. unsigned char AT45DB161_ReadStatus()
  26. {
  27. unsigned char status;
  28. AT45DB161_CS=0;   
  29. SPI_WriteByte(0xd7);
  30. status=SPI_ReadByte();
  31. AT45DB161_CS=1;
  32. return status;   
  33. }
  34. /***********************************************************************
  35. - 功能描述:从某一扇区的某个位置开始读取一定长度的数据,放入数据缓冲区
  36. - 隶属模块:AT45DB161模块
  37. - 函数属性:外部,供用户调用
  38. - 参数说明:addr:扇区地址
  39.              start:扇区内的起始位置
  40.     len:要读取的数据长度
  41.     pbuf:指向数据缓冲中的指针
  42. - 返回说明:无
  43. - 注:无
  44. ***********************************************************************/
  45. void AT45DB161_ReadBytes(unsigned int addr,unsigned int start,unsigned int len,unsigned char *pbuf)
  46. {     
  47. unsigned int i;     
  48. while(!(AT45DB161_ReadStatus()&0x80));
  49. AT45DB161_CS=0;   
  50. SPI_WriteByte(0xe8);   
  51. SPI_WriteByte((unsigned char)(addr>>6));   
  52. SPI_WriteByte((unsigned char)((addr<<2)|(start>>8)));
  53. SPI_WriteByte((unsigned char)start);
  54. for(i=0;i<4;i++) SPI_WriteByte(0x00);
  55. for(i=0;i<len;i++) pbuf[i]=SPI_ReadByte();
  56. AT45DB161_CS=1;
  57. }
  58. /***********************************************************************
  59. - 功能描述:向某一个数据缓冲通道中从某一位置开始写入一定长度的数据
  60. - 隶属模块:AT45DB161模块
  61. - 函数属性:外部,供用户调用
  62. - 参数说明:nbuf:缓冲通道
  63.              start:扇区内的起始位置
  64.     len:要读取的数据长度
  65.     pbuf:指向数据缓冲中的指针
  66. - 返回说明:无
  67. - 注:无
  68. ***********************************************************************/
  69. void AT45DB161_WriteBuffer(unsigned char nbuf,unsigned int start,unsigned int len,unsigned char *pbuf)
  70. {
  71. unsigned int i;
  72. while(!(AT45DB161_ReadStatus()&0x80));   
  73. AT45DB161_CS=0;   
  74. switch(nbuf)
  75. {
  76.   case 1:
  77.          SPI_WriteByte(0x84);
  78.    break;
  79.   case 2:
  80.          SPI_WriteByte(0x87);
  81.    break;
  82. }
  83.   SPI_WriteByte(0x00);
  84.   SPI_WriteByte((unsigned char)(start>>8));
  85.   SPI_WriteByte((unsigned char)start);
  86.   for(i=0;i<len;i++) SPI_WriteByte(pbuf[i]);
  87.   AT45DB161_CS=1;   
  88. }
  89. /****************************************************************************
  90. - 功能描述:通过某一条缓冲通道将一定长度的数据写入到某一扇区中的某个位置上去
  91. - 隶属模块:AT45DB161模块
  92. - 函数属性:内部
  93. - 参数说明:nbuf:缓冲通道
  94.              start:扇区内的起始位置
  95.     len:要写入的数据长度
  96.     pbuf:指向数据缓冲中的指针
  97. - 返回说明:无
  98. - 注:无
  99. ***************************************************************************/
  100. void AT45DB161_WriteBytes(unsigned char nbuf,unsigned int addr,unsigned int start,unsigned int len,unsigned char *pbuf)
  101. {
  102. AT45DB161_WriteBuffer(nbuf,start,len,pbuf);
  103. while(!(AT45DB161_ReadStatus()&0x80));   
  104. AT45DB161_CS=0;
  105. switch(nbuf)
  106. {
  107.   case 1:
  108.          SPI_WriteByte(0x83);
  109.    break;
  110.   case 2:
  111.          SPI_WriteByte(0x86);
  112.    break;
  113. }
  114. SPI_WriteByte((unsigned char)(addr>>6));
  115. SPI_WriteByte((unsigned char)(addr<<2));
  116. SPI_WriteByte(0x00);
  117. AT45DB161_CS=1;
  118. }
  119. /****************************************************************************
  120. - 功能描述:读取AT45DB161的扇区数据(512字节)到缓冲区
  121. - 隶属模块:AT45DB161模块
  122. - 函数属性:外部,供用户调用
  123. - 参数说明:addr:扇区地址
  124.     pbuf:指向数据缓冲中的指针
  125. - 返回说明:无
  126. - 注:无
  127. ***************************************************************************/
  128. void AT45DB161_ReadSector(unsigned long addr,unsigned char *pbuf)
  129. {
  130. AT45DB161_ReadBytes(addr,0,512,pbuf);
  131. }
  132. /****************************************************************************
  133. - 功能描述:将缓冲区中的数据写入AT45DB161的扇区(512字节)
  134. - 隶属模块:AT45DB161模块
  135. - 函数属性:外部,供用户调用
  136. - 参数说明:addr:扇区地址
  137.     pbuf:指向数据缓冲中的指针
  138. - 返回说明:无
  139. - 注:无
  140. ***************************************************************************/
  141. void AT45DB161_WriteSector(unsigned long addr,unsigned char *pbuf)
  142. {
  143. AT45DB161_WriteBytes(1,addr,0,512,pbuf);
  144. }


AT45DB161.h

  1. #ifndef  _AT45DB161_H_
  2. #define  _AT45DB161_H_
  3. /*******************************************************
  4.         +---------------------------------------+
  5.         | 振南电子 驱动程序模块 AT45DB161  部分 |
  6.         +---------------------------------------+
  7.   此源码版权属 振南 全权享有,如欲引用,敬请署名并告知
  8.         严禁随意用于商业目的,违者必究,后果自负
  9.          振南电子
  10.              ->产品网站 http://www.znmcu.cn/
  11.              ->产品网店 http://shop.znmcu.cn/
  12.              ->产品咨询 QQ:987582714
  13.                MSN:yzn07@126.com
  14.                      WW:yzn07
  15.            
  16. ********************************************************/
  17. #include "reg51.h"
  18. //sbit SPI_SI   =P1^5;
  19. //sbit SPI_SCK  =P1^7;
  20. sbit AT45DB161_RESET=P1^0;
  21. sbit AT45DB161_CS   =P0^0;
  22. //sbit SPI_SO   =P1^6;
  23. void AT45DB161_ReadBytes(unsigned int addr,unsigned int start,unsigned int len,unsigned char *pbuf);
  24. void AT45DB161_WriteBytes(unsigned char nbuf,unsigned int addr,unsigned int start,unsigned int len,unsigned char *pbuf);
  25. void AT45DB161_ReadSector(unsigned long addr,unsigned char *pbuf);
  26. void AT45DB161_WriteSector(unsigned long addr,unsigned char *pbuf);
  27. #endif
znmcu 发表于 2009-12-18 15:29 | 显示全部楼层
spi.c


  1. #include "spi.h"

  2. /*******************************************************

  3.         +------------------------------------+
  4.         |  振南电子  驱动程序模块  SPI  部分 |
  5.         +------------------------------------+

  6.   此源码版权属 振南 全权享有,如欲引用,敬请署名并告知
  7.         严禁随意用于商业目的,违者必究,后果自负
  8.          振南电子
  9.              ->产品网站 http://www.znmcu.cn/
  10.              ->产品网店 http://shop.znmcu.cn/
  11.              ->产品咨询 QQ:987582714
  12.                MSN:yzn07@126.com
  13.                      WW:yzn07
  14.            
  15. ********************************************************/

  16. unsigned char bdata dat; //dat是可位寻址的变量

  17. sbit dat7=dat^7;
  18. sbit dat6=dat^6;
  19. sbit dat5=dat^5;
  20. sbit dat4=dat^4;
  21. sbit dat3=dat^3;
  22. sbit dat2=dat^2;
  23. sbit dat1=dat^1;
  24. sbit dat0=dat^0; //取出dat的各个位

  25. /******************************************************************
  26. - 功能描述:IO模拟SPI,发送一个字节
  27. - 隶属模块:SPI模块
  28. - 函数属性:外部,供用户调用
  29. - 参数说明:x:要发送的字节
  30. - 返回说明:无返回
  31. - 注:很多情况下,SPI是需要有较高的速度的,此函数中不使用任何循环
  32.        结构,如for(;;) while等等,并且使用了位寻址就是为了提高速度
  33. ******************************************************************/

  34. void SPI_WriteByte(unsigned char x)
  35. {
  36. dat=x;  //将x赋给可位寻址的dat,这样下面可以直接得到各个位,不需要用位运算,提高效率

  37. SPI_SI=dat7;
  38. SPI_CLK=0;
  39. SPI_CLK=1; //位在时钟的上升沿被写入

  40. SPI_SI=dat6;
  41. SPI_CLK=0;
  42. SPI_CLK=1;

  43. SPI_SI=dat5;
  44. SPI_CLK=0;
  45. SPI_CLK=1;

  46. SPI_SI=dat4;
  47. SPI_CLK=0;
  48. SPI_CLK=1;

  49. SPI_SI=dat3;
  50. SPI_CLK=0;
  51. SPI_CLK=1;

  52. SPI_SI=dat2;
  53. SPI_CLK=0;
  54. SPI_CLK=1;

  55. SPI_SI=dat1;
  56. SPI_CLK=0;
  57. SPI_CLK=1;

  58. SPI_SI=dat0;
  59. SPI_CLK=0;
  60. SPI_CLK=1;
  61. }

  62. /******************************************************************
  63. - 功能描述:IO模拟SPI,读取一个字节
  64. - 隶属模块:SPI模块
  65. - 函数属性:外部,供用户调用
  66. - 参数说明:无
  67. - 返回说明:读到的字节
  68. - 注:很多情况下,SPI是需要有较高的速度的,此函数中不使用任何循环
  69.        结构,如for(;;) while等等,并且使用了位寻址就是为了提高速度
  70. ******************************************************************/

  71. unsigned char SPI_ReadByte()
  72. {  
  73. SPI_SO=1;       //51的IO在作读取时,先将其置高

  74. SPI_CLK=1;
  75. SPI_CLK=0;      //时钟下降沿,从设备的数据输出端(即SPI_SO)产生新数据
  76. dat7=SPI_SO;  //直接把位写到dat的相应位上去,提高效率

  77. SPI_CLK=1;
  78. SPI_CLK=0;
  79. dat6=SPI_SO;

  80. SPI_CLK=1;
  81. SPI_CLK=0;
  82. dat5=SPI_SO;

  83. SPI_CLK=1;
  84. SPI_CLK=0;
  85. dat4=SPI_SO;

  86. SPI_CLK=1;
  87. SPI_CLK=0;
  88. dat3=SPI_SO;

  89. SPI_CLK=1;
  90. SPI_CLK=0;
  91. dat2=SPI_SO;

  92. SPI_CLK=1;
  93. SPI_CLK=0;
  94. dat1=SPI_SO;

  95. SPI_CLK=1;
  96. SPI_CLK=0;
  97. dat0=SPI_SO;

  98. return (dat);
  99. }


spi.h


  1. #ifndef  _SPI_H_
  2. #define  _SPI_H_

  3. /*******************************************************

  4.         +------------------------------------+
  5.         |  振南电子  驱动程序模块  SPI  部分 |
  6.         +------------------------------------+

  7.   此源码版权属 振南 全权享有,如欲引用,敬请署名并告知
  8.         严禁随意用于商业目的,违者必究,后果自负
  9.          振南电子
  10.              ->产品网站 http://www.znmcu.cn/
  11.              ->产品网店 http://shop.znmcu.cn/
  12.              ->产品咨询 QQ:987582714
  13.                MSN:yzn07@126.com
  14.                      WW:yzn07
  15.            
  16. ********************************************************/

  17. #include "reg51.h"

  18. sbit SPI_CLK=P1^7;  //SPI同步时钟  输出
  19. sbit SPI_SI =P1^5;  //SPI同步数据  输出
  20. sbit SPI_SO =P1^6;  //SPI同步数据  输入

  21. void SPI_WriteByte(unsigned char x);
  22. unsigned char SPI_ReadByte();

  23. #endif

main.c


  1. #include
  2. #include "AT45db161.h"
  3. #include "myfun.h"

  4. unsigned char buf[512];

  5. void main(void)
  6. {
  7.   unsigned long i;
  8.    
  9.   for(i=0;i<512;i++)
  10.   {
  11.    buf[i]=i;
  12.   }
  13.   AT45DB161_WriteSector(1000,buf);
  14.   for(i=0;i<512;i++)
  15.   {
  16.    buf[i]=0;
  17.   }  
  18.   AT45DB161_ReadSector(1000,buf);
  19.   for(i=0;i<512;i++)
  20.   {
  21.    P2=~buf[i];
  22.    delay(60000);
  23.   }  
  24.   
  25.   while(1);
  26. }


天地有源 发表于 2009-12-18 17:13 | 显示全部楼层
访问AT45DBXXXX 最好用硬件SPI接口,效率会高很多,用软件模拟SPI,速度是个大问题,因为这种芯片都写都是按page算的.
znmcu 发表于 2009-12-18 19:26 | 显示全部楼层
SPI程序部分是分立出来的,为了程序移植性强一些,可以在spi.c中对SPI进行修改,使用硬件SPI,使用SPI当然是快的。不过有的MCU没有硬件SPI,也就只能用软件的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:上官一出惊天地,   金虹一现震江湖。

35

主题

118

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部
0