我用的是模拟I2C
下面是代码 希望各位能帮我看看有没有什么问题?谢谢了
/*--------------------------------------------------------------------------------
管脚高低电平模拟
函数说明:该部分程序主要在SDA和SCL管脚上模拟输出高电平或者低电平,下面为具体的程序
---------------------------------------------------------------------------------*/
void I2C_Set_sda_high(void)
{
//将SDA设置为输出模式
P1DIR|=SDA;
//SDA管脚输出为高电平
P1OUT|=SDA;
_NOP();
_NOP();
return;
}
void I2C_Set_sda_low(void)
{
//将SDA设置为输出模式
P1DIR|=SDA;
//SDA管脚输出为低电平
P1OUT&=~(SDA);
_NOP();
_NOP();
return;
}
void I2C_Set_sck_high(void)
{
//将SCL设置为输出模式
P1DIR|=SCL;
//SCL管脚输出为高电平
P1OUT|=SCL;
_NOP();
_NOP();
return;
}
void I2C_Set_sck_low(void)
{
//将SCL设置为输出模式
P1DIR|=SCL;
//SCL管脚输出为低电平
P1OUT&=~(SCL);
_NOP();
_NOP();
return;
}
//延时函数
void Delay_ms(unsigned long nValue)//以毫秒为单位,8Mhz为主时钟频率
{
unsigned long nCount;
int i;
unsigned long j;
nCount=2667;
for (i=nValue;i>0;i--)
{
for(j=nCount;j>0;j--);
}
return;
}
/*--------------------------------------------------------------------------------
起始条件及停止条件的产生
说明:通过以上高低电平产生函数,就可以实现I2C的基本操作,比如起始条件的产生和停止条件的产生
下面介绍具体的实现
---------------------------------------------------------------------------------*/
void I2C_START(void)
{
int i;
I2C_Set_sda_high();
for(i=10;i>0;i--);
I2C_Set_sck_high();
for(i=10;i>0;i--);
I2C_Set_sda_low();
for(i=10;i>0;i--);
I2C_Set_sck_low();
return;
}
void I2C_STOP(void)
{
int i;
I2C_Set_sda_low();
for(i=10;i>0;i--);
I2C_Set_sck_low();
for(i=10;i>0;i--);
I2C_Set_sck_high();
for(i=10;i>0;i--);
I2C_Set_sda_high();
for(i=10;i>0;i--);
I2C_Set_sck_low();
//延迟一点时间
Delay_ms(10);
return;
}
void I2C_Initial(void)
{
P1DIR=0x00;
P1OUT=0x00;
//将SCL管脚设置为输出管脚
P1DIR|=SCL;
I2C_Set_sck_low();
I2C_STOP();
Delay_ms(10);
return;
}
//确认处理
int I2C_GetACK(void)
{
int nTemp=0;
int j;
_NOP();
_NOP();
I2C_Set_sck_low();
for(j=30;j>0;j--);
//将SDA设置为输入方向
P1DIR&=~(SDA);
I2C_Set_sck_high();
for (j=30;j>0;j--);
//获得数据
nTemp=(int)(P1IN&SDA);
I2C_Set_sck_low();
return(nTemp&SDA);
}
//上面程序是主设备接受来自从设备的确认信号
void I2C_SetACK(void)
{
I2C_Set_sck_low();
I2C_Set_sda_low();
I2C_Set_sck_high();
I2C_Set_sck_low();
return;
}
void I2C_SetNAK(void)
{
I2C_Set_sck_low();
I2C_Set_sda_high();
I2C_Set_sck_high();
I2C_Set_sck_low();
return;
}
//上面的程序分别为主设备向从设备发送肯定和否定的确认信号
//数据发送可以从字节的高位开始也可以从低位开始。下面编写的程序是从高位开始发送的
void I2C_TxByte(int nValue)
{
int i;
int j;
//从高字节开始发送
for(i=0;i<8;i++)
{
if(nValue&0x80)
I2C_Set_sda_high();
else
I2C_Set_sda_low();
for(j=30;j>0;j--);
I2C_Set_sck_hig h();
nValue<<=1;
for(j=30;j>0;j--);
I2C_Set_sck_low();
}
return;
}
//数据接收可以从高位开始也可以从低位开始,本次编程是从字节的高位开始发送的
int I2C_RxByte(void)
{
int nTemp=0;
int i;
int j;
I2C_Set_sda_high();
//将SDA管脚设置为输入方向
P1DIR&=~(SDA);
_NOP();
_NOP();
_NOP();
_NOP();
//从高字节开始接收
for(i=0;i<8;i++)
{
I2C_Set_sck_high();
if(P1IN&SDA)
{
nTemp|=(0x01<<(7-i));
}
for(j=30;j>0;j--);
I2C_Set_sck_low();
}
return nTemp;
}
//读温度传感器
/*----------------------------------------------------------------------------------------------------
温度值寄存器是一个16位只读寄存器,它的高10位以2的补码格式储存由AD转换器送来的10位温度读
数。位5至0未用
-128℃ 10 0000 0000
-125℃ 10 0000 1100
-100℃ 10 0111 0000
-75℃ 10 1101 0100
-50℃ 11 0011 1000
-25℃ 11 1001 1100
-0.25℃ 11 1111 1111
0℃ 00 0000 0000
+0.25℃ 00 0000 0001
+10℃ 0 0001 01000
+25℃ 0 0011 00100
+50℃ 0 0110 01000
+75℃ 0 1001 01100
+100℃ 0 1100 10000
+125℃ 0 1111 10100
+127℃ 0 1111 11100
------------------------------------------------------------------------------------------------*/
//温度测量程序
int I2C_ReadTemp(void)
{
int temp=0;
char hi;
char lo;
//起始信号
I2C_START();
//发送写命令
I2C_TxByte(0x90);
//读取ACK
temp=I2C_GetACK();
//写入指针寄存器
//指向温度寄存器
I2C_TxByte(0x00);
//读取ACK
temp=I2C_GetACK();
//发送读命令
I2C_TxByte(0x91);
//读取ACK
temp=I2C_GetACK();
//读高字节
hi=I2C_RxByte();
//发送ACK
I2C_SetACK();
//读低字节
lo=I2C_RxByte();
//发送NAK
I2C_SetNAK();
//将高低字节组合成一个整数
temp=hi*256+lo;
//低6位数据无效
temp>>=6;
//停止信号
I2C_STOP();
return temp;
}
现在问题就是读不出数据……然后我现在也分不清是软件问题还是硬件问题。只能求助大家看看软件是不是有问题,再次谢谢各位了
可能有点多,但是希望大家能耐着性子看看 关于AD7416的介绍 会给出附件
硬件电路也附在帖子里,不知道怎么检查硬件电路。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>