天天

[原]MC9S32AW中使用的模拟I2C

0
阅读(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  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();
}
//读取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);
}
//停止
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
}

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();                      //停止
 delay_ms(5);
 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);
 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);    //延时等写完
 return true;
}