并口定义及其编程基础之三:并口实现IIC

(1)硬件原理图

                      并口定义及其编程基础之三:并口实现IIC_第1张图片

图中选用的并口脚都是比较通用的接法,当然也存在使用其他并口脚的情况。图中的每个PIN脚都接了反向器。

(2)如下是一个并口软件IIC调试工具的若干子函数,这些子函数的实现与上图的接法并不对应,下面使用的是并口2作SCL,并口3作SDA。

#define SCL_H      0x01
#define SDA_H      0x02   //使用的并口号

 

#define SCL_L      0x00
#define SDA_L      0x00   //使用的并口号


#define SDA_OE_L     0x00

#define SDA_I      0x80    //读应答或者读数据

#define SDA_DIR      0x04

#define SDA_OE_H     SDA_DIR

void IICDelay(int t)
{
      ::Sleep(t);
}

void IICStart(void)
{
      WritePptByte(validPpt, SDA_H|SCL_H|SDA_OE_L);//SCL = 1; SDA = 1
      IICDelay(DELAY_TIME);

      WritePptByte(validPpt, SDA_L|SCL_H|SDA_OE_L);//when SCL = 1, SDA 1->0 transition , this is start condition
      IICDelay(DELAY_TIME);

      WritePptByte(validPpt, SDA_L|SCL_L|SDA_OE_L);//SCL = 0; SDA = 0
      IICDelay(DELAY_TIME);
}

void IICStop(void)
{
      WritePptByte(validPpt, SDA_L|SCL_L|SDA_OE_L);//SCL = 0; SDA = 0
      IICDelay(DELAY_TIME);

      WritePptByte(validPpt, SDA_L|SCL_H|SDA_OE_L);//SCL = H; SDA = 0
      IICDelay(DELAY_TIME);
      WritePptByte(validPpt, SDA_H|SCL_H|SDA_OE_L);//when SCL = 1; SDA 0->1 transtion, this is stop condition
      IICDelay(DELAY_TIME);
}

int IICWriteByte(BYTE dat)
{
      int i;

      for(i = 0; i < 8; i++)
     {
            WritePptByte(validPpt, ((dat & 0x80)?SDA_H:SDA_L) | SCL_L | SDA_OE_L);//SCL = 0; DATA Ready
            IICDelay(DELAY_TIME);
            WritePptByte(validPpt, ((dat & 0x80)?SDA_H:SDA_L) | SCL_H | SDA_OE_L);//SCL = 0->1; OUTPUT DATA
            IICDelay(DELAY_TIME);
            dat <<= 1;
     }

     WritePptByte(validPpt, ((dat & 0x80)?SDA_H:SDA_L)|SCL_L|SDA_OE_H);//SCL = 0; SDA = 1,此时dat 已为0
     IICDelay(DELAY_TIME);
     WritePptByte(validPpt, ((dat & 0x80)?SDA_H:SDA_L)|SCL_H|SDA_OE_H);//SCL 0->1 ,we will read the ACK
     IICDelay(DELAY_TIME);


     if (~ ReadPptByte(validPpt+1) & SDA_I)   //读并口的状态寄存器。读取的是反向后的值

             i =  0;//no ack
     else

             i = 1;//ack

 

     IICDelay(DELAY_TIME);
     WritePptByte(validPpt, SCL_L|SDA_OE_L);//SCL = 0; SDA = 0  //回复默认,一个操作结束
     IICDelay(DELAY_TIME);

     return i;

}

BYTE IICReadByte(void)
{
     int i;
     BYTE dat = 0;

     for(i = 0; i < 8; i++)
    {
           WritePptByte(validPpt, SDA_H|SCL_L|SDA_OE_H);//SCL = 0; SDA = 1,注意后面并不是从SDA上读的值
           IICDelay(DELAY_TIME);
           WritePptByte(validPpt, SDA_H|SCL_H|SDA_OE_H);//SCL 0->1 ,we will read the Data bit
           IICDelay(DELAY_TIME);
           if(~ ReadPptByte(validPpt+1) & 0x80)    //反向的值,所以要加取反

          {

                 dat <<= 1;

                 dat |= 1;

           }
           else

                 dat <<= 1;
           IICDelay(DELAY_TIME);
     }

     WritePptByte(validPpt, SDA_L|SCL_L|SDA_OE_L);//SCL = 0; SDA = 0
     IICDelay(DELAY_TIME);
     WritePptByte(validPpt, SDA_L|SCL_H|SDA_OE_L);//SCL 0->1 ,we will send the ACK to device

     return dat;

}

void IICSendAck(int ack)
{
      if(ack)
      {//if need ack
             WritePptByte(validPpt, SDA_L|SCL_L|SDA_OE_L);//SCL = 0; SDA = 0
             IICDelay(DELAY_TIME);
             WritePptByte(validPpt, SDA_L|SCL_H|SDA_OE_L);//SCL 0->1 ,we will send the ACK to device
       }//if need ack
       else
       {//no ack
             WritePptByte(validPpt, SDA_H|SCL_L|SDA_OE_L);//SCL = 0; SDA = 1
             IICDelay(DELAY_TIME);
             WritePptByte(validPpt, SDA_H|SCL_H|SDA_OE_L);//SCL 0->1 ,we will send the NO ACK to device 
        }//no ack
        IICDelay(DELAY_TIME);
}

 

你可能感兴趣的:(编程,工具,byte,transition,output,delay)