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