I2C这种协议的使用非常广泛,最基础的是SCL/SDA的两根线来传导,具体实践中并不是一成不变的。比如用I2C完成对屏的控制和初始化,如下图:
在屏的接口上有对应的SCL、SDA、CSB三根数据线。在CSB为低时,通过SDA与SCL的操作写入对应的初始化寄存器数据。数据组如下:
必须在屏上电时将6个寄存器的内容写进去方可有效初始化屏的驱动。以上定义了地址位,读写操作和数据位。本以为需要区分,实际上想复杂了。直接将数据写到I2C总线上,其他的由器件自己来完成。至于每个寄存器的具体含义我们暂且这里不管,当然我们在实际使用时会需要设置到。接下来用完全的GPIO来模拟I2C操作。如:
Void Panel_IIC(U16 Data)
{
U16 temp;
U8 RoopCt;
BusWait(NUM1); //需要偶尔的延时,要参考其他和实际来设定
Temp = Data;
IntDisableWithPush; //一对,相当于设置临界区来保护一样
pvPannel_CBS = 1; //取一个无用的GPIO做CBS
poPannel_CBS = 0; //当CBS PIN为低电平时,才I2C操作有效
IntEnableByPop;
for( RoopCt=0; RoopCt<16; RoopCt++ )
{
IntDisableWithPush;
pvPannel_SCL= 1; //取一个无用的GPIO
poPannel_SCL= 0; //SCL为低时,才能变更SDA
IntEnableByPop;
if( (Temp & 0x8000) != 0 )
{
IntDisableWithPush;
pvPannel_SDA= 1; //GPIO输出方向,1为输出
poPannel_SDA= 1; //从高位往地位写,如果为1写1,为0
IntEnableByPop; //写0
}
else
{
IntDisableWithPush;
pvPannel_SDA= 1;
poPannel_SDA= 0;
IntEnableByPop;
}
IntDisableWithPush;
pvPannel_SCL= 1;
poPannel_SCL= 1; //再重新将SCL置高
IntEnableByPop;
Temp = Temp << 1;
}
IntDisableWithPush;
pvPannel_CBS = 1;
poPannel_CBS = 1; //该次通讯完成后,重新恢复CBS
IntEnableByPop;
}
单次操作的函数完成后,就可以下列代码完成初始化:
然后使用时直接在开机时加上如下代码即可:
void Panel_IIC_Init(void)
{ U16 Data;
Data=0x02d3;
Panel_IIC(Data);
Data=0x116f;
Panel_IIC(Data);
Data=0x2080;
Panel_IIC(Data);
Data=0x3008;
Panel_IIC(Data);
Data=0x419f;
Panel_IIC(Data);
Data=0x61ce;
Panel_IIC(Data);
}