[原]MC9S32AW中使用的模拟I2C
0赞
发表于 11/8/2011 11:29:35 AM
阅读(3029)
这个是飞思卡尔的MC9S32AW中使用的模拟I2C的代码,跟之前所发的I2C是类似的,如果是遇到I2C通讯问题的话,可以使用
示波器或是逻辑分析仪来分析波形,大部分问题都应该能解决的。
#define SDA_HIGH() PTED_PTED1 = 1
#define SDA_LOW() PTED_PTED1 = 0
#define SCL_HIGH() PTED_PTED0 = 1
#define SCL_LOW() PTED_PTED0 = 0
#define SDA_INPUT() PTEDD_PTEDD1 = 0
#define SDA_OUTPUT() PTEDD_PTEDD1 = 1
#define SCL_LOW() PTED_PTED0 = 0
#define SDA_INPUT() PTEDD_PTEDD1 = 0
#define SDA_OUTPUT() PTEDD_PTEDD1 = 1
#define SDA_VALUE() PTED_PTED1
void IIC_Start(void)
{
SDA_OUTPUT();
reset_watchdog();
SDA_HIGH();
SCL_HIGH();
SDA_LOW();
SCL_LOW();
}
void IIC_Write8Bit(u8 data)
{
u8 i;
SDA_OUTPUT();
reset_watchdog();
for(i=0;i<8;i++)
{
if(data&0x80)
{
SDA_HIGH();
}
else
{
SDA_LOW();
}
SCL_HIGH();
SCL_LOW();
data=data<<1;//shift left
}
SDA_INPUT();
reset_watchdog();
}
{
u8 i;
SDA_OUTPUT();
reset_watchdog();
for(i=0;i<8;i++)
{
if(data&0x80)
{
SDA_HIGH();
}
else
{
SDA_LOW();
}
SCL_HIGH();
SCL_LOW();
data=data<<1;//shift left
}
SDA_INPUT();
reset_watchdog();
}
//读取1个字节
u8 IIC_Read_8Bit(void)
{
u8 i,data=0;
SDA_INPUT();
reset_watchdog();
for(i=0;i<8;i++)
{
data <<= 1;
SCL_HIGH();
if(SDA_VALUE())//if(SDA==1)
{
data |= 0x01;
}
else
{
}
SCL_LOW();
}
return(data);
}
u8 IIC_Read_8Bit(void)
{
u8 i,data=0;
SDA_INPUT();
reset_watchdog();
for(i=0;i<8;i++)
{
data <<= 1;
SCL_HIGH();
if(SDA_VALUE())//if(SDA==1)
{
data |= 0x01;
}
else
{
}
SCL_LOW();
}
return(data);
}
//停止
void IIC_Stop(void)
{
SDA_OUTPUT();
reset_watchdog();
SDA_LOW();
SCL_HIGH();
SDA_HIGH();
}
void IIC_Stop(void)
{
SDA_OUTPUT();
reset_watchdog();
SDA_LOW();
SCL_HIGH();
SDA_HIGH();
}
//发送应答
void IIC_ACK(void)
{
SDA_OUTPUT();
reset_watchdog();
SDA_LOW();//
SCL_HIGH();
SCL_LOW();//
}
//发送非应答位
void IIC_NOACK(void)
{
SDA_OUTPUT();
reset_watchdog();
SDA_HIGH();//SDA=1
SCL_HIGH();//SCL=1
SCL_LOW();//SCL=0
}
void IIC_ACK(void)
{
SDA_OUTPUT();
reset_watchdog();
SDA_LOW();//
SCL_HIGH();
SCL_LOW();//
}
//发送非应答位
void IIC_NOACK(void)
{
SDA_OUTPUT();
reset_watchdog();
SDA_HIGH();//SDA=1
SCL_HIGH();//SCL=1
SCL_LOW();//SCL=0
}
u8 IIC_CheckACK(void)
{
u8 ack_flag;
SCL_HIGH();
reset_watchdog();
reset_watchdog();
if(SDA_VALUE())//if(SDA==1)
{
ack_flag = false; //没有响应
}
else
{
ack_flag = true;//响应
}
SCL_LOW();//SCL=0
return ack_flag;
}
}
u8 AT24Cx_read(u16 adr)
{
u8 temp;
u8 addr[2];
u8 len;
addr[0]= (u8)((adr& 0xFF00) >> 8);
addr[1]= (u8)(adr& 0x00FF);
Read_Success_Flag = false;
IIC_Start(); //I2C启动
IIC_Write8Bit(DEVICE_ADR); //器件地址和写方式
if(IIC_CheckACK() == false) {IIC_Stop();return false;}//检查从机响应
for(len=0;len<2;len++)
{
IIC_Write8Bit(addr[len]);
if(IIC_CheckACK() == false) {IIC_Stop();return false;}
}
IIC_Start(); //重新启动
IIC_Write8Bit(DEVICE_ADR+1); //从器件地址和读方式
if(IIC_CheckACK() == false) {IIC_Stop();return false;}//检查从机响应
temp = IIC_Read_8Bit();
IIC_NOACK(); //读到数,由于是单字节,所以就不应答
IIC_Stop(); //停止
{
u8 temp;
u8 addr[2];
u8 len;
addr[0]= (u8)((adr& 0xFF00) >> 8);
addr[1]= (u8)(adr& 0x00FF);
Read_Success_Flag = false;
IIC_Start(); //I2C启动
IIC_Write8Bit(DEVICE_ADR); //器件地址和写方式
if(IIC_CheckACK() == false) {IIC_Stop();return false;}//检查从机响应
for(len=0;len<2;len++)
{
IIC_Write8Bit(addr[len]);
if(IIC_CheckACK() == false) {IIC_Stop();return false;}
}
IIC_Start(); //重新启动
IIC_Write8Bit(DEVICE_ADR+1); //从器件地址和读方式
if(IIC_CheckACK() == false) {IIC_Stop();return false;}//检查从机响应
temp = IIC_Read_8Bit();
IIC_NOACK(); //读到数,由于是单字节,所以就不应答
IIC_Stop(); //停止
delay_ms(5);
Read_Success_Flag = true;
return temp;
}
Read_Success_Flag = true;
return temp;
}
u8 AT24Cx_write(u16 adr, u8 dat)
{
u8 addr[2];
u8 len;
addr[0]= (u8)((adr& 0xFF00) >> 8);
addr[1]= (u8)(adr& 0x00FF);
{
u8 addr[2];
u8 len;
addr[0]= (u8)((adr& 0xFF00) >> 8);
addr[1]= (u8)(adr& 0x00FF);
IIC_Start(); //启动
IIC_Write8Bit(DEVICE_ADR); //从器件地址和写方式
if(IIC_CheckACK() == false) {IIC_Stop();return false;}//检查从机响应
for(len=0;len<2;len++)
{
IIC_Write8Bit(addr[len]);
if(IIC_CheckACK() == false) {IIC_Stop();return false;}
}
IIC_Write8Bit(dat); //写数据
if(IIC_CheckACK() == false) {IIC_Stop();return false;}
IIC_Stop(); //停止
delay_ms(10); //延时等写完
IIC_Write8Bit(DEVICE_ADR); //从器件地址和写方式
if(IIC_CheckACK() == false) {IIC_Stop();return false;}//检查从机响应
for(len=0;len<2;len++)
{
IIC_Write8Bit(addr[len]);
if(IIC_CheckACK() == false) {IIC_Stop();return false;}
}
IIC_Write8Bit(dat); //写数据
if(IIC_CheckACK() == false) {IIC_Stop();return false;}
IIC_Stop(); //停止
delay_ms(10); //延时等写完
return true;
}
