找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2052|回复: 0
收起左侧

基于51单片机的I2C通信及从AT24C02读取保存数据来显示在4位数码管上的项目工程

[复制链接]
ID:171036 发表于 2020-4-25 09:55 | 显示全部楼层 |阅读模式
本帖最后由 51黑电子会员 于 2020-4-25 10:10 编辑
  1. /***Main.C***/
  2. #include <reg52.h>//包含52单片机头文件
  3. #include "I2C.H"//包含I2C.H头文件
  4. #define uchar unsigned char//自定义uchar为unsigned char(即无符号字符型数据,数据范围:0到255。)
  5. #define uint unsigned int//自定义uint为unsigned int(即有符号整数型数据,数据范围:0到65535。)   
  6. uchar i2cwriteflag;//AT24C02存储芯片写入标志位变量
  7. uchar qian,bai,shi,ge;//数值个位变量、数值十位变量、数值百位变量、数值千位变量
  8. uchar valuege,valueshi,valuebai,valueqian;//数值个位数变量、数值十位数变量、数值百位数变量、数值千位数变量
  9. uint count,value;//声明定时器0中断次数变量、数值变量
  10. uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共阴数码管段码数字0~9字码表,高电平点亮数码管段码数字0~9。
  11.   //  void Delay100us()    //晶振11.0592MHz,100微妙延时。
  12. //{
  13. //   unsigned char i, j;
  14. //   _nop_();
  15. //   _nop_();
  16. //   i = 2;
  17. //   j = 15;
  18. //   do
  19. // {
  20. //    while (--j);
  21. //   }
  22. //   while (--i);
  23. // }
  24.   void delay(uint z)//延时程序
  25. {
  26.    uint x,y;
  27.    for(x=z;x>0;x--)
  28.     for(y=110;y>0;y--);
  29. }
  30. //  void ShuMaGuanDisplayValue(uint value)//数码管显示数值函数
  31. //{  
  32. //   qian=value%10000/1000;//数码管千位变量
  33. //   bai=value%1000/100;//数码管百位变量
  34. //   shi=value%100/10;//数码管十位变量
  35. //   ge=value%10;//数码管个位变量
  36. //  
  37. //   P2=0xfe;//数码管千位显示位
  38. //   P0=table[qian];//数码管千位数值显示
  39. //   delay(5);//延时
  40. //
  41. //   P2=0xfd;//数码管百位显示位
  42. //   P0=table[bai];//数码管百位数值显示
  43. //   delay(5);//延时
  44. //
  45. //
  46. //   P2=0xfb;//数码管十位显示位
  47. //   P0=table[shi];//数码管十位数值显示
  48. //   delay(5);//延时
  49. //
  50. //   P2=0xf7;//数码管个位显示位
  51. //   P0=table[ge];//数码管个位数值显示
  52. //   delay(5);//延时

  53. //   weixuan=1;
  54. //   P0=0xfe;//数码管千位显示位
  55. //   weixuan=0;
  56. //   duanxuan=1;
  57. //   P0=table[qian];//数码管千位数值显示
  58. //   duanxuan=0;
  59. //   P0=0xff;
  60. //   Delay(5);//延时
  61. //
  62. //   weixuan=1;
  63. //   P0=0xfd;//数码管百位显示位
  64. //   weixuan=0;
  65. //   duanxuan=1;
  66. //   P0=table[bai];//数码管百位数值显示
  67. //   duanxuan=0;
  68. //   P0=0xff;
  69. //   Delay(5);//延时
  70. //  
  71. //   weixuan=1;
  72. //   P0=0xfb;//数码管十位显示位
  73. //   weixuan=0;
  74. //   duanxuan=1;
  75. //   P0=table[shi];//数码管十位数值显示
  76. //   duanxuan=0;
  77. //   P0=0xff;
  78. //   Delay(5);//延时
  79. //
  80. //   weixuan=1;
  81. //   P0=0xf7;//数码管个位显示位
  82. //   weixuan=0;
  83. //   duanxuan=1;
  84. //   P0=table[ge];//数码管个位数值显示
  85. //   duanxuan=0;
  86. //   P0=0xff;
  87. //   Delay(5);//延时
  88. // }
  89.   void ShuMaGuanDisplayValue(uchar valuege,valueshi,valuebai,valueqian)//数码管显示数值函数
  90. {  
  91.    P2=0xf7;//数码管个位显示位
  92.    P0=table[valuege];//数码管个位数值显示
  93.    delay(5);//延时

  94.    P2=0xfb;//数码管十位显示位
  95.    P0=table[valueshi];//数码管十位数值显示
  96.    delay(5);//延时

  97.    P2=0xfd;//数码管百位显示位
  98.    P0=table[valuebai];//数码管百位数值显示
  99.    delay(5);//延时

  100.    P2=0xfe;//数码管千位显示位
  101.    P0=table[valueqian];//数码管千位数值显示
  102.    delay(5);//延时
  103.   }  
  104.   void Timer0Init()//定时器0初始化
  105. {
  106.    TMOD=0x01;//设定定时器类型为定时器0,定时器工作模式为模式0。
  107.    TH0=(65536-50000)/256;//TH0装初值
  108.    TL0=(65536-50000)%256;//TL0装初值
  109.    EA=1;//开启定时器总中断
  110.    ET0=1;//开启定时器0中断开关
  111.    TR0=1;//启动定时器0
  112. }
  113.   void Timer0() interrupt 1//定时器0中断函数
  114. {
  115.    TH0=(65536-50000)/256;//TH0重新装值
  116.    TL0=(65536-50000)%256;//TL0重新装值
  117.    count++;//定时器0中断次数变量先赋值再加
  118.    if(count==18)//判断定时器0中断次数变量是否为18次
  119.   {
  120.     count=0;//定时器0中断次数变量置0
  121.     i2cwriteflag=1;//AT24C02存储芯片写入标志位变量置1
  122.     valuege++;//数值个位数变量先赋值再加
  123.     if(valuege==10)//判断数值个位数变量是否为10
  124.    {
  125.      valuege=0;//数值个位数变量置0
  126.      valueshi++;//数值十位数变量先赋值再加
  127.      if(valueshi==10)//判断数值十位数变量是否为10
  128.     {
  129.       valueshi=0;//数值十位数变量置0
  130.       valuebai++;//数值百位数变量先赋值再加
  131.       if(valuebai==10)//判断数值百位数变量是否为10
  132.      {
  133.        valuebai=0;//数值百位数变量置0
  134.        valueqian++;//数值千位数变量先赋值再加
  135.        if(valueqian==10)//判断数值千位数变量是否为10
  136.       {
  137.         valueqian=9;//数值千位数变量置9      
  138.        }
  139.       }
  140.      }
  141.     }
  142.     if(valuege==9&&valueshi==9&&valuebai==9&&valueqian==9)//判断数值个位数变量是否为9与数值十位数变量是否为9与数值百位数变量是否为9与数值千位数变量是否为9
  143.    {
  144.      valuege=0;//数值个位数变量置0
  145.      valueshi=0;//数值十位数变量置0
  146.      valuebai=0;//数值百位数变量置0
  147.      valueqian=0;//数值千位数变量置0
  148.     }
  149.    }
  150.   }
  151.   void main()//主函数
  152. {
  153.    Timer0Init();//定时器0初始化函数
  154.    i2cinit();//I2C初始化信号函数
  155. //   value=i2cread_add(0xa0,0);
  156.    valuege=i2cread_add(0xa0,0);//读出AT24C02存储芯片第0地址所写数值个位数变量
  157.    valueshi=i2cread_add(0xa0,1);//读出AT24C02存储芯片第1地址所写数值十位数变量
  158.    valuebai=i2cread_add(0xa0,2);//读出AT24C02存储芯片第2地址所写数值百位数变量
  159.    valueqian=i2cread_add(0xa0,3);//读出AT24C02存储芯片第3地址所写数值千位数变量
  160.    while(1)//固定循环
  161. {  
  162.     if(i2cwriteflag==1)//判断AT24C02存储芯片写入标志位变量是否为1
  163.   {
  164.      i2cwriteflag=0;//AT24C02存储芯片写入标志位变量置0
  165. //   i2cwrite_add(0xa0,0,value);
  166.      i2cwrite_add(0xa0,0,valuege);//往AT24C02存储芯片第0地址写入数值个位数变量
  167.      ShuMaGuanDisplayValue(valuege,valueshi,valuebai,valueqian);//数码管显示数值
  168.      i2cwrite_add(0xa0,1,valueshi);//往AT24C02存储芯片第1地址写入数值十位数变量
  169.      ShuMaGuanDisplayValue(valuege,valueshi,valuebai,valueqian);//数码管显示数值
  170.      i2cwrite_add(0xa0,2,valuebai);//往AT24C02存储芯片第2地址写入数值百位数变量
  171.      ShuMaGuanDisplayValue(valuege,valueshi,valuebai,valueqian);//数码管显示数值
  172.      i2cwrite_add(0xa0,3,valueqian);//往AT24C02存储芯片第3地址写入数值千位数变量
  173.      ShuMaGuanDisplayValue(valuege,valueshi,valuebai,valueqian);//数码管显示数值
  174.    }
  175. //    ShuMaGuanDisplayValue(value);//数码管显示数值
  176.     ShuMaGuanDisplayValue(valuege,valueshi,valuebai,valueqian);//数码管显示数值
  177.   }      
  178. }

  179. /***I2C.C***/
  180. #include "I2C.H"//包含I2C.H头文件
  181. #define uchar unsigned char//自定义uchar为unsigned char(即无符号字符型数据,数据范围:0到255。)
  182. #define uint unsigned int//自定义uint为unsigned int(即有符号整数型数据,数据范围:0到65535。)
  183.   void delay()//延时程序
  184. {
  185.    ;;
  186. }
  187.   void i2cstart()//单片机I2C总线启动信号函数
  188. {
  189.    SDA=1;//AT24C02芯片串行数据端置高电平
  190.    delay();//延时
  191.    SCL=1;//AT24C02芯片串行时钟输入端置高电平
  192.    delay();//延时
  193.    SDA=0;//AT24C02芯片串行数据端置低电平
  194.    delay();//延时
  195. }
  196.   void i2cstop()//单片机I2C总线停止信号函数
  197. {
  198.    SDA=0;//AT24C02芯片串行数据端置低电平
  199.    delay();//延时
  200.    SCL=1;///AT24C02芯片串行时钟输入端置高电平
  201.    delay();//延时
  202.    SDA=1;//AT24C02芯片串行数据端置高电平
  203.    delay();//延时
  204. }
  205.   void i2crespons()//单片机I2C应答信号函数
  206. {
  207.    uchar i;//计时变量
  208.    SCL=1;//AT24C02芯片串行时钟输入端置高电平
  209.    delay();//延时
  210.    while((SDA==1)&&(i<250)) //加个延时退出,防止没应答进入死循环。
  211.    i++;//计时变量先赋值再加
  212.    SCL=0;//AT24C02芯片串行时钟输入端置低电平
  213.    delay();//延时
  214. }
  215. //  void i2cnorespons()//I2C不应答信号函数
  216. //{
  217. //   SCL=1;
  218. //   delay();
  219. //   SDA=1;
  220. //   SCL=0;
  221. //   delay();
  222. // }
  223.   void i2cinit()//单片机I2C总线初始化信号函数
  224. {
  225.    SDA=1;//AT24C02芯片串行数据端置高电平
  226.    delay();//延时
  227.    SCL=1;//AT24C02芯片串行时钟输入端置高电平
  228.    delay();//延时
  229. }
  230.   void i2cwrite_byte(uchar value)//单片机I2C总线向从机写一个字节信号函数
  231. {
  232.    uchar i,temp;//字节位变量、临时变量
  233.    temp=value;//数据变量赋给临时变量
  234.    for(i=0;i<8;i++)//循环8位
  235. {
  236.     temp=temp<<1;//临时变量左移一位
  237.     SCL=0;//AT24C02芯片串行时钟输入端置低电平
  238.     delay();//延时
  239.     SDA=CY;//CY是进位标志
  240.     delay();//延时
  241.     SCL=1;//AT24C02芯片串行时钟输入端置高电平
  242.     delay();//延时
  243.    }
  244.    SCL=0;//AT24C02芯片串行时钟输入端置低电平
  245.    delay();//延时
  246.    SDA=1;//AT24C02芯片串行数据端置高电平
  247.    delay();//延时
  248. }
  249.   uchar i2cread_byte()//单片机I2C总线接口向从机读一个字节信号函数
  250. {
  251.    uchar i,k;//字节位变量、临时变量
  252.    SCL=0;//AT24C02芯片串行时钟输入端置低电平
  253.    delay();//延时
  254.    SDA=1;//AT24C02芯片串行数据端置高电平
  255.    delay();//延时
  256.    for(i=0;i<8;i++)//循环8位
  257. {
  258.    SCL=1;//AT24C02芯片串行时钟输入端置高电平
  259.    delay();//延时
  260.    k=(k<<1)|SDA;//一个字节
  261.    SCL=0;//AT24C02芯片串行时钟输入端置低电平
  262.    delay();//延时
  263.   }
  264.    return k;//返回临时变量
  265. }
  266.   void i2cwrite_add(uchar salveaddress,uchar address,uint value)//单片机I2C总线接口向某个从机的某个地址写一个字节数据信号函数
  267. {
  268.    i2cstart();//单片机I2C总线接口开始信号
  269.    i2cwrite_byte(salveaddress);//发送设备地址+写信号
  270.    i2crespons();//单片机I2C总线接口应答信号
  271.    i2cwrite_byte(address);//发送存储单元地址
  272.    i2crespons();//单片机I2C总线接口应答信号
  273.    i2cwrite_byte(value);//单片机I2C总线接口往AT24C02芯写入数据
  274.    i2crespons();//单片机I2C总线接口应答信号
  275.    i2cstop();//单片机I2C总线接口停止信号
  276. }
  277.   uint i2cread_add(uchar salveaddress,uchar address)//单片机I2C总线接口向某个从机的某个地址读一个字节数据信号函数
  278. {
  279.    uint information;//声明一个数据变量
  280.    i2cstart();//单片机I2C总线接口开始信号
  281.    i2cwrite_byte(salveaddress);//发送设备地址+写信号
  282.    i2crespons();//单片机I2C总线接口应答信号
  283.    i2cwrite_byte(address);//发送存储单元地址
  284.    i2crespons();//单片机I2C总线接口应答信号
  285.    i2cstart();//单片机I2C总线接口开始信号
  286.    i2cwrite_byte(salveaddress+1);//发送设备地址+读信号
  287.    i2crespons();//单片机I2C总线接口应答信号
  288.    information=i2cread_byte();//单片机I2C总线接口读取AT24C02芯片所存数据赋给数据变量
  289. //   i2cnorespons();//单片机I2C总线接口不应答信号
  290.    i2cstop();//单片机I2C总线接口停止信号
  291.    return information;//返回数据变量
  292. }

  293. /***I2C.H***/
  294. #ifndef __I2C_H__//防止Main.C头文件和I2C.C头文件同时编译i2c.h文件出现多重定义
  295. #define __I2C_H__//
  296. #include <reg52.h>//包含52单片机头文件
  297. #define uchar unsigned char//自定义uchar为unsigned char(即无符号字符型数据,数据范围:0到255。)
  298. #define uint unsigned int//自定义uint为unsigned int(即有符号整数型数据,数据范围:0到65535。)
  299. sbit SCL=P3^0;//位定义AT24C02芯片串行时钟输入端为单片机P3.0端口
  300. sbit SDA=P3^1;//位定义AT24C02芯片串行数据端为单片机P3.1端口
  301. void delay();//延时程序
  302. void i2cstart();//单片机I2C总线启动信号函数
  303. void i2cstop();//单片机I2C总线停止信号函数
  304. void i2crespons();//单片机I2C总线应答信号函数
  305. //void i2cnorespons();//单片机I2C总线不应答信号函数
  306. void i2cinit();//单片机I2C总线初始化信号函数
  307. void i2cwrite_byte(uchar value);//单片机I2C总线向从机写一个字节信号函数
  308. uchar i2cread_byte();//单片机I2C总线接口向从机读一个字节信号函数
  309. void i2cwrite_add(uchar salveaddress,uchar address,uint value);//单片机I2C总线接口向某个从机的某个地址写一个字节数据信号函数
  310. uint i2cread_add(uchar salveaddress,uchar address);//单片机I2C总线接口向某个从机的某个地址读一个字节数据信号函数
  311. #endif
复制代码
1680900-20200219212257853-1961729998.png

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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