|
/*利用IIC總線接口底層驅(qū)動(dòng)代碼,設(shè)計(jì)應(yīng)用程序,實(shí)現(xiàn)下面功能:1.系統(tǒng)開機(jī)后,讀取0x01、0x03和0x05 內(nèi)存單元的數(shù)據(jù),并從左至右顯示在數(shù)碼管上, .數(shù)字之間用“-”分隔,
2.將0x01單元的數(shù)據(jù)加1后,寫回該內(nèi)存單元,使用按鍵s1加1后結(jié)果如大于10,恢復(fù)0.0x03單元的數(shù)據(jù)加2后,寫回該內(nèi)存單元, .加2后結(jié)果如大于20,恢復(fù)0。將0x05單元的數(shù)據(jù)加3后,寫回該內(nèi)存單元,加3后結(jié)果如大于30,恢復(fù)0。*/
/*main.c文件*/
- #include "reg51.h"
- #include "i2c.h"
- typedef unsigned int u16; //對(duì)數(shù)據(jù)類型進(jìn)行聲明定義
- typedef unsigned char u8;
- void datapros();
- sbit LSA=P2^2;
- sbit LSB=P2^3;
- sbit LSC=P2^4;
- sbit k1=P3^1;
- sbit k2=P3^3;
- u8 display[8],addr,a=0,b=0,c=0;
- u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- void delayy(u16 i)
- {
- while(i--);
- }
- void DigDisplay()
- {
- u8 i;
- for(i=0;i<8;i++)
- {
- switch(i) //位選,選擇點(diǎn)亮的數(shù)碼管,
- {
- case(0):
- LSA=0;LSB=0;LSC=0; break;//顯示第0位
- case(1):
- LSA=1;LSB=0;LSC=0; break;//顯示第1位
- case(2):
- LSA=0;LSB=1;LSC=0; break;//顯示第2位
- case(3):
- LSA=1;LSB=1;LSC=0; break;//顯示第3位
- case(4):
- LSA=0;LSB=0;LSC=1; break;//顯示第4位
- case(5):
- LSA=1;LSB=0;LSC=1; break;//顯示第5位
- case(6):
- LSA=0;LSB=1;LSC=1; break;//顯示第6位
- case(7):
- LSA=1;LSB=1;LSC=1; break;//顯示第7位
- }
- P0=display[i];
- delayy(100);
- P0=0x00;
- }
- }
- void datapros()//數(shù)碼管數(shù)據(jù)的處理
- {
- display[0]=smgduan[a%10];
- display[1]=smgduan[a/10];
- display[2]=0x40;
- display[3]=smgduan[b%10];
- display[4]=smgduan[b/10];
- display[5]=0x40;
- display[6]=smgduan[c%10];
- display[7]=smgduan[c/10];
- }
- void ack() //取讀保存在地址內(nèi)的數(shù)據(jù)
- {
- a=At24c02Read(0x01);
- b=At24c02Read(0x03);
- c=At24c02Read(0x05);
- }
- void anjian()
- {
- if(k1==0)
- {
- delayy(1000);
- if(k1==0)
- {
-
- a=At24c02Read(0x01); //將0X01地址內(nèi)的數(shù)據(jù)賦給A
- a++;
- if(a>10)
- {
- a=0;
- }
- At24c02Write(0x01,a); //將A數(shù)據(jù)寫入0x01的地址中去
- delayy(1000);
-
- b=At24c02Read(0x03); //將0X03地址內(nèi)的數(shù)據(jù)賦給B
- b=b+2;
- if(b>20)
- {
- b=0;
- }
- At24c02Write(0x03,b); //將B的數(shù)據(jù)寫入0x03的地址中去
- delayy(1000);
- c=At24c02Read(0x05); //將0X05地址內(nèi)的數(shù)據(jù)賦給C
- c=c+3;
- if(c>30)
- {
- c=0;
- }
- At24c02Write(0x05,c); //將C的數(shù)據(jù)寫入0x05的地址中去
- delayy(1000);
- }
- while(!k1);
- }
- }
- void an() //將數(shù)據(jù)都至0,并保存起來
- {
- if(k2==0)
- {
- delayy(100);
- if(k2==0)
- {
- while(k2==0)
- {
- datapros();
- }
- a=0;
- At24c02Write(0x01,a);
- delayy(100);
- b=0;
- At24c02Write(0x03,b);
- delayy(100);
- c=0;
- At24c02Write(0x05,c);
- }
- while(!k2);
- }
- }
-
- void main()
- {
- ack();//開機(jī)取讀最新保存的數(shù)據(jù)
- while(1)
- {
- an(); //數(shù)據(jù)至0
- anjian(); //數(shù)據(jù)運(yùn)行
- datapros(); //數(shù)碼管顯示數(shù)據(jù)處理
- DigDisplay();//數(shù)碼管處理
- }
- }
- /*i2c.c文件*/
- #include"i2c.h"
- unsigned char I2cSend(unsigned char dat); //聲明函數(shù)
- unsigned char I2cRead();
- void Delay10us()//小延遲
- {
- unsigned char a,b;
- for(b=1;b>0;b--)
- for(a=2;a>0;a--);
- }
- void delay(int i) //大延遲
- {
- while(i--);
- }
- void I2cStart() //起始信號(hào)
- {
- SDA=1;
- Delay10us();
- SCL=1;
- Delay10us();//延遲時(shí)間,使SDA保持高位時(shí)間>4.7us后至低位
- SDA=0;
- Delay10us();//保持處于低位時(shí)間大于4us
- SCL=0;
- Delay10us();//起始之后SDA和SC要至0
- }
- void I2cStop() //終止信號(hào)
- {
- SDA=0;
- Delay10us(); //延遲SDA數(shù)據(jù)線處于低位時(shí)間,使SDA在低位時(shí)間>4us
- SCL=1;
- Delay10us();//延遲時(shí)間,使SCL在高位時(shí)間>4.7us
- SDA=1;
- Delay10us();//結(jié)束之后保持SDA和SCL都為1;表示總線空閑
- }
- unsigned char I2cSendByte(unsigned char dat) //發(fā)送字節(jié)
- {
- unsigned char a=0,b=0;
- for(a=0;a<8;a++)//要發(fā)送8位,從最高位開始
- {
- SDA=dat>>7; //dat的第一位右移7位,寫入SDA
- dat=dat<<1; //dat左移一位把高一位移除,相當(dāng)于dat從左到右依次寫到SDA
- Delay10us();
- SCL=1;
- Delay10us();//延遲時(shí)間,使SCL在高位時(shí)間>4.7us
- SCL=0;
- Delay10us();
- }
- SDA=1;
- Delay10us();
- SCL=1;
- while(SDA)//等待應(yīng)答,也就是等待從設(shè)備把SDA拉低
- {
- b++;
- if(b>200) //如果超過2000us沒有應(yīng)答發(fā)送失敗,或者為非應(yīng)答,表示接收結(jié)束
- {
- SCL=0;
- Delay10us(); //延時(shí)10us
- return 0; //發(fā)送失敗返回0
- }
- }
- SCL=0;
- Delay10us(); //延時(shí)10us
- return 1; //發(fā)送成功返回1
- }
- unsigned char I2cReadByte() //取讀一個(gè)字節(jié)
- {
- unsigned char a=0,dat=0;
- SDA=1; //起始和發(fā)送一個(gè)字節(jié)之后SCL都是0
- Delay10us();
- for(a=0;a<8;a++)//接收8個(gè)字節(jié)
- {
- SCL=1;
- Delay10us(); //dat左移并上SDA,相當(dāng)于SDA從低位寫入
- dat<<=1;
- dat|=SDA;
- Delay10us(); //延時(shí)10us
- SCL=0;
- Delay10us(); //延時(shí)10us
- }
- return dat; //接收完一個(gè)字節(jié)SCL=0,SDA=1
- }
- void At24c02Write(unsigned char addr,unsigned char dat)//將數(shù)據(jù)寫入一個(gè)地址中
- {
- I2cStart(); //開始
- I2cSendByte(0xa0);//發(fā)送寫器件地址
- I2cSendByte(addr);//發(fā)送要寫入內(nèi)存地址
- I2cSendByte(dat); //發(fā)送數(shù)據(jù)
- I2cStop(); //結(jié)束
- delay(1000); //等待數(shù)據(jù)穩(wěn)定寫入
- }
- unsigned char At24c02Read(unsigned char addr)//寫入取讀到的地址
- {
- unsigned char num;
- I2cStart(); //開始
- I2cSendByte(0xa0); //發(fā)送寫器件地址 0xa0為寫入標(biāo)志
- I2cSendByte(addr); //發(fā)送要讀取的地址 ,,先寫入要讀的地址
- I2cStart();
- I2cSendByte(0xa1); //發(fā)送讀器件地址 0xa1為讀標(biāo)志
- num=I2cReadByte(); //讀取數(shù)據(jù)
- I2cStop(); //結(jié)束
- return num;
- }
- /*i2c.h文件*/
- #include"i2c.h"
- unsigned char I2cSend(unsigned char dat); //聲明函數(shù)
- unsigned char I2cRead();
- void Delay10us()//小延遲
- {
- unsigned char a,b;
- for(b=1;b>0;b--)
- for(a=2;a>0;a--);
- }
- void delay(int i) //大延遲
- {
- while(i--);
- }
- void I2cStart() //起始信號(hào)
- {
- SDA=1;
- Delay10us();
- SCL=1;
- Delay10us();//延遲時(shí)間,使SDA保持高位時(shí)間>4.7us后至低位
- SDA=0;
- Delay10us();//保持處于低位時(shí)間大于4us
- SCL=0;
- Delay10us();//起始之后SDA和SC要至0
- }
- void I2cStop() //終止信號(hào)
- {
- SDA=0;
- Delay10us(); //延遲SDA數(shù)據(jù)線處于低位時(shí)間,使SDA在低位時(shí)間>4us
- SCL=1;
- Delay10us();//延遲時(shí)間,使SCL在高位時(shí)間>4.7us
- SDA=1;
- Delay10us();//結(jié)束之后保持SDA和SCL都為1;表示總線空閑
- }
- unsigned char I2cSendByte(unsigned char dat) //發(fā)送字節(jié)
- {
- unsigned char a=0,b=0;
- for(a=0;a<8;a++)//要發(fā)送8位,從最高位開始
- {
- SDA=dat>>7; //dat的第一位右移7位,寫入SDA
- dat=dat<<1; //dat左移一位把高一位移除,相當(dāng)于dat從左到右依次寫到SDA
- Delay10us();
- SCL=1;
- Delay10us();//延遲時(shí)間,使SCL在高位時(shí)間>4.7us
- SCL=0;
- Delay10us();
- }
- SDA=1;
- Delay10us();
- SCL=1;
- while(SDA)//等待應(yīng)答,也就是等待從設(shè)備把SDA拉低
- {
- b++;
- if(b>200) //如果超過2000us沒有應(yīng)答發(fā)送失敗,或者為非應(yīng)答,表示接收結(jié)束
- {
- SCL=0;
- Delay10us(); //延時(shí)10us
- return 0; //發(fā)送失敗返回0
- }
- }
- SCL=0;
- Delay10us(); //延時(shí)10us
- return 1; //發(fā)送成功返回1
- }
- unsigned char I2cReadByte() //取讀一個(gè)字節(jié)
- {
- unsigned char a=0,dat=0;
- SDA=1; //起始和發(fā)送一個(gè)字節(jié)之后SCL都是0
- Delay10us();
- for(a=0;a<8;a++)//接收8個(gè)字節(jié)
- {
- SCL=1;
- Delay10us(); //dat左移并上SDA,相當(dāng)于SDA從低位寫入
- dat<<=1;
- dat|=SDA;
- Delay10us(); //延時(shí)10us
- SCL=0;
- Delay10us(); //延時(shí)10us
- }
- return dat; //接收完一個(gè)字節(jié)SCL=0,SDA=1
- }
- void At24c02Write(unsigned char addr,unsigned char dat)//將數(shù)據(jù)寫入一個(gè)地址中
- {
- I2cStart(); //開始
- I2cSendByte(0xa0);//發(fā)送寫器件地址
- I2cSendByte(addr);//發(fā)送要寫入內(nèi)存地址
- I2cSendByte(dat); //發(fā)送數(shù)據(jù)
- I2cStop(); //結(jié)束
- delay(1000); //等待數(shù)據(jù)穩(wěn)定寫入
- }
- unsigned char At24c02Read(unsigned char addr)//寫入取讀到的地址
- {
- unsigned char num;
- I2cStart(); //開始
- I2cSendByte(0xa0); //發(fā)送寫器件地址 0xa0為寫入標(biāo)志
- I2cSendByte(addr); //發(fā)送要讀取的地址 ,,先寫入要讀的地址
- I2cStart();
- I2cSendByte(0xa1); //發(fā)送讀器件地址 0xa1為讀標(biāo)志
- num=I2cReadByte(); //讀取數(shù)據(jù)
- I2cStop(); //結(jié)束
- return num;
- }
復(fù)制代碼
|
評(píng)分
-
查看全部評(píng)分
|