欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
單片機IIC的簡單應用
[打印本頁]
作者:
108880802
時間:
2020-6-17 20:17
標題:
單片機IIC的簡單應用
/*利用IIC總線接口底層驅動代碼,設計應用程序,實現下面功能:1.系統開機后,讀取0x01、0x03和0x05 內存單元的數據,并從左至右顯示在數碼管上, .數字之間用“-”分隔,
2.將0x01單元的數據加1后,寫回該內存單元,使用按鍵s1加1后結果如大于10,恢復0.0x03單元的數據加2后,寫回該內存單元, .加2后結果如大于20,恢復0。將0x05單元的數據加3后,寫回該內存單元,加3后結果如大于30,恢復0。*/
/*main.c文件*/
#include "reg51.h"
#include "i2c.h"
typedef unsigned int u16; //對數據類型進行聲明定義
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) //位選,選擇點亮的數碼管,
{
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()//數碼管數據的處理
{
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() //取讀保存在地址內的數據
{
a=At24c02Read(0x01);
b=At24c02Read(0x03);
c=At24c02Read(0x05);
}
void anjian()
{
if(k1==0)
{
delayy(1000);
if(k1==0)
{
a=At24c02Read(0x01); //將0X01地址內的數據賦給A
a++;
if(a>10)
{
a=0;
}
At24c02Write(0x01,a); //將A數據寫入0x01的地址中去
delayy(1000);
b=At24c02Read(0x03); //將0X03地址內的數據賦給B
b=b+2;
if(b>20)
{
b=0;
}
At24c02Write(0x03,b); //將B的數據寫入0x03的地址中去
delayy(1000);
c=At24c02Read(0x05); //將0X05地址內的數據賦給C
c=c+3;
if(c>30)
{
c=0;
}
At24c02Write(0x05,c); //將C的數據寫入0x05的地址中去
delayy(1000);
}
while(!k1);
}
}
void an() //將數據都至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();//開機取讀最新保存的數據
while(1)
{
an(); //數據至0
anjian(); //數據運行
datapros(); //數碼管顯示數據處理
DigDisplay();//數碼管處理
}
}
/*i2c.c文件*/
#include"i2c.h"
unsigned char I2cSend(unsigned char dat); //聲明函數
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() //起始信號
{
SDA=1;
Delay10us();
SCL=1;
Delay10us();//延遲時間,使SDA保持高位時間>4.7us后至低位
SDA=0;
Delay10us();//保持處于低位時間大于4us
SCL=0;
Delay10us();//起始之后SDA和SC要至0
}
void I2cStop() //終止信號
{
SDA=0;
Delay10us(); //延遲SDA數據線處于低位時間,使SDA在低位時間>4us
SCL=1;
Delay10us();//延遲時間,使SCL在高位時間>4.7us
SDA=1;
Delay10us();//結束之后保持SDA和SCL都為1;表示總線空閑
}
unsigned char I2cSendByte(unsigned char dat) //發送字節
{
unsigned char a=0,b=0;
for(a=0;a<8;a++)//要發送8位,從最高位開始
{
SDA=dat>>7; //dat的第一位右移7位,寫入SDA
dat=dat<<1; //dat左移一位把高一位移除,相當于dat從左到右依次寫到SDA
Delay10us();
SCL=1;
Delay10us();//延遲時間,使SCL在高位時間>4.7us
SCL=0;
Delay10us();
}
SDA=1;
Delay10us();
SCL=1;
while(SDA)//等待應答,也就是等待從設備把SDA拉低
{
b++;
if(b>200) //如果超過2000us沒有應答發送失敗,或者為非應答,表示接收結束
{
SCL=0;
Delay10us(); //延時10us
return 0; //發送失敗返回0
}
}
SCL=0;
Delay10us(); //延時10us
return 1; //發送成功返回1
}
unsigned char I2cReadByte() //取讀一個字節
{
unsigned char a=0,dat=0;
SDA=1; //起始和發送一個字節之后SCL都是0
Delay10us();
for(a=0;a<8;a++)//接收8個字節
{
SCL=1;
Delay10us(); //dat左移并上SDA,相當于SDA從低位寫入
dat<<=1;
dat|=SDA;
Delay10us(); //延時10us
SCL=0;
Delay10us(); //延時10us
}
return dat; //接收完一個字節SCL=0,SDA=1
}
void At24c02Write(unsigned char addr,unsigned char dat)//將數據寫入一個地址中
{
I2cStart(); //開始
I2cSendByte(0xa0);//發送寫器件地址
I2cSendByte(addr);//發送要寫入內存地址
I2cSendByte(dat); //發送數據
I2cStop(); //結束
delay(1000); //等待數據穩定寫入
}
unsigned char At24c02Read(unsigned char addr)//寫入取讀到的地址
{
unsigned char num;
I2cStart(); //開始
I2cSendByte(0xa0); //發送寫器件地址 0xa0為寫入標志
I2cSendByte(addr); //發送要讀取的地址 ,,先寫入要讀的地址
I2cStart();
I2cSendByte(0xa1); //發送讀器件地址 0xa1為讀標志
num=I2cReadByte(); //讀取數據
I2cStop(); //結束
return num;
}
/*i2c.h文件*/
#include"i2c.h"
unsigned char I2cSend(unsigned char dat); //聲明函數
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() //起始信號
{
SDA=1;
Delay10us();
SCL=1;
Delay10us();//延遲時間,使SDA保持高位時間>4.7us后至低位
SDA=0;
Delay10us();//保持處于低位時間大于4us
SCL=0;
Delay10us();//起始之后SDA和SC要至0
}
void I2cStop() //終止信號
{
SDA=0;
Delay10us(); //延遲SDA數據線處于低位時間,使SDA在低位時間>4us
SCL=1;
Delay10us();//延遲時間,使SCL在高位時間>4.7us
SDA=1;
Delay10us();//結束之后保持SDA和SCL都為1;表示總線空閑
}
unsigned char I2cSendByte(unsigned char dat) //發送字節
{
unsigned char a=0,b=0;
for(a=0;a<8;a++)//要發送8位,從最高位開始
{
SDA=dat>>7; //dat的第一位右移7位,寫入SDA
dat=dat<<1; //dat左移一位把高一位移除,相當于dat從左到右依次寫到SDA
Delay10us();
SCL=1;
Delay10us();//延遲時間,使SCL在高位時間>4.7us
SCL=0;
Delay10us();
}
SDA=1;
Delay10us();
SCL=1;
while(SDA)//等待應答,也就是等待從設備把SDA拉低
{
b++;
if(b>200) //如果超過2000us沒有應答發送失敗,或者為非應答,表示接收結束
{
SCL=0;
Delay10us(); //延時10us
return 0; //發送失敗返回0
}
}
SCL=0;
Delay10us(); //延時10us
return 1; //發送成功返回1
}
unsigned char I2cReadByte() //取讀一個字節
{
unsigned char a=0,dat=0;
SDA=1; //起始和發送一個字節之后SCL都是0
Delay10us();
for(a=0;a<8;a++)//接收8個字節
{
SCL=1;
Delay10us(); //dat左移并上SDA,相當于SDA從低位寫入
dat<<=1;
dat|=SDA;
Delay10us(); //延時10us
SCL=0;
Delay10us(); //延時10us
}
return dat; //接收完一個字節SCL=0,SDA=1
}
void At24c02Write(unsigned char addr,unsigned char dat)//將數據寫入一個地址中
{
I2cStart(); //開始
I2cSendByte(0xa0);//發送寫器件地址
I2cSendByte(addr);//發送要寫入內存地址
I2cSendByte(dat); //發送數據
I2cStop(); //結束
delay(1000); //等待數據穩定寫入
}
unsigned char At24c02Read(unsigned char addr)//寫入取讀到的地址
{
unsigned char num;
I2cStart(); //開始
I2cSendByte(0xa0); //發送寫器件地址 0xa0為寫入標志
I2cSendByte(addr); //發送要讀取的地址 ,,先寫入要讀的地址
I2cStart();
I2cSendByte(0xa1); //發送讀器件地址 0xa1為讀標志
num=I2cReadByte(); //讀取數據
I2cStop(); //結束
return num;
}
復制代碼
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1