epprom.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*--------------------------------------------------
  2. * 用的芯片是AT24C128
  3. * 一共256页,每页64个字节
  4. * -------------------------------------------------*/
  5. #include "epprom.h"
  6. #include "I2C.h"
  7. #include "timeout.h"
  8. /*--------------------------------------------------------
  9. * 在AT24CXX里面的指定地址开始读出指定个数的数据
  10. * ReadAddr :开始读出的地址 对24c02为0~255
  11. *pBuffer :数据数组首地址
  12. *NumToRead:要读出数据的个数
  13. * --------------------------------------------------------*/
  14. void epprom_read(uint32_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead)
  15. {
  16. uint8_t addrH,addrL;
  17. uint16_t lentmp,lentow,lens;
  18. uint8_t tmp;
  19. if(NumToRead==0) return;
  20. // i2c_init();
  21. __set_PRIMASK(1);//关总中断
  22. delay_ms(100);//两次写操作,必须加间隔,否则写不进去
  23. //fwdgt_feed();
  24. lentmp=NumToRead;
  25. while(lentmp)
  26. {
  27. tmp=ReadAddr%PAGE_SIZE_EPPROM;
  28. tmp=PAGE_SIZE_EPPROM-tmp;
  29. if(tmp>=lentmp)//当页剩余空间大于要写入的长度
  30. {
  31. lentow=lentmp;
  32. }
  33. else
  34. {
  35. lentow=tmp;//写入长度只能是剩余空间长度
  36. }
  37. lentmp=lentmp-lentow;//计算要在下一页写入的长度
  38. lens=lentow;
  39. addrH=ReadAddr>>8;
  40. addrL=ReadAddr&0xff;
  41. i2c_start();
  42. i2c_send_byte(0xa0);//写
  43. i2c_wait_ack();
  44. i2c_send_byte(addrH); //发送高地址
  45. i2c_wait_ack();
  46. i2c_send_byte(addrL); //发送低地址
  47. i2c_wait_ack();
  48. delay_us(4);
  49. i2c_start();
  50. i2c_send_byte(0xa1); //读 //进入接收模式
  51. i2c_wait_ack();
  52. while(lentow)
  53. {
  54. *pBuffer=i2c_read_byte(1);
  55. pBuffer++;
  56. //ReadAddr++;
  57. lentow--;
  58. }
  59. i2c_read_byte(0);
  60. i2c_stop();//产生一个停止条件
  61. delay_us(4);
  62. //printf("at24 read %d %d\r\n", ReadAddr, lens);
  63. ReadAddr=ReadAddr+lens;//下一页的地址
  64. }
  65. //IIC_WRITE_PROTECT_ON(); // 写保护打开
  66. __set_PRIMASK(0);//开总中断
  67. }
  68. /*---------------------------------------------------------
  69. * 在AT24CXX里面的指定地址开始写入指定个数的数据
  70. * WriteAddr :开始写入的地址 对24c02为0~255
  71. * pBuffer :数据数组首地址
  72. * NumToWrite:要写入数据的个数
  73. * 每64bytes为一个page,
  74. * --------------------------------------------------------*/
  75. void epprom_write(uint32_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite)
  76. {
  77. uint8_t addrH,addrL;
  78. uint16_t lentmp,lentow,lens;
  79. uint8_t tmp;
  80. // rt_err_t err;
  81. if(NumToWrite==0) return;
  82. // i2c_init();
  83. IIC_WRITE_PROTECT_OFF(); // 写保护关闭
  84. __set_PRIMASK(1);//关总中断
  85. delay_ms(10);//两次写操作,必须加间隔,否则写不进去
  86. //fwdgt_feed();
  87. lentmp=NumToWrite;
  88. while(lentmp)
  89. {
  90. tmp=WriteAddr%PAGE_SIZE_EPPROM;
  91. tmp=PAGE_SIZE_EPPROM-tmp;
  92. if(tmp>=lentmp)//当页剩余空间大于要写入的长度
  93. {
  94. lentow=lentmp;
  95. }
  96. else
  97. {
  98. lentow=tmp;//写入长度只能是剩余空间长度
  99. }
  100. lentmp=lentmp-lentow;//计算要在下一页写入的长度
  101. lens=lentow;
  102. addrH=WriteAddr>>8;
  103. addrL=WriteAddr&0xff;
  104. i2c_start();
  105. i2c_send_byte(0xa0);
  106. i2c_wait_ack();
  107. i2c_send_byte(addrH); //发送高地址
  108. i2c_wait_ack();
  109. i2c_send_byte(addrL); //发送低地址
  110. i2c_wait_ack();
  111. while(lentow--)
  112. {
  113. i2c_send_byte(*pBuffer);
  114. i2c_wait_ack();
  115. pBuffer++;
  116. }
  117. i2c_stop();//产生一个停止条件
  118. delay_ms(10);
  119. WriteAddr=WriteAddr+lens;//下一页的地址
  120. }
  121. delay_ms(10);//两次写操作,必须加间隔,否则写不进去
  122. IIC_WRITE_PROTECT_ON(); // 写保护使能打开
  123. __set_PRIMASK(0);//开总中断
  124. }
  125. void epprom_test(void)
  126. {
  127. uint8_t i = 0,vale=0;
  128. for(i=1;i<128;i++){
  129. epprom_write(640+i,&i,1);
  130. }
  131. for(i=1;i<128;i++){
  132. vale = 0;
  133. epprom_read(640+i,&vale,1);
  134. printf("i = %d,val = %d\r\n",i,vale);
  135. }
  136. }