AT24C128.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. #include "includes.h"
  2. #include "AT24C128.h"
  3. #include "stdio.h"
  4. //#include "sys.h"
  5. #include "delay.h"
  6. //#include "sys.h"
  7. /* AT24C128C organized as 256 pages of 64-bytes each
  8. AT24C512C, organized as 512 pages of 128 bytes each
  9. 不同的的EEPROM对应的页大小不一样,注意修改
  10. */
  11. #define PAGE_SIZE 64
  12. void I2C_init(void)
  13. {
  14. GPIO_InitTypeDef GPIO_InitStructure = {0};
  15. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能GPIOB时钟
  16. //解除写保护
  17. GPIO_InitStructure.GPIO_Pin = IIC_WP_PIN;
  18. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//
  19. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//2MHz
  20. GPIO_Init(IIC_WP_PORT, &GPIO_InitStructure);
  21. //解除写保护
  22. // GPIO_ResetBits(IIC_WP_PORT,IIC_WP_PIN);
  23. //打开写保护
  24. GPIO_SetBits(IIC_WP_PORT,IIC_WP_PIN);
  25. //IIC时钟信号位
  26. GPIO_InitStructure.GPIO_Pin = IIC_SCL_PIN;
  27. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
  28. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
  29. GPIO_SetBits(IIC_SCL_PORT,IIC_SCL_PIN);
  30. GPIO_Init(IIC_SCL_PORT, &GPIO_InitStructure);//初始化
  31. //IIC数据信号位
  32. GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;
  33. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//OD
  34. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
  35. GPIO_SetBits(IIC_SDA_PORT,IIC_SDA_PIN);
  36. GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure);//初始化
  37. }
  38. u8 iic_cmd_delay=0;
  39. /***********************iic**************************/
  40. void delay_nop(void)
  41. {
  42. unsigned int i;
  43. for(i=0;i<50;i++)
  44. __nop();
  45. }
  46. //产生IIC起始信号
  47. void IIC_Start(void)
  48. {
  49. /*while(iic_cmd_delay < E_DELAY) // 距上一个命令时间太短
  50. {
  51. R_WDT_Restart();
  52. }*/
  53. SDA_OUT();//sda线输出
  54. IIC_SDA = 1;
  55. IIC_SCL = 1;
  56. delay_us(4);
  57. IIC_SDA = 0;//START:when CLK is high,DATA change form high to low
  58. delay_us(4);
  59. IIC_SCL = 0;//钳住I2C总线,准备发送或接收数据
  60. }
  61. //产生IIC停止信号
  62. void IIC_Stop(void)
  63. {
  64. SDA_OUT();//sda线输出
  65. IIC_SDA = 0;
  66. IIC_SCL = 0;
  67. delay_us(4);
  68. IIC_SCL = 1;
  69. delay_us(4);
  70. IIC_SDA = 1;//发送I2C总线结束信号
  71. delay_us(4);
  72. iic_cmd_delay=0;
  73. }
  74. //等待应答信号到来
  75. //返回值:
  76. // 1,接收应答失败
  77. // 0,接收应答成功
  78. u8 IIC_Wait_Ack(void)
  79. {
  80. u8 ucErrTime=0;
  81. SDA_IN(); //SDA设置为输入
  82. IIC_SDA=1;delay_us(1);
  83. IIC_SCL=1;delay_us(1);
  84. while(READ_SDA)
  85. {
  86. ucErrTime++;
  87. if(ucErrTime>250)
  88. {
  89. IIC_Stop();
  90. return 1;
  91. }
  92. }
  93. IIC_SCL=0;//时钟输出0
  94. return 0;
  95. }
  96. //产生ACK应答
  97. void IIC_Ack(void)
  98. {
  99. IIC_SCL = 0;
  100. SDA_OUT();//sda线输出
  101. IIC_SDA = 0;
  102. delay_us(4);
  103. IIC_SCL = 1;
  104. delay_us(2);
  105. IIC_SCL = 0;
  106. }
  107. //不产生ACK应答
  108. void IIC_NAck(void)
  109. {
  110. IIC_SCL = 0;
  111. SDA_OUT();//sda线输出
  112. IIC_SDA = 1;
  113. delay_us(4);
  114. IIC_SCL = 1;
  115. delay_us(2);
  116. IIC_SCL = 0;
  117. }
  118. //IIC发送一个字节
  119. //返回从机有无应答
  120. //1,有应答
  121. //0,无应答
  122. void IIC_Send_Byte(u8 txd)
  123. {
  124. u8 t;
  125. IIC_SCL=0;//拉低时钟开始数据传输
  126. SDA_OUT();
  127. for(t=0;t<8;t++)
  128. {
  129. IIC_SDA=(txd&0x80)>>7;
  130. // SDA_OUT();
  131. // if((txd&0x80)>>7)
  132. // IIC_SDA=1;
  133. // else
  134. // IIC_SDA=0;
  135. txd<<=1;
  136. delay_us(4); //对TEA5767这三个延时都是必须的
  137. IIC_SCL=1;
  138. delay_us(2);
  139. IIC_SCL=0;
  140. delay_us(2);
  141. }
  142. }
  143. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  144. u8 IIC_Read_Byte(u8 ack)
  145. {
  146. u8 i,receive=0;
  147. SDA_IN();//SDA设置为输入
  148. for(i=0;i<8;i++ )
  149. {
  150. IIC_SCL=0;
  151. delay_us(4);
  152. IIC_SCL=1;
  153. receive<<=1;
  154. if(READ_SDA)receive++;
  155. delay_us(1);
  156. }
  157. if (!ack)
  158. IIC_NAck();//发送nACK
  159. else
  160. IIC_Ack(); //发送ACK
  161. return receive;
  162. }
  163. /***********************以上为IIC驱动**************************/
  164. /***********************iic**************************/
  165. //在AT24CXX指定地址读出一个数据
  166. //ReadAddr:开始读数的地址
  167. //返回值 :读到的数据
  168. u8 AT24CXX_ReadOneByte(u32 ReadAddr)
  169. {
  170. u8 temp;
  171. u8 addrH,addrL;
  172. addrH=ReadAddr>>8;
  173. addrL=ReadAddr&0xff;
  174. IIC_Start();
  175. IIC_Send_Byte(0xa0);
  176. IIC_Wait_Ack();
  177. IIC_Send_Byte(addrH); //发送高地址
  178. IIC_Wait_Ack();
  179. IIC_Send_Byte(addrL); //发送低地址
  180. IIC_Wait_Ack();
  181. IIC_Start();
  182. IIC_Send_Byte(0xa1); //进入接收模式
  183. IIC_Wait_Ack();
  184. temp= IIC_Read_Byte(0);
  185. IIC_Stop();//产生一个停止条件
  186. delay_us(4);
  187. return temp;
  188. }
  189. //在AT24CXX指定地址写入一个数据
  190. //WriteAddr :写入数据的目的地址
  191. //DataToWrite:要写入的数据
  192. void AT24CXX_WriteOneByte(u32 WriteAddr,u8 DataToWrite)
  193. {
  194. u8 addrH,addrL;
  195. addrH=WriteAddr>>8;
  196. addrL=WriteAddr&0xff;
  197. IIC_Start();
  198. IIC_Send_Byte(0xa0);
  199. IIC_Wait_Ack();
  200. IIC_Send_Byte(addrH); //发送高地址
  201. IIC_Wait_Ack();
  202. IIC_Send_Byte(addrL); //发送低地址
  203. IIC_Wait_Ack();
  204. IIC_Send_Byte(DataToWrite); //发送字节
  205. IIC_Wait_Ack();
  206. IIC_Stop();//产生一个停止条件
  207. delay_ms(10);//两次写操作,必须加间隔,否则写不进去
  208. }
  209. //在AT24CXX里面的指定地址开始读出指定个数的数据
  210. //ReadAddr :开始读出的地址 对24c02为0~255
  211. //pBuffer :数据数组首地址
  212. //NumToRead:要读出数据的个数
  213. void AT24CXX_Read(u32 ReadAddr,u8 *pBuffer,u16 NumToRead)
  214. {
  215. u8 addrH,addrL;
  216. u16 lentmp,lentow,lens;
  217. u8 tmp;
  218. if(NumToRead==0)
  219. return;
  220. lentmp=NumToRead;
  221. while(lentmp)
  222. {
  223. tmp=ReadAddr%PAGE_SIZE;
  224. tmp=PAGE_SIZE-tmp;
  225. if(tmp>=lentmp)//当页剩余空间大于要写入的长度
  226. {
  227. lentow=lentmp;
  228. }
  229. else
  230. {
  231. lentow=tmp;//写入长度只能是剩余空间长度
  232. }
  233. lentmp=lentmp-lentow;//计算要在下一页写入的长度
  234. lens=lentow;
  235. addrH=ReadAddr>>8;
  236. addrL=ReadAddr&0xff;
  237. IIC_Start();
  238. IIC_Send_Byte(0xa0);//写
  239. IIC_Wait_Ack();
  240. IIC_Send_Byte(addrH); //发送高地址
  241. IIC_Wait_Ack();
  242. IIC_Send_Byte(addrL); //发送低地址
  243. IIC_Wait_Ack();
  244. delay_us(4);
  245. IIC_Start();
  246. IIC_Send_Byte(0xa1); //读 //进入接收模式
  247. IIC_Wait_Ack();
  248. while(lentow)
  249. {
  250. *pBuffer=IIC_Read_Byte(1);
  251. pBuffer++;
  252. //ReadAddr++;
  253. lentow--;
  254. }
  255. IIC_Read_Byte(0);
  256. IIC_Stop();//产生一个停止条件
  257. delay_us(4);
  258. //printf("at24 read %d %d\r\n", ReadAddr, lens);
  259. ReadAddr=ReadAddr+lens;//下一页的地址
  260. }
  261. }
  262. //在AT24CXX里面的指定地址开始写入指定个数的数据
  263. //WriteAddr :开始写入的地址 对24c02为0~255
  264. //pBuffer :数据数组首地址
  265. //NumToWrite:要写入数据的个数
  266. // 每128bytes为一个page,写操作不能跨页
  267. void AT24CXX_Write(u32 WriteAddr,u8 *pBuffer,u16 NumToWrite)
  268. {
  269. OS_ERR err;
  270. u8 addrH,addrL;
  271. u16 lentmp,lentow,lens;
  272. u8 tmp;
  273. //关闭写保护
  274. IIC_WRITE_PROTECT_DISABLE();
  275. if(NumToWrite==0)
  276. return;
  277. lentmp=NumToWrite;
  278. while(lentmp)
  279. {
  280. tmp=WriteAddr%PAGE_SIZE;
  281. tmp=PAGE_SIZE-tmp;
  282. if(tmp>=lentmp)//当页剩余空间大于要写入的长度
  283. {
  284. lentow=lentmp;
  285. }
  286. else
  287. {
  288. lentow=tmp;//写入长度只能是剩余空间长度
  289. }
  290. lentmp=lentmp-lentow;//计算要在下一页写入的长度
  291. lens=lentow;
  292. addrH=WriteAddr>>8;
  293. addrL=WriteAddr&0xff;
  294. IIC_Start();
  295. IIC_Send_Byte(0xa0);
  296. IIC_Wait_Ack();
  297. IIC_Send_Byte(addrH); //发送高地址
  298. IIC_Wait_Ack();
  299. IIC_Send_Byte(addrL); //发送低地址
  300. IIC_Wait_Ack();
  301. while(lentow--)
  302. {
  303. IIC_Send_Byte(*pBuffer);
  304. IIC_Wait_Ack();
  305. pBuffer++;
  306. }
  307. IIC_Stop();//产生一个停止条件
  308. // delay_ms(10);
  309. OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_DLY, &err);
  310. //printf("at24 write %d %d %d, %d\r\n", WriteAddr, lens, addrH, addrL);
  311. WriteAddr=WriteAddr+lens;//下一页的地址
  312. }
  313. //打开写保护
  314. IIC_WRITE_PROTECT_ENABLE();
  315. // delay_ms(10);//两次写操作,必须加间隔,否则写不进去
  316. OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_DLY, &err);
  317. }
  318. void AT24CXX_clr(u32 WriteAddr,u32 NumToWrite)
  319. {
  320. u8 addrH,addrL;
  321. u16 lentmp,lentow,lens;
  322. u8 tmp;
  323. lentmp=NumToWrite;
  324. while(lentmp)
  325. {
  326. tmp=WriteAddr%PAGE_SIZE;
  327. tmp=PAGE_SIZE-tmp;
  328. if(tmp>=lentmp)
  329. {
  330. lentow=lentmp;
  331. }
  332. else
  333. {
  334. lentow=tmp;
  335. }
  336. lentmp=lentmp-lentow;
  337. lens=lentow;
  338. addrH=WriteAddr>>8;
  339. addrL=WriteAddr&0xff;
  340. IIC_Start();
  341. IIC_Send_Byte(0xa0);
  342. IIC_Wait_Ack();
  343. IIC_Send_Byte(addrH); //发送高地址
  344. IIC_Wait_Ack();
  345. IIC_Send_Byte(addrL); //发送低地址
  346. IIC_Wait_Ack();
  347. while(lentow--)
  348. {
  349. IIC_Send_Byte(0xff);
  350. IIC_Wait_Ack();
  351. }
  352. IIC_Stop();//产生一个停止条件
  353. delay_ms(10);
  354. WriteAddr=WriteAddr+lens;
  355. }
  356. delay_ms(10);
  357. }
  358. //----------------------EEPROM---------------------------//
  359. //--------------------------------------------------------EEPROM DATA
  360. /*********************************************END OF FILE**********************/
  361. #define I2C_DATA_LEN 256
  362. u8 I2c_Buf_Write[I2C_DATA_LEN], I2c_Buf_Read[I2C_DATA_LEN];
  363. /**
  364. * @brief I2C(AT24C02)读写测试
  365. * @param 无
  366. * @retval 正常返回 1 ,不正常返回 0
  367. */
  368. uint8_t I2C_Test(void)
  369. {
  370. u16 i;
  371. I2C_init();
  372. EEPROM_INFO("\r\nI2C(AT24C128)字节读写测试\r\n");
  373. memset(I2c_Buf_Write, 0, I2C_DATA_LEN);
  374. memset(I2c_Buf_Read, 0, I2C_DATA_LEN);
  375. for ( i=0; i< I2C_DATA_LEN; i++ ) //填充缓冲
  376. {
  377. I2c_Buf_Write[i] = i;
  378. AT24CXX_WriteOneByte(i, i);
  379. I2c_Buf_Read[i] = AT24CXX_ReadOneByte(i);
  380. }
  381. data_dump("I2C Write", I2c_Buf_Write, I2C_DATA_LEN);
  382. data_dump("I2C Read", I2c_Buf_Read, I2C_DATA_LEN);
  383. EEPROM_INFO("\r\nI2C(AT24C128)连续地址读写测试\r\n");
  384. memset(I2c_Buf_Write, 0, I2C_DATA_LEN);
  385. memset(I2c_Buf_Read, 0, I2C_DATA_LEN);
  386. for ( i=0; i< I2C_DATA_LEN; i++ ) //填充缓冲
  387. {
  388. I2c_Buf_Write[i] = i+100;
  389. }
  390. AT24CXX_clr(I2C_DATA_LEN, I2C_DATA_LEN);
  391. AT24CXX_Read(I2C_DATA_LEN, I2c_Buf_Read, I2C_DATA_LEN);
  392. data_dump("I2C Read", I2c_Buf_Read, I2C_DATA_LEN);
  393. AT24CXX_Write(I2C_DATA_LEN, I2c_Buf_Write, I2C_DATA_LEN);
  394. AT24CXX_Read(I2C_DATA_LEN, I2c_Buf_Read, I2C_DATA_LEN);
  395. data_dump("I2C Write", I2c_Buf_Write, I2C_DATA_LEN);
  396. data_dump("I2C Read", I2c_Buf_Read, I2C_DATA_LEN);
  397. EEPROM_INFO("\r\nI2C(AT24C128)读写测试成功\r\n");
  398. return 1;
  399. }
  400. void Tmp75_read(u8 *pBuffer)
  401. {
  402. u16 lentow;
  403. lentow = 2;
  404. IIC_Start();
  405. IIC_Send_Byte(0x90);//写
  406. IIC_Wait_Ack();
  407. IIC_Send_Byte(0x00); //发送寄存器地址
  408. IIC_Wait_Ack();
  409. delay_us(4);
  410. IIC_Start();
  411. IIC_Send_Byte(0x91); //读 //进入接收模式
  412. IIC_Wait_Ack();
  413. while(lentow)
  414. {
  415. *pBuffer=IIC_Read_Byte(1);
  416. pBuffer++;
  417. //ReadAddr++;
  418. lentow--;
  419. }
  420. IIC_Stop();//产生一个停止条件
  421. }
  422. u8 Temp_buf[4];
  423. float Temp_test(void)
  424. {
  425. float temp_data,tmp;
  426. I2C_init();
  427. Tmp75_read(Temp_buf);
  428. //data_dump("temp Read", Temp_buf, 2);
  429. // printf("\ntemp Read ");
  430. // printf("%d ",Temp_buf[0]);
  431. // printf("%d \n",Temp_buf[1]);
  432. tmp = (float)(Temp_buf[1]>>4);
  433. tmp /= 16.0;
  434. temp_data = (float)Temp_buf[0] + tmp;
  435. // printf("\ntemp Read ");
  436. // printf("%f\n",temp_data);
  437. return temp_data;
  438. }