IIC通信软件模拟

/*
//管脚定义
#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");
}    

*/

你可能感兴趣的:(C语言)