利用模拟IIC读取AM1805得不到应答
时间:10-02
整理:3721RD
点击:
最近在项目中用到了时钟芯片AM1805(IIC接口),但是读出的数据一直是0XFF,经过仿真发现在写入指令后,单片机得不到AM1805的应答,已经调试三天了不知道问题在哪,希望大家帮忙看看,以下是我的程序
//IIC开始
void IIC_Start(void)
{
SDA_OUT(); //sda设置为输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//释放总线
delay_us(1);
}
//停止IIC
void IIC_Stop(void)
{
SDA_OUT();//sda设置为输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//释放总线
delay_us(4);
}
//等待从机应答
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA?????
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//????0
return 0;
}
//主机应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//主机不应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//向IIC写一个字节
void IIC_Write_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//
for(t=0;t<8;t++)
{
//IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
delay_us(2); //
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//读取一个字节
u8 IIC_Read_Byte(void)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
return receive;
}
void AM1805_Write_Addr(u8 REG_ADD)
{
IIC_Write_Byte(REG_ADD);//?/д??
IIC_Wait_Ack();
}
void AM1805_Write_Byte(u8 REG_ADD,u8 dat)
{
// IIC_Start();
IIC_Write_Byte(REG_ADD);//?/д??
IIC_Wait_Ack();
IIC_Write_Byte(dat);//????
IIC_Wait_Ack();
// IIC_Stop();
}
}
u8 IIC_Read_Byte(void)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
return receive;
}
uint8_t AM18XX_ReadOneByte(uint8_t ReadAddr)
{
uint8_t temp=0;
IIC_Start();//开始
IIC_Write_Byte(0xD2);//AM1805写命令
if(IIC_Wait_Ack())//等待应答
{
temp=1;
}
AM1805_Write_Addr(ReadAddr%256); ////写入操作地址
IIC_Wait_Ack();//等待应答
IIC_Start();//开始信号
IIC_Write_Byte(0xD3);//AM1805读取指令
IIC_Wait_Ack();//等待应答
temp= IIC_Read_Byte();//读取AM1805数据
IIC_Stop();//结束
return temp;
}
//IIC开始
void IIC_Start(void)
{
SDA_OUT(); //sda设置为输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//释放总线
delay_us(1);
}
//停止IIC
void IIC_Stop(void)
{
SDA_OUT();//sda设置为输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//释放总线
delay_us(4);
}
//等待从机应答
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA?????
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//????0
return 0;
}
//主机应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//主机不应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//向IIC写一个字节
void IIC_Write_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//
for(t=0;t<8;t++)
{
//IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
delay_us(2); //
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//读取一个字节
u8 IIC_Read_Byte(void)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
return receive;
}
void AM1805_Write_Addr(u8 REG_ADD)
{
IIC_Write_Byte(REG_ADD);//?/д??
IIC_Wait_Ack();
}
void AM1805_Write_Byte(u8 REG_ADD,u8 dat)
{
// IIC_Start();
IIC_Write_Byte(REG_ADD);//?/д??
IIC_Wait_Ack();
IIC_Write_Byte(dat);//????
IIC_Wait_Ack();
// IIC_Stop();
}
}
u8 IIC_Read_Byte(void)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
return receive;
}
uint8_t AM18XX_ReadOneByte(uint8_t ReadAddr)
{
uint8_t temp=0;
IIC_Start();//开始
IIC_Write_Byte(0xD2);//AM1805写命令
if(IIC_Wait_Ack())//等待应答
{
temp=1;
}
AM1805_Write_Addr(ReadAddr%256); ////写入操作地址
IIC_Wait_Ack();//等待应答
IIC_Start();//开始信号
IIC_Write_Byte(0xD3);//AM1805读取指令
IIC_Wait_Ack();//等待应答
temp= IIC_Read_Byte();//读取AM1805数据
IIC_Stop();//结束
return temp;
}
你这个代码时序是不是有点问题
示波器一测两跟线,啥问题都出来了
请问是什么问题?我现在还没有调试出来 不知道是哪的问题