找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

24c256操作函数,连续读写

[复制链接]
慧龙 发表于 2010-5-14 23:44:38 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
24c256的操作,在程序里搞了个连续读写的函数!很烦那页写跨页的问题,所以干脆做了个通用点的函数,小于3字节的写就用随机写,大于3字节的就用页写
真正供其他操作调用的函数是:
unchar SeqWriteTo24c256(unchar sla_add,unint addr_op,unchar write_size,unchar *write_buf);
unchar SeqReadFrom24c256(unchar sla_add,unint addr_op,unchar read_size,unchar *read_buf);
其他的都是本文件内自己调用的函数!!

  1. //*****************************************************调试函数
  2. void DebugEepromService(void)
  3. {
  4. unchar debug_buf[255];
  5. debug_buf[0]=0x91;
  6. debug_buf[1]=0x92;
  7. debug_buf[2]=0x93;
  8. debug_buf[3]=0x94;
  9. debug_buf[4]=0x95;
  10. debug_buf[250]=0x05;
  11. debug_buf[251]=0x06;
  12. debug_buf[252]=0x07;
  13. debug_buf[253]=0x08;
  14. debug_buf[254]=0x09;
  15. SeqWriteTo24c256(EEP1_ADDR,1,255,debug_buf);
  16. SeqReadFrom24c256(EEP1_ADDR,1,255,debug_buf);
  17. }
  18. //*************************************************************



  19. #define IIC_SDA_PB 0x20
  20. #define IIC_SCL_PB 0x80
  21. #define IIC_DEL_WAIT 0x10 //>4.7us(12.80us) for Fre=11.0592M
  22. #define IIC_DEL_WRITE 0x2700 //>6ms(7266.54us=7.266ms) for Fre=11.0592M

  23. #define EEP1_ADDR 0xa4
  24. #define PAGE_CAP_BYTE 64 //24C256页写容量:64字节


  25. /*
  26. 功能函数文件
  27. 2005-9-22 9:54 by xth
  28. 版本: v1.0
  29. --------------------------------------------
  30. Mcu: AVR mega32 Frequency: 11.0592M
  31. --------------------------------------------
  32. 功能概述:Eeprom操作文件
  33. --------------------------------------------
  34. */
  35. //=============================函数声明
  36. //----------IIC操作调用函数
  37. void IicDelayService(unint delay_time);
  38. void IicStartBitSend(void);
  39. void IicStopBitSend(void);
  40. void IicAckService(unchar ack_data);
  41. unchar IicSendByteService(unchar tx_data);
  42. unchar IicAccByteService(void);
  43. //----------At24c256操作函数
  44. unchar RandWriteByteTo24c256(unchar sla_add,unint addr_op,unchar data_op);
  45. unchar WritePageTo24c256(unchar sla_add,unint addr_op,unchar *write_data_buf);
  46. unchar SeqWriteTo24c256ByPage(unchar sla_add,unint addr_op,unchar write_size,unchar *write_buf);
  47. unchar SeqWriteTo24c256(unchar sla_add,unint addr_op,unchar write_size,unchar *write_buf);
  48. unchar SeqReadFrom24c256(unchar sla_add,unint addr_op,unchar read_size,unchar *read_buf);
  49. //=============================函数定义
  50. void IicDelayService(unint delay_count)
  51. {
  52. unint count;
  53. for(count=0;count<delay_count;count++)
  54. asm("NOP");
  55. }

  56. void IicStartBitSend(void)
  57. {
  58. PORTB |= IIC_SCL_PB; //发送起始条件的时钟信号
  59. asm("NOP");
  60. PORTB |= IIC_SDA_PB; //起始条件建立时间大于4.7us,延时
  61. IicDelayService(IIC_DEL_WAIT);
  62. PORTB &= ~IIC_SDA_PB;
  63. IicDelayService(IIC_DEL_WAIT);
  64. PORTB &= ~IIC_SCL_PB; //钳住I2C总线,准备发送或接收数据
  65. asm("NOP");
  66. }

  67. void IicStopBitSend(void)
  68. {
  69. PORTB &= ~IIC_SDA_PB;//发送结束条件的时钟信号
  70. IicDelayService(IIC_DEL_WAIT);
  71. PORTB |= IIC_SCL_PB; //结束条件建立时间大于4μs
  72. IicDelayService(IIC_DEL_WAIT);
  73. PORTB |= IIC_SDA_PB;
  74. asm("NOP");
  75. }

  76. void IicAckService(unchar ack_data)
  77. {//作为主控器件应答->发应答或非应答信号
  78. if(ack_data==0) PORTB &= ~IIC_SDA_PB;
  79. else PORTB |= IIC_SDA_PB;
  80. IicDelayService(IIC_DEL_WAIT);
  81. PORTB |= IIC_SCL_PB;
  82. IicDelayService(IIC_DEL_WAIT);
  83. PORTB &= ~IIC_SCL_PB;//清时钟线,钳住I2C总线以便继续接收
  84. asm("NOP");
  85. }

  86. unchar IicSendByteService(unchar tx_data)
  87. {//将字节发送出去,可以是地址,也可以是数据,发完后等待应答并返回
  88. unchar bit_count,ack_flag;
  89. for(bit_count=0;bit_count<8;bit_count++)
  90. {
  91. if((tx_data<<bit_count)&0x80)
  92. PORTB |= IIC_SDA_PB;
  93. else
  94. PORTB &= ~IIC_SDA_PB;
  95. IicDelayService(IIC_DEL_WAIT);
  96. PORTB |= IIC_SCL_PB; //置时钟线为高,通知被控器开始接收数据位
  97. IicDelayService(IIC_DEL_WAIT); //保证时钟高电平周期大于4μs
  98. PORTB &= ~IIC_SCL_PB;
  99. }
  100. IicDelayService(IIC_DEL_WAIT);
  101. PORTB &= ~IIC_SDA_PB;
  102. DDRB &= ~IIC_SDA_PB; //SDA置成输入
  103. asm("NOP");
  104. PORTB |= IIC_SCL_PB;
  105. IicDelayService(IIC_DEL_WAIT);
  106. IicDelayService(IIC_DEL_WAIT);
  107. if(PINB&IIC_SDA_PB) //判断是否接收到应答信号
  108. ack_flag=NO;
  109. else
  110. ack_flag=YES; //有应答信号
  111. DDRB |= IIC_SDA_PB;
  112. PORTB &= ~IIC_SCL_PB;
  113. asm("NOP");
  114. return(ack_flag);
  115. }

  116. unchar IicAccByteService(void)
  117. {//接收从器件传来的数据,并判断总线错误
  118. unchar bit_count,get_data;
  119. DDRB &= ~IIC_SDA_PB;
  120. get_data=0;
  121. for(bit_count=0;bit_count<8;bit_count++)
  122. {
  123. asm("NOP");
  124. PORTB &= ~IIC_SCL_PB; //置时钟线为低,准备接收数据位
  125. IicDelayService(IIC_DEL_WAIT); //时钟低电平周期大于4.7μs;
  126. PORTB |= IIC_SCL_PB; //置时钟线为高使数据线上数据有效
  127. get_data<<=1;
  128. if(PINB&IIC_SDA_PB)
  129. get_data++;
  130. asm("NOP");
  131. asm("NOP");
  132. }
  133. PORTB &= ~IIC_SCL_PB;
  134. DDRB |= IIC_SDA_PB;
  135. asm("NOP");
  136. return(get_data);
  137. }

  138. unchar RandWriteByteTo24c256(unchar sla_add,unint addr_op,unchar data_op)
  139. {
  140. unchar result_now,temp_data;
  141. IicStartBitSend(); //起始条件
  142. temp_data=sla_add; //从器件地址
  143. result_now=IicSendByteService(temp_data);
  144. if(result_now==NO) return(result_now);
  145. temp_data=addr_op>>8; //操作单元地址高8位
  146. result_now=IicSendByteService(temp_data);
  147. if(result_now==NO) return(result_now);
  148. temp_data=addr_op; //操作单元地址低8位
  149. result_now=IicSendByteService(temp_data);
  150. if(result_now==NO) return(result_now);
  151. temp_data=data_op; //操作数据
  152. result_now=IicSendByteService(temp_data);
  153. if(result_now==NO) return(result_now);
  154. IicStopBitSend(); //停止条件
  155. IicDelayService(IIC_DEL_WRITE);
  156. result_now=YES;
  157. return(result_now);
  158. }

  159. unchar SeqReadFrom24c256(unchar sla_add,unint addr_op,unchar read_size,unchar *read_buf)
  160. {//addr “roll over” during read:from last byte of the last page, to the first byte of the first page
  161. unchar result_now,temp_data,read_count;
  162. IicStartBitSend(); //起始条件
  163. temp_data=sla_add; //从器件地址
  164. result_now=IicSendByteService(temp_data);
  165. if(result_now==NO) return(result_now);
  166. temp_data=addr_op>>8; //操作单元地址高8位
  167. result_now=IicSendByteService(temp_data);
  168. if(result_now==NO) return(result_now);
  169. temp_data=addr_op; //操作单元地址低8位
  170. result_now=IicSendByteService(temp_data);
  171. if(result_now==NO) return(result_now);
  172. IicStartBitSend();
  173. temp_data=sla_add+1; //读操作
  174. result_now=IicSendByteService(temp_data);
  175. if(result_now==NO) return(result_now);
  176. for(read_count=0;read_count<read_size-1;read_count++)
  177. { //连续读数据
  178. *(read_buf+read_count)=IicAccByteService();
  179. IicAckService(NO);
  180. }
  181. *(read_buf+read_count)=IicAccByteService();
  182. IicAckService(YES);
  183. IicStopBitSend();
  184. result_now=YES;
  185. return(result_now);
  186. }

  187. unchar WritePageTo24c256(unchar sla_add,unint addr_op,unchar *write_data_buf)
  188. {//页写
  189. unchar count,result_now,temp_data;
  190. IicStartBitSend(); //起始条件
  191. temp_data=sla_add; //从器件地址
  192. result_now=IicSendByteService(temp_data);
  193. if(result_now==NO) return(result_now);
  194. temp_data=addr_op>>8; //操作单元地址高8位
  195. result_now=IicSendByteService(temp_data);
  196. if(result_now==NO) return(result_now);
  197. temp_data=addr_op; //操作单元地址低8位
  198. result_now=IicSendByteService(temp_data);
  199. if(result_now==NO) return(result_now);
  200. for(count=0;count<PAGE_CAP_BYTE;count++)
  201. {//连续写
  202. temp_data=*(write_data_buf+count);
  203. result_now=IicSendByteService(temp_data);
  204. if(result_now==NO) return(result_now);
  205. }
  206. IicStopBitSend(); //停止条件
  207. IicDelayService(IIC_DEL_WRITE);
  208. result_now=YES;
  209. return(result_now);
  210. }

  211. unchar SeqWriteTo24c256ByPage(unchar sla_add,unint addr_op,unchar write_size,unchar *write_buf)
  212. {//addr “roll over” during write:from last byte of the current page to first byte of the same page.
  213. unint page_write,read_addr,temp_op_int;
  214. unchar data_count,result_out,modify_count,count,write_data_buf[PAGE_CAP_BYTE];
  215. result_out=YES;
  216. data_count=0;
  217. while(write_size>0)
  218. {
  219. page_write=addr_op/PAGE_CAP_BYTE; //得到当前页
  220. read_addr=page_write*PAGE_CAP_BYTE;
  221. SeqReadFrom24c256(sla_add,read_addr,PAGE_CAP_BYTE,write_data_buf);
  222. temp_op_int=addr_op&(PAGE_CAP_BYTE-1); //得到在页内的起始字节地址
  223. if(temp_op_int+write_size>=PAGE_CAP_BYTE)
  224. {
  225. modify_count=PAGE_CAP_BYTE;
  226. addr_op=(page_write+1)*PAGE_CAP_BYTE; //写下一页的起始地址
  227. }
  228. else
  229. modify_count=write_size;
  230. count=temp_op_int;
  231. write_size=write_size-modify_count+count; //写下一页的数据量
  232. for(;count<modify_count;count++,data_count++)
  233. write_data_buf[count]=*(write_buf+data_count);
  234. result_out=WritePageTo24c256(sla_add,read_addr,write_data_buf);
  235. }
  236. return(result_out);
  237. }

  238. unchar SeqWriteTo24c256(unchar sla_add,unint addr_op,unchar write_size,unchar *write_buf)
  239. {//连续写(非页写)
  240. unchar write_result;
  241. if(write_size<3)
  242. {//如果要写入的数据小于3个,则用随机写实现
  243. write_result=RandWriteByteTo24c256(sla_add,addr_op,*write_buf);
  244. write_result=RandWriteByteTo24c256(sla_add,addr_op+1,*(write_buf+1));
  245. }
  246. else
  247. write_result=SeqWriteTo24c256ByPage(sla_add,addr_op,write_size,write_buf);
  248. return(write_result);
  249. }
复制代码
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-11-23 06:29 , Processed in 0.049310 second(s), 8 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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