打印
[Kinetis]

I2C模拟驱动

[复制链接]
674|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ccw1986|  楼主 | 2016-1-22 21:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
*******************************************************************************
*
*
*
******************************************************************************/

#include "sw_iic.h"

//----I2C Variables -------------------------------------------------------
byte ak1=NACK;
byte ak2=NACK;
byte ak3=NACK;
//-------------------------------------------------------------------------

/**************************************************************
*        Function:         Delay
*        Parameters: 16-bit delay value
*        Return:                none
*
*        Simple delay loop.
**************************************************************/
void SwIIC_Delay(byte count)
{
        byte i;
        for (i=0; i<count; i++)
        {
    //asm nop;           
        }
}

/**************************************************************
*        Function:         Wait
*        Parameters: 8-bit delay value
*        Return:                none
*
*        Simple delay loop. Little longer than delay function.
**************************************************************/
void SwIIC_Wait(byte loop)
{
while(--loop);
{                     
    //asm nop;      
}
}

/**************************************************************
*        Function:         SwIIC_Init
*        Parameters: none
*        Return:                none
*
*        Function initialize sw IIC interface
**************************************************************/
void SwIIC_Init(void)
{
  SCL_D = P_IN;
  SDA_D = P_IN;
  SS_D = P_OUT;
  SCL_PU = PU_ON;
  SDA_PU = PU_ON;
  SS=1;                 
}

/**************************************************************
*        Function:         IIC_DATA_0                 
*        Parameters: none
*        Return:                none
*
*        Physical layer of IIC - Write '0' on bus   
**************************************************************/
void IIC_DATA_0(void)
{
  word i = 0;
  
  SDA = 0;
  SDA_D = P_OUT;
  SwIIC_Wait(SDA_HOLD);
  SCL_D = P_IN;
  while((!SCL) && (i++ < MAX_IIC_TIMEOUT));
  SwIIC_Wait(SCL_HOLD);
  SCL = 0;
  SCL_D = P_OUT;
  SwIIC_Wait(SCL_HOLD);
}

/**************************************************************
*        Function:         IIC_DATA_1               
*        Parameters: none
*        Return:                none
*
*        Physical layer of IIC - Write '1' on bus   
**************************************************************/
void IIC_DATA_1(void)
{
  word i = 0;
  
  SDA_D = P_IN;
  SwIIC_Wait(SDA_HOLD);
  SCL_D = P_IN;
  while((!SCL) && (i++ < MAX_IIC_TIMEOUT));
  SwIIC_Wait(SCL_HOLD);
  SCL = 0;
  SCL_D = P_OUT;
  SwIIC_Wait(SCL_HOLD);
}

/**************************************************************
*        Function:         IIC_GetBit                       
*        Parameters: none
*        Return:                value of bit on bus
*
*        Physical layer of IIC - Read a bit from bus IIC
**************************************************************/
byte IIC_GetBit(void)
{
  byte level;
  word i = 0;

  SDA_D = P_IN;
  SwIIC_Wait(SDA_HOLD);
  SCL_D = P_IN;
  while((!SCL) && (i++ < MAX_IIC_TIMEOUT));
  SwIIC_Wait(SCL_HOLD);
  level = SDA;
  SCL = 0;
  SCL_D = P_OUT;
  SwIIC_Wait(SCL_HOLD);
  return level;  
}


相关帖子

沙发
ccw1986|  楼主 | 2016-1-22 21:03 | 只看该作者
/**************************************************************
*        Function:         IIC_START                  
*        Parameters: none
*        Return:                none
*
*        Physical layer of IIC - Set up START condition on bus
**************************************************************/
void IIC_START(void)
{
  SDA = 0;
  SDA_D = P_OUT;
  SwIIC_Wait(SDA_HOLD);
  SCL = 0;
  SCL_D = P_OUT;
  SwIIC_Wait(SCL_HOLD);
}

