#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;
}
望解答,急用!!!!!
|