找回密码
 立即注册

QQ登录

只需一步,快速开始

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

带注释的AT24C02 IIC总线单片机读写源程序

[复制链接]
跳转到指定楼层
楼主
ID:300102 发表于 2018-6-10 14:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned  int
  5. #define AT24C02_addr
  6. bit write=0;//写24C02的标志
  7. sbit sda=P2^0;
  8. sbit scl=P2^1;
  9. sbit dula=P2^6;//申明U1锁存器的锁存端
  10. sbit wela=P2^7;//U2锁存端
  11. uchar i,miao,t;
  12. uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  13. void Delay5us()  //@11.0592MHz
  14. {
  15. uchar i;
  16.   _nop_();
  17. i = 11;
  18. while (--i);
  19. }
  20. void start()//起始信号
  21. {
  22. scl=1;//先保持高电平,再进行数据传输
  23. _nop_();//延时1微秒
  24.   sda=1;
  25. Delay5us();//函数调用
  26. sda=0;
  27. Delay5us();
  28. }
  29. void stop()
  30. {
  31. scl=1;
  32. _nop_();
  33. sda=0;
  34. Delay5us();
  35. sda=1;
  36. Delay5us();
  37. }
  38. void Mster_ASK()//主机发送应答
  39. {
  40.   uchar i;
  41. scl=1;
  42. _nop_();
  43. if(i==1)//受控器做出响应
  44. {
  45. sda=0;//释放sda线送出应答信号
  46. }
  47. else
  48. {
  49.   sda=1;
  50. }
  51. _nop_();
  52. scl=1;//数据保持稳定
  53. Delay5us();
  54. scl=0;//占用总线进行通信
  55. sda=1;//准备下一次的通信
  56. }
  57. void test_ASK()//从机接受应答,低电平为应答
  58. {
  59. scl=1;//scl为高电平,数据不允许改变
  60. Delay5us();
  61. if(sda==1)//因为sda等于1时,表示空闲状态
  62. {
  63.   scl=0;//表示不应答
  64.   _nop_();
  65.   stop();
  66. return (0);
  67. }
  68. else//sda等于0,表示应答,scl拉低,表示收到这个是否应达的信息
  69. {
  70. scl=0;//低电平有效
  71. _nop_();
  72. return (1);
  73. }
  74. }
  75. uchar sendbyte(uchar byte)//传送(写)一个字节
  76. {
  77.   uchar i;
  78. for(i=0;i<8;i++)
  79.   {
  80.    scl=0;//低电平时数据可以改变
  81.    _nop_();//稳定一下
  82.    if(byte&0x80)
  83.    {
  84.      sda=1;//发一个1的数据,先发高位
  85.      _nop_();
  86.    }
  87.    else
  88.    {
  89.      sda=0;//如果if处是0的话,就说明最高位是0,所以传数据0
  90.     _nop_();
  91.    }
  92.    scl=1;//数据手册看出来
  93.    _nop_();
  94.    byte<<=1;
  95.   }
  96. }
  97. uchar readbyte()//读一个字节
  98. {
  99. uchar dat,i;
  100. scl=0;//可要可不要吧,看它忙不忙
  101. _nop_();
  102. scl=1;//置1,数据不允许改变
  103. _nop_();
  104. for(i=0;i<8;i++)
  105. {
  106.    scl=1;//置1,数据不允许改变
  107.   _nop_();

  108.   if(sda)//若为1,则要读1出来
  109.   {
  110.     dat=dat|0x01;//或上都等于1
  111.    else
  112.    {
  113.     dat=dat&0xfe;//与上都等于0
  114.    }
  115.     _nop_();
  116.    scl=0; //释放总线,允许下一次数据输入
  117.     dat<<=1;
  118.   }
  119. }
  120. }

  121. void T0()interrpt 1//定时中断服务函数
  122. {
  123.   uchar t,miao,write;
  124. TH0=(65536-50000)/256//从15536开始装初值,装满5000,即为50ms
  125. TL0=(65536-50000)%256//装计数初值
  126. t++;
  127. if(t==20)//表示记满1秒
  128. {
  129.    t=0;//重新计数
  130.   miao++;
  131. }
  132.   if(miao=100)
  133.     miao=0;//重新计数
  134. }
  135. void display()
  136. {
  137. uchar bai,ge;
  138. wela=1;//打开位选
  139. P0=0x7e;//点亮第一位数码管
  140. wela=0;//关闭位选
  141. dula=1;;//打开段选
  142. P0=table[bai];
  143. dula=0;
  144. wela=1;
  145. P0=0x7d;
  146. wela=0;
  147. dula=1;
  148. P0=table[ge];
  149. dula=0;
  150. main()
  151. {
  152. ACK_flag=0;
  153. Init();//初始化
  154. start();
  155. sendbyte(AT24C02+0)//器件地址加0
  156. if(!test_ASK())//若不应答,则为假,然 后取反
  157. {
  158.    ACK_flag=1;
  159. }
  160. t=readbyte();//读出的时间赋予t
  161. if(t>100)
  162.   t=0;//预防首次读取出错误数据
  163. TMOD=0x01;//定时器工作在方式1
  164. ET0=1;//开定时器0
  165. EA=1;//开总定时器
  166. TH0=(65536-50000)/256;//对TH0TL0赋值
  167. TL0=(65536-50000)%256;//使定时器50毫秒中断一次
  168. TR0=1;//开始计时
  169. while(1)
  170. {
  171.    display(t/10,t%10)
  172.    if(write==1)//判断计时器是否为1秒
  173.    {
  174.      write=0;//清0
  175.     sendbyte(2,t)//在地址2中写入数据t
  176.    }

  177. }
  178. }
  179. void write_address(uchar date,uchar address)
  180. {
  181. start();
  182. writebyte(0xa0);
  183. Mster_ASK;//应答
  184. write_byte(date);
  185. test_ASK;//应答
  186. stop();
  187. }
  188. void read_add(uchar address)
  189. {
  190. uchar date;
  191. start();
  192. writebyte(0xa0);
  193. Mster_ASK();
  194. writebyte(address);
  195. test_ASK();
  196. start();
  197. writebyte(0xa1);
  198. Mster_ASK();
  199. test_ASK();
  200. date=writebyte();
  201. stop();
  202. return date;
  203. }



  204. bit I2C_WriteData(uchar ADDR,uchar DAT)  //I2C写数据
  205. {
  206. I2C_Start();
  207. I2C_send_byte(AT24C02_ADDR+0);
  208. if (!Test_ACK())
  209. {
  210.   return(0);
  211. }
  212. I2C_send_byte(ADDR);
  213. if (!Test_ACK())
  214. {
  215.   return(0);
  216. }
  217. I2C_send_byte(DAT);
  218. if (!Test_ACK())
  219. {
  220.   return(0);
  221. }
  222. I2C_Stop();
  223. return(1);
  224. }
  225. uchar I2C_ReadData(uchar ADDR)  //I2C读数据
  226. {
  227. uchar dat;
  228. I2C_Start();
  229. I2C_send_byte(AT24C02_ADDR+0);
  230. if (!Test_ACK())
  231. {
  232.   return(0);
  233. }
  234. I2C_send_byte(ADDR);
  235. if (!Test_ACK())
  236. {
  237.   return(0);
  238. }
  239. Master_ACK(0);
  240. I2C_Start();
  241. I2C_send_byte(AT24C02_ADDR+1);
  242. if (!Test_ACK())
  243. {
  244.   return(0);
  245. }
  246. dat = I2C_read_byte();
  247. Master_ACK(0);
  248. I2C_Stop();
  249. return(dat);
  250. }
  251. void main()
  252. {
  253. I2C_init();
  254. Timer0_init();
  255. EEPROM_DATA = I2C_ReadData(255); //上电后首先读出24C02第255单元的值
  256. while(1)
  257. {
  258.   display(EEPROM_DATA);//数码管显示
  259.    
  260. }
  261. }
  262. /*定时器0中断服务程序*/
  263. void timer0() interrupt 1 //T0内部查询顺序1
  264. {
  265. uchar i;   
  266. TH0 = 0x4b;
  267. TL0 = 0xfe;      //T0 定时50ms
  268. i++;
  269. if (i == 100)   //5秒时间到
  270. {
  271.   i = 0;    //计数清零
  272.   if (EEPROM_DATA < 99) //判断待写数据值
  273.   {
  274.    EEPROM_DATA++;
  275.   }
  276.   else
  277.   {
  278.    EEPROM_DATA = 0;
  279.   }
  280.   if(!I2C_WriteData(255,EEPROM_DATA)) //写入待写数据并判断是否成功写入
  281.   {
  282.    LED1 = 0;//如果写失败  让LED1小灯点亮
  283.   }
  284.   else
  285.   {
  286.    LED1 = 1;
  287.   }  
  288. }
  289. }   


复制代码






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

使用道具 举报

沙发
ID:393744 发表于 2018-9-6 17:17 | 只看该作者
有返回值的,会出现void函数吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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