/**************************************************************
*        Function:         IIC_REPEAT_START              
*        Parameters: none
*        Return:                none
*
*        Physical layer of IIC - Set up REPEAT_START condition on bus
**************************************************************/
void IIC_REPEAT_START(void)
{
  word i = 0;
  
  SDA_D = P_IN;
  SwIIC_Wait(SDA_HOLD);
  SCL_D = P_IN;
  while((!SCL) && (i++ < MAX_IIC_TIMEOUT));
  SwIIC_Wait(SCL_HOLD);
  IIC_START();
}

/**************************************************************
*        Function:         IIC_STOP                       
*        Parameters: none
*        Return:                none
*
*        Physical layer of IIC - Set up STOP condition on bus
**************************************************************/
void IIC_STOP(void)
{
  word i = 0;
  
  SDA = 0;
  SDA_D = P_OUT;
  SwIIC_Wait(SDA_HOLD);
  SCL_D = P_IN;
  while((!SCL) && (i++ < MAX_IIC_TIMEOUT));
  SwIIC_Wait(SCL_HOLD);
  SDA_D = P_IN;
  SwIIC_Wait(SDA_HOLD);
}

/**************************************************************
*        Function:         SwIIC_SendAddressWrite         
*        Parameters: tx_byte
*        Return:                none
*
*        Send device address on bus with write flag
**************************************************************/
void SwIIC_SendAddressWrite(byte tx_byte)
{
  byte k;

  tx_byte <<= 1;   
  tx_byte &= 0xfe;  

  for(k=8;k>0;k--)   
  {                                
    if (tx_byte & 0x80)            
      IIC_DATA_1();               
    else
      IIC_DATA_0();
    tx_byte <<= 1;
  }
  ak1=IIC_GetBit();
}
   

/**************************************************************
*        Function:         SwIIC_SendAddressRead           
*        Parameters: tx_byte
*        Return:                none
*
*        Send device address on bus with read flag
**************************************************************/
void SwIIC_SendAddressRead(byte tx_byte)
{
  byte k;           

  tx_byte <<= 1;      
  tx_byte |= 0x01;   
                                          
  for(k=8;k>0;k--)   
  {                                                                    
    if (tx_byte & 0x80)                                                
      IIC_DATA_1();
    else
      IIC_DATA_0();
    tx_byte <<= 1;
  }
  ak3=IIC_GetBit();
}
   
/**************************************************************
*        Function:         SwIIC_SendRegister               
*        Parameters: tx_byte
*        Return:                none
*
*        Send device internal register address on bus  
**************************************************************/   
void SwIIC_SendRegister(byte tx_byte)
{
  byte k;
      
  for(k=8;k>0;k--)   
  {         
    if (tx_byte & 0x80)
      IIC_DATA_1();
    else
      IIC_DATA_0();
    tx_byte <<= 1;
  }
  ak2=IIC_GetBit();
}

使用特权

评论回复
板凳
ccw1986|  楼主 | 2016-1-22 21:04 | 只看该作者
/**************************************************************
*        Function:         IIC_ReadByte                    
*        Parameters: ack
*        Return:                val
*
*        Read a byte from IIC bus  
**************************************************************/
byte IIC_ReadByte(byte ack)      
{                                 
byte i, val;

  for(i=8; i>0; i--)
  {
    val <<= 1;
    val |= IIC_GetBit();
  }
  
  if (ack == IIC_ACK)            
    IIC_DATA_0();               
  else
    IIC_DATA_1();               
                                                                     
  return val;  
}

/**************************************************************
*        Function:         IIC_SendByte                     
*        Parameters: tx_byte
*        Return:                none
*
*        Write a byte to IIC bus  
**************************************************************/
void IIC_SendByte(byte tx_byte)
{
  byte k;      

  for(k=8;k>0;k--)   
  {         
    if (tx_byte & 0x80)
      IIC_DATA_1();
    else
      IIC_DATA_0();
    tx_byte <<= 1;
  }
  ak3=IIC_GetBit();
}

byte IIC_SendByteM(byte tx_byte)
{
  byte k;      

  for(k=8;k>0;k--)   
  {         
    if (tx_byte & 0x80)
      IIC_DATA_1();
    else
      IIC_DATA_0();
    tx_byte <<= 1;
  }
  
  ak3=IIC_GetBit();
  
  return(ak3);
}

