Cortex-M3 (NXP LPC1788)之EEPROM存储器

嵌入式系统 时间:2016-11-19来源:网络
EEPROM是一种非易失性存储器,主要用于存储相对少量的数据,如存储一些系统的配置信息。通过系统的EEPROM控制模块可以轻松的进行EERPOM的存储控制。

要正确使用EPPROM需要配置掉电寄存器EEPWRDWN确定EEPROM的工作模式,配置EEPROM时钟分频器寄存器,使EPPROM工作在375KHZ。下面对EPPROM的读和写数据进行介绍。

EEPROM存储器的访问有三种操作方式:读、写、擦除/编程。对EPPROM中写数据分成两个单独的操作:写和擦除/编程。第一步写操作并不是真正把数据写入EPPROM的存储介质中,而只是更新被称作“页寄存器”的临时数据寄存器。只有执行下一步”擦除/编程“操作才会真正地更新非易失存储器。LPC1788共有4K的片内EPPROM,其中EPPROM的每一页等于页寄存器大小为64Byte,总共有64页。大小正好是64*64=4096Byte=4K。首先我们指定的位数,如8、16或者32位,将数据写入页寄存器,页内的地址偏移由EEPROM地址寄存器的第6位决定。如果需要往页寄存器写入一串数据,写完第一个数据后,页内的偏移地址会自动增加,我们只需把要操作的下一个数据填入EEPROM写数据寄存器即可。当页寄存器的64个字节被写满,必须进行编程操作,将数据写入到EEPROM的存储介质。然后更新页寄存器的偏移地址。

对于EEPROM的读操作,首先要向地址寄存器写入一个12位的地址,高6位为页的偏移,即我们需要读哪个页寄存器。低6位为页内的偏移,即我们需要读当前页的哪个字节。读操作也可以自动的对地址寄存器做后递增,这样就可以对EEPROM存储器进行连续的操作而无需每次读数据都写入一个新地址。

下面的程序将信息写入EEPROM后读出通过串口打印显示

  1. #include"LPC1788_REG.h"
  2. #include"uart.h"
  3. #definerEECMD(*(volatileunsigned*)(0x00200080))
  4. #definerEEADDR(*(volatileunsigned*)(0x00200084))
  5. #definerEEWDATA(*(volatileunsigned*)(0x00200088))
  6. #definerEERDATA(*(volatileunsigned*)(0x0020008C))
  7. #definerEEWSTATE(*(volatileunsigned*)(0x00200090))
  8. #definerEECLKDIV(*(volatileunsigned*)(0x00200094))
  9. #definerEEPWRDWN(*(volatileunsigned*)(0x00200098))
  10. #definerEEINTEN(*(volatileunsigned*)(0x00200FE4))
  11. #definerEEINTCLR(*(volatileunsigned*)(0x00200FD8))
  12. #definerEEINTSET(*(volatileunsigned*)(0x00200FDC))
  13. #definerEEINTSTAT(*(volatileunsigned*)(0x00200FE0))
  14. #definerEEINTSTATCLR(*(volatileunsigned*)(0x00200FE8))
  15. #definerEEINTSTATSET(*(volatileunsigned*)(0x00200FEC))
  16. #defineEEPROM_PAGE_SIZE64
  17. voidInit_EEPROM(void);
  18. voidWrite_EEPROM(unsignedcharpage_num,unsignedcharpage_offset,char*data,unsignedintcount);
  19. voidRead_EEPROM(unsignedcharpage_num,unsignedcharpage_offset,char*data,unsignedintcount);
  20. charread_buffer[];
  21. charwrite_buffer[]={"nr
  22. t-Name:Nuncle.leenr
  23. t-QQ:23610603nr
  24. t-Email:nuncle.lee@gmail.comnr"};
  25. intmain(void)
  26. {
  27. Init_Uart2();
  28. Init_EEPROM();
  29. Write_EEPROM(0,0,write_buffer,sizeof(write_buffer));
  30. Write_EEPROM(sizeof(write_buffer)/64,sizeof(write_buffer)%64,,1);
  31. Read_EEPROM(0,0,read_buffer,sizeof(write_buffer)+1);
  32. Uart2SendS(read_buffer);
  33. return0;
  34. }
  35. voidInit_EEPROM(void)
  36. {
  37. unsignedintval=0;
  38. rEEPWRDWN=0;//不处于掉电模式
  39. rEECLKDIV=(CCLK/375000)-1;//设置一个375KHZ的EEPROM时钟
  40. val=((((CCLK/1000000)*15)/1000)+1);//配置等待状态时间
  41. val|=(((((CCLK/1000000)*55)/1000)+1)<<8);
  42. val|=(((((CCLK/1000000)*35)/1000)+1)<<16);
  43. rEEWSTATE=val;
  44. }
  45. voidWrite_EEPROM(unsignedcharpage_num,unsignedcharpage_offset,char*data,unsignedintcount)
  46. {
  47. unsignedinti;
  48. rEEADDR=(page_offset&0x3f);//确定开始写的页内偏移地址
  49. for(i=0;i
  50. {
  51. rEECMD=0x3;//8位写操作
  52. rEEWDATA=*(data+i);
  53. while(!(rEEINTSTAT&(0x1<<26)));//等待写操作完成
  54. page_offset++;
  55. if(page_offset>=EEPROM_PAGE_SIZE)//如果当前页写满了64Byte则启动编程操作
  56. {
  57. rEEINTSTATCLR=0x1<<28;
  58. rEEADDR=(page_num&0x3F)<<6;
  59. rEECMD=0x6;//擦除编程
  60. while(!(rEEINTSTAT&(0x1<<28)));//等待编程完成
  61. page_offset=0;
  62. page_num++;//写满一页,准备写下一页
  63. rEEADDR=0;//写满一页,从页的开始写
  64. }
  65. elseif(i==count-1)//如果要写入EPPROM的数据写完成,启动编程操作
  66. {
  67. rEEINTSTATCLR=0x1<<28;
  68. rEEADDR=(page_num&0x3F)<<6;
  69. rEECMD=0x6;//擦除编程
  70. while(!(rEEINTSTAT&(0x1<<28)));
  71. }
  72. }
  73. }
  74. voidRead_EEPROM(unsignedcharpage_num,unsignedcharpage_offset,char*data,unsignedintcount)
  75. {
  76. unsignedinti;
  77. rEEADDR=(page_num&0x3F)<<6|page_offset&0x3F;//确定读数据的起始位置,包括页偏移和页内的偏移
  78. rEECMD=0x1<<3;//8位读,地址自动递增模式
  79. for(i=0;i
  80. {
  81. while(!(rEEINTSTAT&(0x1<<26)));//等待上一次读数据完成
  82. *(data+i)=rEERDATA;
  83. page_offset++;
  84. if(page_offset>=EEPROM_PAGE_SIZE)//如果当前页64Byte读完,准备读下一页
  85. {
  86. page_offset=0;
  87. page_num++;
  88. rEEADDR=(page_num&0x3F)<<6|page_offset&0x3F;
  89. rEECMD=0x1<<3;
  90. }
  91. }
  92. }

程序的执行结果如下图

程序中,sizeof关键字计算出字符数组的大小,并不包含字符串的结束标志‘’。因此还需在sizeof(write_buffer)的位置写入字符串的结束标志。读取时读sizeof(write_buffer)+1个字节,才能正确的通过串口打印数据。当然,也可以自己指定串口打印字符的个数,而不用字符串结束标志去判断。

关键词: Cortex-M3NXPLPC1788)EEPROM存储

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版