找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2742|回复: 0
打印 上一主题 下一主题
收起左侧

51单片机与24CXX通信的C程序

[复制链接]
跳转到指定楼层
楼主
ID:71259 发表于 2014-12-30 00:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. /******************************************************************************************
  2. 端口定义
  3. ****************************************************************************************/
  4. sbit SCL=P2^1;         //将串行时钟总线SCL位定义在为P3.4引脚
  5. sbit SDA=P2^0;          //将串行数据总线SDA位定义在为P3.5引脚

  6. #define OP_READ 0xa1  // 器件地址以及读取操作,0xa1即为1010 0001B
  7. #define OP_WRITE 0xa0  // 器件地址以及写入操作,0xa1即为1010 0000B

  8. /******************************************************************************************
  9. * 函数名称    :Start
  10. * 功能描述    : 启动I2C总线
  11. * 参数        : 无
  12. * 返回值      : 无
  13. * 创建日期    :2010-11-25
  14. * 作者        :zzj
  15. * 全局变量    :
  16. * 全局静态变量:
  17. * 局部静态变量:
  18. *----------------------------------------修改历史------------------------------------------
  19. * 当前版本    :     修改人:                  修改日期:
  20. * 修改说明    :
  21. ******************************************************************************************/
  22. void Start()
  23. {
  24. SDA = 1;    //SDA初始化为高电平“1”
  25.     SCL = 1;    //开始数据传送时,要求SCL为高电平“1”
  26. _nop_();     //等待一个机器周期
  27. _nop_();     //等待一个机器周期
  28. _nop_();     //等待一个机器周期
  29. _nop_();     //等待一个机器周期
  30. _nop_();     //等待一个机器周期
  31. SDA = 0;    //SDA的下降沿被认为是开始信号
  32. _nop_();     //等待一个机器周期
  33. _nop_();     //等待一个机器周期
  34. _nop_();     //等待一个机器周期
  35. _nop_();     //等待一个机器周期
  36. _nop_();     //等待一个机器周期
  37. SCL = 0;    //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
  38. }
  39. /******************************************************************************************
  40. * 函数名称    :Stop
  41. * 功能描述    : 结束I2C总线
  42. * 参数        : 无
  43. * 返回值      : 无
  44. * 创建日期    :2010-11-25
  45. * 作者        :zzj
  46. * 全局变量    :
  47. * 全局静态变量:
  48. * 局部静态变量:
  49. *----------------------------------------修改历史------------------------------------------
  50. * 当前版本    :     修改人:                  修改日期:
  51. * 修改说明    :
  52. ******************************************************************************************/
  53. void Stop()// 停止位
  54. {
  55. SDA = 0;     //SDA初始化为低电平“0” _n
  56. SCL = 1;     //结束数据传送时,要求SCL为高电平“1”
  57. _nop_();     //等待一个机器周期
  58. _nop_();     //等待一个机器周期
  59. _nop_();     //等待一个机器周期
  60. _nop_();     //等待一个机器周期
  61. _nop_();     //等待一个机器周期
  62. SDA = 1;    //SDA的上升沿被认为是结束信号
  63. _nop_();     //等待一个机器周期
  64. _nop_();     //等待一个机器周期
  65. _nop_();     //等待一个机器周期
  66. _nop_();     //等待一个机器周期
  67. _nop_();     //等待一个机器周期
  68. SDA=0;
  69. SCL=0;
  70. }
  71. /******************************************************************************************
  72. * 函数名称    :TeskAsk
  73. * 功能描述    : 检测应答位
  74. * 参数        : 无
  75. * 返回值      : 无
  76. * 创建日期    :2010-11-25
  77. * 作者        :zzj
  78. * 全局变量    :
  79. * 全局静态变量:
  80. * 局部静态变量:
  81. *----------------------------------------修改历史------------------------------------------
  82. * 当前版本    :     修改人:                  修改日期:
  83. * 修改说明    :
  84. ******************************************************************************************/
  85. void TestAsk()               
  86. {
  87.     bit ack_bit;        //储存应答位
  88.     SDA = 1;  // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线,
  89.                  //以让SDA线转由接收设备(AT24Cxx)控制
  90. _nop_();        //等待一个机器周期
  91. _nop_();        //等待一个机器周期
  92. SCL = 1;       //根据上述规定,SCL应为高电平
  93. _nop_();       //等待一个机器周期
  94. _nop_();       //等待一个机器周期
  95. _nop_();       //等待一个机器周期
  96. _nop_();       //等待一个机器周期
  97. _nop_();       //等待一个机器周期
  98. ack_bit = SDA; //接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节
  99.                 //若送高电平,表示没有接收到,传送异常 结束发送
  100. SCL = 0;       //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
  101. while(ack_bit!=0);
  102. }
  103. /******************************************************************************************
  104. * 函数名称    :SendAsk
  105. * 功能描述    :发送应答位
  106. * 参数        : 无
  107. * 返回值      : 无
  108. * 创建日期    :2010-11-25
  109. * 作者        :zzj
  110. * 全局变量    :
  111. * 全局静态变量:
  112. * 局部静态变量:
  113. *----------------------------------------修改历史------------------------------------------
  114. * 当前版本    :     修改人:                  修改日期:
  115. * 修改说明    :
  116. ******************************************************************************************/
  117. void SendAsk()
  118. {
  119.   SCL=0;
  120.   _nop_();
  121.   _nop_();     
  122.   SDA=0;    //将SDA拉低并持续4.5us以上
  123.    SCL=1;  
  124.    
  125. _nop_();
  126. _nop_();
  127. _nop_();
  128. _nop_();
  129. _nop_();

  130. SCL=0;
  131. SDA=1;
  132. }
  133. /******************************************************************************************
  134. * 函数名称    :ReadData
  135. * 功能描述    :从24CXX里读一个字节
  136. * 参数        : 无
  137. * 返回值      : x
  138. * 创建日期    :2010-11-25
  139. * 作者        :zzj
  140. * 全局变量    :
  141. * 全局静态变量:
  142. * 局部静态变量:
  143. *----------------------------------------修改历史------------------------------------------
  144. * 当前版本    :     修改人:                  修改日期:
  145. * 修改说明    :
  146. ******************************************************************************************/
  147. unsigned char ReadData()
  148. // 从AT24Cxx移入数据到MCU
  149. {
  150. unsigned char i;
  151. unsigned char x;   //储存从AT24Cxx中读出的数据
  152. for(i = 0; i < 8; i++)
  153. {
  154.   SCL = 1;                //SCL置为高电平
  155.   x<<=1;                  //将x中的各二进位向左移一位
  156.   x|=(unsigned char)SDA;  //将SDA上的数据通过按位“或“运算存入x中
  157.   SCL = 0;                        //在SCL的下降沿读出数据
  158. }
  159. return(x);                //将读取的数据返回
  160. }
  161. /******************************************************************************************
  162. * 函数名称    :WriteCurrent
  163. * 功能描述    :向AT24Cxx的当前地址写入数据
  164. * 参数        : y (储存待写入的数据)
  165. * 返回值      : 无
  166. * 创建日期    :2010-11-25
  167. * 作者        :zzj
  168. * 全局变量    :
  169. * 全局静态变量:
  170. * 局部静态变量:
  171. *----------------------------------------修改历史------------------------------------------
  172. * 当前版本    :     修改人:                  修改日期:
  173. * 修改说明    :
  174. ******************************************************************************************/
  175. //在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0
  176. void WriteCurrent(unsigned char y)
  177. {
  178. unsigned char i;
  179. for(i = 0; i < 8; i++)  // 循环移入8个位
  180. {
  181.      SDA = (bit)(y&0x80);   //通过按位“与”运算将最高位数据送到S
  182.                                     //因为传送时高位在前,低位在后
  183.   _nop_();            //等待一个机器周期  
  184.      SCL = 1;            //在SCL的上升沿将数据写入AT24Cxx     
  185.      _nop_();            //等待一个机器周期
  186.      _nop_();             //等待一个机器周期      
  187.   
  188.     SCL = 0;            //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲
  189.   y <<= 1;           //将y中的各二进位向左移一位
  190.               
  191. }
  192. }
  193. /******************************************************************************************
  194. * 函数名称    :WriteSet
  195. * 功能描述    :向AT24Cxx中的指定地址写入数据
  196. * 参数        :add (储存指定的地址);dat(储存待写入的数据)
  197. * 返回值      : 无
  198. * 创建日期    :2010-11-25
  199. * 作者        :zzj
  200. * 全局变量    :
  201. * 全局静态变量:
  202. * 局部静态变量:
  203. *----------------------------------------修改历史------------------------------------------
  204. * 当前版本    :     修改人:                  修改日期:
  205. * 修改说明    :
  206. ******************************************************************************************/
  207. void WriteSet(unsigned char add, unsigned char dat)
  208. // 在指定地址addr处写入数据WriteCurrent
  209. {
  210. Start();               //开始数据传递
  211. WriteCurrent(OP_WRITE);  //选择要操作的AT24Cxx芯片,并告知要对其写入数据
  212. TestAsk();
  213. WriteCurrent(add);       //写入指定地址
  214. TestAsk();
  215. WriteCurrent(dat);       //向当前地址(上面指定的地址)写入数据
  216. TestAsk();
  217. Stop();                //停止数据传递
  218. delay(4);        //1个字节的写入周期为1ms, 最好延时1ms以上
  219. }
  220. /******************************************************************************************
  221. * 函数名称    :ReadCurrent
  222. * 功能描述    :从AT24Cxx中的当前地址读取数据
  223. * 参数        : 无
  224. * 返回值      : x (储存读出的数据)
  225. * 创建日期    :2010-11-25
  226. * 作者        :zzj
  227. * 全局变量    :
  228. * 全局静态变量:
  229. * 局部静态变量:
  230. *----------------------------------------修改历史------------------------------------------
  231. * 当前版本    :     修改人:                  修改日期:
  232. * 修改说明    :
  233. ******************************************************************************************/
  234. unsigned char ReadCurrent()
  235. {
  236. unsigned char x;
  237. Start();               //开始数据传递
  238. WriteCurrent(OP_READ);   //选择要操作的AT24Cxx芯片,并告知要读其数据
  239. TestAsk();
  240. x=ReadData();         //将读取的数据存入x
  241. Stop();                //停止数据传递
  242. return x;              //返回读取的数据
  243. }
  244. /******************************************************************************************
  245. * 函数名称    :ReadSet
  246. * 功能描述    :从AT24Cxx中的指定地址读取数据
  247. * 参数        : set_addr
  248. * 返回值      : x
  249. * 创建日期    :2010-11-25
  250. * 作者        :zzj
  251. * 全局变量    :
  252. * 全局静态变量:
  253. * 局部静态变量:
  254. *----------------------------------------修改历史------------------------------------------
  255. * 当前版本    :     修改人:                  修改日期:
  256. * 修改说明    :
  257. ******************************************************************************************/
  258. unsigned char ReadSet(unsigned char set_addr)
  259. // 在指定地址读取
  260. {
  261. Start();                      //开始数据传递
  262. WriteCurrent(OP_WRITE);       //选择要操作的AT24Cxx芯片,并告知要对其写入数据
  263. TestAsk();
  264. WriteCurrent(set_addr);       //写入指定地址
  265. TestAsk();
  266. return(ReadCurrent());        //从指定地址读出数据并返回
  267. }
  268. /******************************************************************************************
  269. * 函数名称    :WritePage
  270. * 功能描述    :从AT24Cxx中的指定页地址写8字节数据
  271. * 参数        : address,*s(要写进去的数组首地址)
  272. * 返回值      : 无
  273. * 创建日期    :2010-11-25
  274. * 作者        :zzj
  275. * 全局变量    :
  276. * 全局静态变量:
  277. * 局部静态变量:
  278. *----------------------------------------修改历史------------------------------------------
  279. * 当前版本    :     修改人:                  修改日期:
  280. * 修改说明    :
  281. ******************************************************************************************/
  282. void WritePage(unsigned char address,unsigned char *s)  //按页写
  283. {
  284. unsigned char i;

  285. Start();
  286. WriteCurrent(OP_WRITE);  //发送控制写字节
  287. TestAsk();
  288. WriteCurrent(address);   //存储器地址;每次读完之后指针自动加1
  289. TestAsk();

  290. for(i=0;i<8;i++)       //直接连续写8次,每页含有16个字节
  291. {
  292.   WriteCurrent(*s);
  293.   TestAsk();
  294.   s++;

  295. }
  296. Stop();
  297. delay(4);        //1个字节的写入周期为1ms, 最好延时1ms以上
  298. }
  299. /******************************************************************************************
  300. * 函数名称    :ReadPage
  301. * 功能描述    :从AT24Cxx中的指定页地址读取8字节数据
  302. * 参数        : address,tmp[](存放读出来的数据)
  303. * 返回值      : 无
  304. * 创建日期    :2010-11-25
  305. * 作者        :zzj
  306. * 全局变量    :
  307. * 全局静态变量:
  308. * 局部静态变量:
  309. *----------------------------------------修改历史------------------------------------------
  310. * 当前版本    :     修改人:                  修改日期:
  311. * 修改说明    :
  312. ******************************************************************************************/
  313. void ReadPage(unsigned char address,unsigned char tmp[]) //按页读取、可以连续读,不需要按页读
  314. {
  315. unsigned char i;

  316. Start();
  317. WriteCurrent(OP_WRITE);  //发送控制写字节
  318. TestAsk();
  319. WriteCurrent(address);  //存储器地址;每次读完之后指针自动加1
  320. TestAsk();

  321. Start();
  322. WriteCurrent(OP_READ);   //选择要操作的AT24Cxx芯片,并告知要读其数据
  323. TestAsk();

  324. tmp[0]=ReadData();
  325. for(i=1;i<8;i++)  
  326. {
  327.   SendAsk();
  328.   tmp[i]=ReadData();
  329. }  /**/


  330. Stop();
  331. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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