/**************************************************************
*        Function:         SwIIC_ReadByte                  
*        Parameters: RegAdd
*        Return:                none
*
*        Complete data transfer - read a byte from device register
* Note: Secured routine through check of acknowledge
**************************************************************/
byte SwIIC_ReadByte(byte RegAdd)                        
{  
      byte temp;
      ak1=NACK;
      ak2=NACK;
      ak3=NACK;
     
      while(!(ak3==ACK))
      {   
        IIC_START();
        SwIIC_Delay(START_DELAY);                 
        SwIIC_SendAddressWrite(ION_ADDR);
        SwIIC_Delay(ADDRESS_DELAY);  
          if(!ak1)                                   
          {
          SwIIC_SendRegister(RegAdd);
              if(!ak2)                              
              {      
              IIC_REPEAT_START();
              SwIIC_Delay(START_DELAY);           
              SwIIC_SendAddressRead(ION_ADDR);
              if(!ak3) temp=IIC_ReadByte(IIC_NACK);  
              }
          }
      IIC_STOP();
      ak1=NACK;
      ak2=NACK;
      }  
    return(temp);   
}

/**************************************************************
*        Function:         SwIIC_WriteByte                  
*        Parameters: RegAdd, RegVal
*        Return:                none
*
*        Complete data transfer - write a byte to device (ION) register
* Note: Secured routine through check of acknowledge
**************************************************************/
void SwIIC_WriteByte(byte RegAdd, byte RegVal)                     
{     
              
      ak1=NACK;
      ak2=NACK;
      ak3=NACK;
      
      while(ak3)
      {
        IIC_START();
        SwIIC_Delay(START_DELAY);  
        SwIIC_SendAddressWrite(ION_ADDR);
        SwIIC_Delay(ADDRESS_DELAY);   
          if(!ak1)                                 
          {
              SwIIC_SendRegister(RegAdd);
              SwIIC_Delay(ADDRESS_DELAY);
              if(!ak2)                             
              {
              IIC_SendByte(RegVal);
              }
          }
        IIC_STOP();
        ak1=NACK;
        ak2=NACK;
      }           
}

/**************************************************************
*        Function:         SwIIC_MultiRead                  
*        Parameters: RegAdd, *buff (data), cnt - length
*        Return:                none
*
*        Complete data transfer - multiple write a bytes to device (ION) registers
* Note: Secured routine through check of acknowledge
**************************************************************/
void SwIIC_MultiReadBytes(byte RegAdd, byte *buff, byte cnt)        
{  
  byte i;
  
  i=0;
  ak1=NACK;
  ak2=NACK;
  ak3=NACK;
   
      while(!(ak3==ACK))
      {         
       IIC_START();
       SwIIC_Delay(START_DELAY);                 
       SwIIC_SendAddressWrite(ION_ADDR);
       SwIIC_Delay(ADDRESS_DELAY);
       if(!ak1)
       {
        SwIIC_SendRegister(RegAdd);
        if(!ak2)      
        {
         IIC_REPEAT_START();
         SwIIC_SendAddressRead(ION_ADDR);
         SwIIC_Delay(ADDRESS_DELAY);
         if(!ak3)
         {
          for(i=0;i<(cnt - 1);i++)
          {
           *buff++ = IIC_ReadByte(IIC_ACK);
          }
          *buff++ = IIC_ReadByte(IIC_NACK);
         }
        }
       }
       IIC_STOP();
       ak1=NACK;
       ak2=NACK;
      }
}

