IIC通信软件模拟

    技术2023-12-01  87

    /* //管脚定义 #define            I2C_SCL            RB6 #define            I2C_SDA            RB7 volatile bit      I2C_SCL_IO        @((unsigned)&TRISB*8)+6;        //IB口方向设置 volatile bit      I2C_SDA_IO        @((unsigned)&TRISB*8)+7;        //IB口方向设置

    unsigned char I2C_Read1bYTE(unsigned char ack);//用于触摸仿真工具 unsigned char I2C_Write1bYTE(unsigned char data); //----------------------------------------------------------------------------- //函数声明 void DataPro(void);

    extern unsigned int  TKDATA0;            //按键旧值

    unsigned char I2C_Read1bYTE(unsigned char ack); unsigned char I2C_Write1bYTE(unsigned char data); void I2C_WaitMoment(); void I2C_WriteStop(); void I2C_WriteStart();

    uint TKdata[16]; void DataPro(void) {     uchar checksum = 5;     asm("clrwdt");     //Key_Test();        //检测按键值     checksum *= 3;        //在此之前的checksum表示按键个数     checksum += 2;        //在此之后的checksum表示校验和     //-----------------与软件通讯规则为   0xA0+数据个数+数据+检验和------------------         I2C_WriteStart();         I2C_Write1bYTE(0xa0);                            //建立连接的命令         I2C_Write1bYTE(checksum);                        //数据个数为  X*2+2  X表示按键个数                  //KEY7         I2C_Write1bYTE(0x07);         I2C_Write1bYTE(TKdata[6] & 0xff);                //键值数据低位            I2C_Write1bYTE((TKdata[6]>>8) & 0xff);              //键值数据高位         checksum += 7;         checksum += (TKdata[6] & 0xff);                    //检验和= 数据个数+键值数据的总和         checksum += ((TKdata[6]>>8) & 0xff);                 //KEY8         I2C_Write1bYTE(0x08);         I2C_Write1bYTE(TKdata[7] & 0xff);                //键值数据低位            I2C_Write1bYTE((TKdata[7]>>8) & 0xff);              //键值数据高位         checksum += 8;         checksum += (TKdata[7] & 0xff);                    //检验和= 数据个数+键值数据的总和         checksum += ((TKdata[7]>>8) & 0xff);                 //KEY12         I2C_Write1bYTE(0x0C);         I2C_Write1bYTE(TKdata[11] & 0xff);                //键值数据低位            I2C_Write1bYTE((TKdata[11]>>8) & 0xff);              //键值数据高位         checksum += 0x0C;         checksum += (TKdata[11] & 0xff);                    //检验和= 数据个数+键值数据的总和         checksum += ((TKdata[11]>>8) & 0xff);                 //KEY13         I2C_Write1bYTE(0x0D);         I2C_Write1bYTE(TKdata[12] & 0xff);                //键值数据低位            I2C_Write1bYTE((TKdata[12]>>8) & 0xff);              //键值数据高位         checksum += 0x0D;         checksum += (TKdata[12] & 0xff);                    //检验和= 数据个数+键值数据的总和         checksum += ((TKdata[12]>>8) & 0xff);                 //KEY14         I2C_Write1bYTE(0x0E);         I2C_Write1bYTE(TKdata[13] & 0xff);                //键值数据低位            I2C_Write1bYTE((TKdata[13]>>8) & 0xff);              //键值数据高位         checksum += 0x0E;         checksum += (TKdata[13] & 0xff);                    //检验和= 数据个数+键值数据的总和         checksum += ((TKdata[13]>>8) & 0xff);        

            I2C_Write1bYTE(checksum);                        //发校验和         I2C_WriteStop();                                //结束                     }           //IIC函数      //起始信号-在SCL为高电平时,SDA线上发生从高到低的电平变化 void I2C_WriteStart() {     I2C_SDA_IO = 0;     I2C_SCL_IO = 0;     I2C_WaitMoment();          I2C_SDA = 1;            //先将SDA=1,以准备在SCL=1时,将SDA=0     I2C_SCL = 1;            //时钟总线拉高     I2C_WaitMoment();     I2C_SDA = 0;            //SCL=1时,将SDA拉低即产生启动信号          I2C_WaitMoment();     I2C_SCL = 0;            //将SCL=0,完成启动信号操作     I2C_WaitMoment(); }

    //结束信号-在SCL为高电平时,SDA线上发生从低到高的电平变化 void I2C_WriteStop() {     I2C_SDA_IO = 0;     I2C_SCL_IO = 0;     I2C_WaitMoment();          I2C_SDA = 0;            //先将SDA=0,以准备在SCL=1时,将SDA=1     I2C_SCL = 1;            //时钟总线拉高     I2C_WaitMoment();     I2C_SDA = 1;            //SCL=1时,将SDA拉高即产生停止信号          I2C_WaitMoment();     I2C_SCL = 0;            //将SCL=0,完成启动信号操作     I2C_WaitMoment(); }

    // //函数功能:模拟IIC主机发送8位数据 //入口参数:data-待发送数据 //函数返回:返回ack应答信号 //备    注:IIC协议ack应答信号为低有效 unsigned char I2C_Write1bYTE(unsigned char data) {     unsigned char i = 8;     I2C_SDA_IO = 0;     I2C_SCL_IO = 0;     do     {         I2C_SCL = 0;         if(data&0x80)             I2C_SDA = 1;         else             I2C_SDA = 0;                  I2C_SCL = 1;        //时钟线做一个上升沿,将一位数据写入         data <<= 1;     }     while(--i);     I2C_SCL = 0;          I2C_SDA_IO = 1;            //置为输入口接收应答信号

        I2C_WaitMoment();     I2C_SCL = 1;            //做个上升沿准备读应答信号     I2C_WaitMoment();          i = I2C_SDA;     I2C_SCL = 0;     I2C_SDA_IO = 0;     return i; }

    //函数功能:模拟IIC主机接收8位数据 //入口参数:ack-应答信号 //函数返回:接收到的数据 //备    注:IIC协议ack应答信号为低有效 unsigned char I2C_Read1bYTE(unsigned char ack) {     unsigned char i,data;     I2C_SDA_IO = 1;     I2C_SCL_IO = 1;     I2C_WaitMoment();          while(!I2C_SCL);                //等待从机准备好数据释放时钟     I2C_SCL_IO = 0;     I2C_SCL = 0;     I2C_WaitMoment();          data <<= 1;     if(I2C_SDA) data |= 0x1;               for(i = 0; i < 7; i++)     {         I2C_SCL = 1;         data <<= 1;         if(I2C_SDA) data |= 0x1;         I2C_SCL = 0;     }          I2C_SDA_IO = 0;          if(ack)I2C_SDA = 1;            //是否需要更多的数据     else I2C_SDA = 0;          I2C_WaitMoment();     I2C_SCL = 1;     I2C_WaitMoment();     I2C_SCL = 0;     return data; }

    void I2C_WaitMoment() {     asm("nop");     asm("nop"); }    

    */

    Processed: 0.009, SQL: 9