|
#include <REGX51.H>
sbit I2C_SCL = P1^3;
sbit I2C_SDA = P1^4;
I2C:
//延時(shí)
void delay_us(unsigned char i)
{
while(i--);
}
// 開始信號(hào):在I2C_SCL時(shí)鐘信號(hào)在高電平期間I2C_SDA信號(hào)產(chǎn)生一個(gè)下降沿
void I2C_Start()
{
I2C_SDA=1;
delay_us(1);
I2C_SCL=1;
delay_us(1);//保持時(shí)間>4.7us
I2C_SDA=0;
delay_us(1);//保持時(shí)間是>4us
I2C_SCL=0;
delay_us(1);
}
//結(jié)束信號(hào):在I2C_SCL時(shí)鐘信號(hào)高電平期間I2C_SDA信號(hào)產(chǎn)生一個(gè)上升沿
void I2C_Stop()
{
I2C_SDA=0;
delay_us(1);
I2C_SCL=1;
delay_us(1);
I2C_SDA=1;
delay_us(1);
}
//通過I2C發(fā)送一個(gè)字節(jié)。在I2C_SCL時(shí)鐘信號(hào)高電平期間, 保持發(fā)送信號(hào)I2C_SDA保持穩(wěn)定
unsigned char I2C_SendByte(unsigned char dat, unsigned char ack)
{
unsigned char a = 0,b = 0;
for(a=0; a<8; a++)//要發(fā)送8位,從最高位開始
{
I2C_SDA=dat>>7;
dat=dat<<1;//傳輸
delay_us(1);
I2C_SCL=1;
delay_us(1);
I2C_SCL=0;
delay_us(1);
}
I2C_SDA=1;
delay_us(1);
I2C_SCL=1;
delay_us(1);
while(I2C_SDA&&(ack==1))//等待應(yīng)答
{
b++;
if(b>255) //如果超過255us沒有應(yīng)答發(fā)送失敗,或者為非應(yīng)答,表示接收結(jié)束
{
I2C_SCL=0;
delay_us(1);
return 0;
}
}
I2C_SCL=0;
delay_us(1);
return 1;
}
// 使用I2c讀取一個(gè)字節(jié)
unsigned char I2C_ReadByte()
{
unsigned char a = 0,dat = 0;
I2C_SDA = 1;//時(shí)序
delay_us(1);
for(a=0; a<8; a++)//接收8個(gè)字節(jié)
{
I2C_SCL = 1;
delay_us(1);
dat<<=1;
dat|=I2C_SDA;
delay_us(1);
I2C_SCL=0;
delay_us(1);
}
return dat;
}
//往24c02的一個(gè)地址寫入一個(gè)數(shù)據(jù)
void At24c02Write(unsigned char addr,unsigned char dat)
{
I2C_Start();
I2C_SendByte(0xa0,1);//發(fā)送寫器件地址
I2C_SendByte(addr,1);//發(fā)送要寫入內(nèi)存地址
I2C_SendByte(dat,0); //發(fā)送數(shù)據(jù)
I2C_Stop();
}
// 讀取24c02的一個(gè)地址的一個(gè)數(shù)據(jù)
unsigned char At24c02Read(unsigned char addr)
{
unsigned char num;
I2C_Start();
I2C_SendByte(0xa0, 1); //發(fā)送寫器件地址
I2C_SendByte(addr, 1); //發(fā)送要讀取的地址
I2C_Start();
I2C_SendByte(0xa1, 1); //發(fā)送讀器件地址
num=I2C_ReadByte(); //讀取數(shù)據(jù)
I2C_Stop();
return num;
}
這個(gè)I2C時(shí)序應(yīng)該沒寫錯(cuò)吧,下面是我的掉電存儲(chǔ)函數(shù):
從主函數(shù)中截出來的
unsigned int shangxian=35;unsigned int xiaxian=10;
unsigned char set_st=0;
unsigned char As=0,Ds=0;//As是第二個(gè)按鍵(加一ADD)按下的次數(shù),Ds是第三個(gè)按鍵(減一)按下的次數(shù)
//{
// while(1)
// {
// if(set_st==0) //設(shè)置按鍵按下,等待
// while(1);
// else if(set_st==1)//轉(zhuǎn)到上限設(shè)置
// {
// if(As--){
// shangxian=shangxian+As;
// At24c02Write(2,shangxian);
// shangxian=At24c02Read(2);}
// else if(Ds--){
// shangxian=shangxian-Ds;
// At24c02Write(3,shangxian);
// shangxian=At24c02Read(3);}
// }
// else if(set_st==2)//轉(zhuǎn)到下限設(shè)置
// {
// if(As--){
// xiaxian=xiaxian+As;
// At24c02Write(4,xiaxian);
// xiaxian=At24c02Read(4);}
// else if(Ds--){
// xiaxian=xiaxian-Ds;
// At24c02Write(5,xiaxian);
// xiaxian=At24c02Read(5);}
// }
// }
//}
而As的外部中斷函數(shù):
void Xint0 () interrupt 0//外部中斷0------
{
EX0=0;
if(ADD==0&&set_st==1){//進(jìn)入上限第二個(gè)按鍵按下,增大上限值
do{
display_anjian(shangxian,set_st);
}
while(ADD==0);//設(shè)置范圍
As++;
shangxian=shangxian+1;
if(shangxian>99)
shangxian=99;}
else if(ADD==0&&set_st==2)//進(jìn)入下限第二個(gè)按鍵按下,增大下限值
{
do{
display_anjian(xiaxian,set_st);
}
while(ADD==0);//設(shè)置范圍
xiaxian=xiaxian+1;
if(xiaxian>shangxian)
xiaxian=shangxian;
}
望解答,急用。。。。
|
|