/**************************************************************
*        Function:         SwIIC_MultiWrite               
*        Parameters: RegAdd, *buff (data), cnt - length
*        Return:                none
*
*        Complete data transfer - multiple write a bytes into device (ION) registers
* Note: Secured routine through check of acknowledge
**************************************************************/
void SwIIC_MultiWriteBytes(byte RegAdd, byte *buff, byte cnt)
{  
  byte i,j,ak[32];
  
  i=0;
  ak1=NACK;
  ak2=NACK;
  ak3=NACK;
  for(j=0;j<32;j++) ak[j]=NACK;
   
      while(!(ak[cnt+2]==ACK))
      {                                                   
        IIC_START();
        SwIIC_Delay(START_DELAY);                       
        SwIIC_SendAddressWrite(ION_ADDR);
        SwIIC_Delay(ADDRESS_DELAY);
          if(!ak1)                                 
          {              
              SwIIC_SendRegister(RegAdd);      
              SwIIC_Delay(ADDRESS_DELAY);
              ak[2]=ak2;
              while((!ak[i+2])&&(i<cnt))      
              {
                ak[i+3]=IIC_SendByteM(*(buff++));
                i++;
              }
          }
        IIC_STOP();
        ak1=NACK;
        for (j=0;j<(cnt-1);j++) ak[j+2]=NACK;
      }
}

使用特权

评论回复
地板
ccw1986|  楼主 | 2016-1-22 21:05 | 只看该作者
***************************************************************************//*!
*
* [url=home.php?mod=space&uid=288409]@file[/url]      sw_iic.h
*
* [url=home.php?mod=space&uid=187600]@author[/url]    R20246
*
* [url=home.php?mod=space&uid=895143]@version[/url]   2.0.0.1
*
* [url=home.php?mod=space&uid=212281]@date[/url]      FEB-14-2008
*
* [url=home.php?mod=space&uid=247401]@brief[/url]     ION (MMA7455L) - Ion MMA7455L in Measure mode (using SPI or IIC)
*
*******************************************************************************
*
*
*
******************************************************************************/
#ifndef SW_IIC_H
#define SW_IIC_H

#include "derivative.h"

#define ION_ADDR 0x1D /* ION address is 1D */

#define SCL     PTCD_PTCD3        
#define SCL_D   PTCDD_PTCDD3  
#define SCL_PU  PTCPE_PTCPE3  
#define SDA     PTCD_PTCD2        
#define SDA_D   PTCDD_PTCDD2  
#define SDA_PU  PTCPE_PTCPE2
#define SS      PTBD_PTBD3      
#define SS_D    PTBDD_PTBDD3      
#define SS_PU   PTBPE_PTBPE3      

#define P_OUT   1
#define P_IN    0
#define PU_ON   1
#define PU_OFF  0

#define ACK 0
#define NACK 1

#define IIC_ACK  0
#define IIC_NACK 1

#define START_DELAY 1
#define ADDRESS_DELAY 1

#define SDA_HOLD 5          //20MHz Bus Clock: 1  => IIC 110kHz
#define SCL_HOLD 5          //                 5  => IIC  70kHz

#define MAX_IIC_TIMEOUT 0x9F00

// FUNCTION DECLARATION
void SwIIC_Delay(byte);
void SwIIC_Wait(byte);
void IIC_DATA_0(void);
void IIC_DATA_1(void);
byte IIC_GetBit(void);
void IIC_START(void);
void IIC_REPEAT_START(void);
void IIC_STOP(void);
byte IIC_ReadByte(byte ack);
void IIC_SendByte(byte tx_byte);
byte IIC_SendByteM(byte tx_byte);
void SwIIC_Init(void);
void SwIIC_SendAddressWrite(byte tx_byte);
void SwIIC_SendAddressRead(byte tx_byte);
void SwIIC_SendRegister(byte tx_byte);
byte SwIIC_ReadByte(byte RegAdd);
void SwIIC_WriteByte(byte RegAdd, byte RegVal);
void SwIIC_MultiReadBytes(byte num, byte *buff, byte cnt);
void SwIIC_MultiWriteBytes(byte num, byte *buff, byte cnt);
  
#endif //SW_IIC_H

使用特权

评论回复
5
neeringstu| | 2016-1-23 20:51 | 只看该作者
这个需要保存啊,也可以用于其他单片机之类的吗
KL系列的iic不是挺好用的吗,为啥还要模拟

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

925

帖子

6

粉丝