/***Main.C ***/ #include <reg52.h> #include "I2C.H" #define uchar unsigned char // 自定义uchar为unsigned char(即无符号字符型数据,数据范围:0到255。) #define uint unsigned int //自定义uint为unsigned int(即有符号整数型数据,数据范围:0到65535。) uchar i2cwriteflag; uchar qian,bai,shi,ge; uchar valueqian,valuebai,valueshi,valuege; uint count,value;//声明定时器0中断次数变量、数值变量 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共阴数码管段码数字0~9字码表,高电平点亮数码管段码数字0~9。 // void Delay100us() //晶振11.0592MHz,100微妙延时。 //{ // unsigned char i, j; // _nop_(); // _nop_(); // i = 2; // j = 15; // do // { // while (--j); // } // while (--i); // } void delay(uint z)//延时程序 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void ShuMaGuanDisplayValue(uint value)//数码管显示数值函数 { qian=value/1000;//数码管千位变量 bai=value%1000/100;//数码管百位变量 shi=value%100/10;//数码管十位变量 ge=value%10;//数码管个位变量 P2=0xfe;//数码管千位显示位 P0=table[qian];//数码管千位数值显示 delay(5);//延时 P2=0xfd;//数码管百位显示位 P0=table[bai];//数码管百位数值显示 delay(5);//延时 P2=0xfb;//数码管十位显示位 P0=table[shi];//数码管十位数值显示 delay(5);//延时 P2=0xf7;//数码管个位显示位 P0=table[ge];//数码管个位数值显示 delay(5);//延时 // weixuan=1; // P0=0xfe;//数码管千位显示位 // weixuan=0; // duanxuan=1; // P0=table[qian];//数码管千位数值显示 // duanxuan=0; // P0=0xff; // Delay(5);//延时 // // weixuan=1; // P0=0xfd;//数码管百位显示位 // weixuan=0; // duanxuan=1; // P0=table[bai];//数码管百位数值显示 // duanxuan=0; // P0=0xff; // Delay(5);//延时 // // weixuan=1; // P0=0xfb;//数码管十位显示位 // weixuan=0; // duanxuan=1; // P0=table[shi];//数码管十位数值显示 // duanxuan=0; // P0=0xff; // Delay(5);//延时 // // weixuan=1; // P0=0xf7;//数码管个位显示位 // weixuan=0; // duanxuan=1; // P0=table[ge];//数码管个位数值显示 // duanxuan=0; // P0=0xff; // Delay(5);//延时 } void Timer0Init()//定时器0初始化 { TMOD=0x01;//设定定时器类型为定时器0,定时器工作模式为模式0。 TH0=(65536-50000)/256;//TH0装初值 TL0=(65536-50000)%256;//TL0装初值 EA=1;//开启定时器总中断 ET0=1;//开启定时器0中断开关 TR0=1;//启动定时器0 } void Timer0() interrupt 1//定时器0中断函数 { TH0=(65536-50000)/256;//TH0重新装值 TL0=(65536-50000)%256;//TL0重新装值 count++;//定时器0中断次数变量先赋值再加 // if(count==18)//判断定时器0中断次数变量是否为18次 // { // count=0;//定时器0中断次数变量归零 // value++;//数值变量先赋值再加 // I2Cwriteflag=1;// // if(value>=3600)//判断数值变量是否大于等于3600 // value=0;//数值变量置0 // } } void main()//主函数 { Timer0Init();//定时器0初始化函数 i2cinit();//I2C初始化信号函数 value=i2cread_add(0xa0,0)*1000+i2cread_add(0xa0,1)*100+i2cread_add(0xa0,2)*10+i2cread_add(0xa0,3);//I2C向某个从机的某个地址读一个字节数据信号函数 if(value>=3600)//判断数值变量是否大于等于3600 value=0;//数值变量置0 while(1)//固定循环 { if(count==18)//判断定时器0中断次数变量是否为18次 { count=0;//定时器0中断次数变量归零 value++;//数值变量先赋值再加 i2cwriteflag=1;// valueqian=value/1000;//数值变量千位变量 valuebai=value%1000/100;//数值变量百位变量 valueshi=value%100/10;//数值变量十位变量 valuege=value%10;//数值变量个位变量 if(value>=3600)//判断数值变量是否大于等于3600 value=0;//数值变量置0 } if(i2cwriteflag==1) { i2cwriteflag=0;// i2cwrite_add(0xa0,0,valueqian); delay(5);//延时 value=i2cread_add(0xa0,0)*1000+i2cread_add(0xa0,1)*100+i2cread_add(0xa0,2)*10+i2cread_add(0xa0,3); i2cwrite_add(0xa0,1,valuebai); delay(5);//延时 value=i2cread_add(0xa0,0)*1000+i2cread_add(0xa0,1)*100+i2cread_add(0xa0,2)*10+i2cread_add(0xa0,3); i2cwrite_add(0xa0,2,valueshi); delay(5);//延时 value=i2cread_add(0xa0,0)*1000+i2cread_add(0xa0,1)*100+i2cread_add(0xa0,2)*10+i2cread_add(0xa0,3); i2cwrite_add(0xa0,3,valuege); delay(5);//延时 value=i2cread_add(0xa0,0)*1000+i2cread_add(0xa0,1)*100+i2cread_add(0xa0,2)*10+i2cread_add(0xa0,3); } ShuMaGuanDisplayValue(value);//数码管显示数值 } }
/***I2C.C***/ #include "I2C.H" #define uchar unsigned char #define uint unsigned int void delay()//延时程序 { ;; } void i2cstart()//I2C启动信号函数 { SDA=1; delay(); SCL=1; delay(); SDA=0; delay(); } void i2cstop()//I2C停止信号函数 { SDA=0; delay(); SCL=1; delay(); SDA=1; delay(); } void i2crespons()//I2C应答信号函数 { uchar i; SCL=1; delay(); while((SDA==1)&&(i<250)) //加个延时退出,防止没应答进入死循环。 i++; SCL=0; delay(); } void i2cinit()//I2C初始化信号函数 { SDA=1; delay(); SCL=1; delay(); } void i2cwrite_byte(uchar value)//I2C向从机写一个字节信号函数 { uchar i,temp; temp=value; for(i=0;i<8;i++) { temp=temp<<1; SCL=0; delay(); SDA=CY;//CY是进位标志 delay(); SCL=1; delay(); } SCL=0; delay(); SDA=1; delay(); } uchar i2cread_byte()//I2C向从机读一个字节信号函数 { uchar i,k; SCL=0; delay(); SDA=1; delay(); for(i=0;i<8;i++) { SCL=1; delay(); k=(k<<1)|SDA; SCL=0; delay(); } return k; } void i2cwrite_add(uchar salveaddress,uchar address,uchar value)//I2C向某个从机的某个地址写一个字节数据信号函数 { i2cstart(); i2cwrite_byte(salveaddress);//发送设备地址+写信号 i2crespons(); i2cwrite_byte(address);//发送存储单元地址 i2crespons(); i2cwrite_byte(value);//发送数据 i2crespons(); i2cstop(); } uchar i2cread_add(uchar salveaddress,uchar address)//I2C向某个从机的某个地址读一个字节数据信号函数 { uchar information; i2cstart(); i2cwrite_byte(salveaddress);//发送设备地址+写信号 i2crespons(); i2cwrite_byte(address);//发送存储单元地址 i2crespons(); i2cstart(); i2cwrite_byte(salveaddress+1);//发送设备地址+读信号 i2crespons(); information=i2cread_byte();//读取数据 i2cstop(); return information; }
/**I2C.H**/ #ifndef __I2C_H__ #define __I2C_H__ #include <reg52.h> #define uchar unsigned char #define uint unsigned int sbit SDA=P2^0; sbit SCL=P2^1; void delay();//延时程序 void i2cstart();//I2C启动信号函数 void i2cstop();//I2C停止信号函数 void i2crespons();//I2C应答信号函数 void i2cinit();//I2C初始化信号函数 void i2cwrite_byte(uchar value);//I2C向从机写一个字节信号函数 uchar i2cread_byte();//I2C向从机读一个字节信号函数 void i2cwrite_add(uchar salveaddress,uchar address,uchar value);//I2C向某个从机的某个地址写一个字节数据信号函数 uchar i2cread_add(uchar salveaddress,uchar address);//I2C向某个从机的某个地址读一个字节数据信号函数 #endif
基于51单片机的I2C通信及从AT24C02读取保存数据来显示在4位数码管上的项目工程
原文:https://www.cnblogs.com/AChenWeiqiangA/p/12330431.html