📄 i2c.c
字号:
#include <HT86072.H>
#include "Structure.H"
#include "External.H"
#include "Variable.H"
unsigned char ucWatch, ucWatch2, ucWatch3;
void SYSTEM_INITIAL(void)
{
SPEECH_INITIAL();
_pac = 0b11111111; //Input:Bit=1,Output:Bit=0
_pbc = 0b11110000;
_pcc = 0b00000011;
_tmr1c = 0x80;
_emi = 1;
_et0i = 1;
_et1i = 0;
_et2i = 1;
_et3i = 0;
_tmr2c = 0x90; //500us Timer
_tmr2h = 0xFC;
_tmr2l = 0x18;
_T1ON = 0;
_T2ON = 0;
_T3ON = 0;
}
void GameInitial(void)
{
I2C.uMode.ucValue = 0xE0;
}
unsigned char ucI2CAcc, ucI2CStatus;
void INTERRUPT_TIMER1_I2C(void)
{
#asm
mov _ucI2CAcc,a
mov a,[0ah]
mov _ucI2CStatus,a
#endasm
if (I2C.bPulseBusy == TRUE) //判断脉冲有没有输出完
{
if (I2C.bPulse == HIGH)
{
_SCL = LOW; //SCL输出低电平
I2C.uMode.bits.bSCL = OUTPUT;
_I2CPort = I2C.uMode.ucValue;
if (I2C.uSend.bits.bData)
{
I2C.uMode.bits.bSDA = INPUT;
_I2CPort = I2C.uMode.ucValue;
}
else
{
_SDA = LOW;
I2C.uMode.bits.bSDA = OUTPUT;
_I2CPort = I2C.uMode.ucValue;
}
}
else
{
I2C.uMode.bits.bSCL = INPUT; //SCL输出高电平
_I2CPort = I2C.uMode.ucValue;
I2C.bPulseBusy = FALSE;
}
I2C.bPulse = ~I2C.bPulse; //输出脉冲的电平取反
}
#asm
mov a,_ucI2CStatus
mov [0ah],a
mov a,_ucI2CAcc
reti
#endasm
}
void PulseOut(void)
{
_tmr1l = TIME1_L;
_tmr1h = TIME1_H; //50us:Pulse
_T1ON = 1;
_et1i = 1;
I2C.bPulse = HIGH; //输出脉冲的初始化
while(I2C.ucPulseNumber != 0)
{
I2C.bPulseBusy = TRUE;
while(I2C.bPulseBusy == TRUE) //等待输出的脉冲
{
_T1ON = 1;
_et1i = 1;
}
I2C.uSend.ucValue <<= 1; //下一个地址
//发送8位数据后,需要输出结束位。即SCL输出一个脉冲,并上升沿时,SDA输出高电平
I2C.uSend.ucValue |= 0x01;
I2C.ucPulseNumber--;
}
_T1ON = 0;
_et1i = 0;
}
bit SendStart(void)
{
I2C.uMode.bits.bSCL = INPUT; //发送Start信号,即在SCL为高电平时,SDA下降沿。
_I2CPort = I2C.uMode.ucValue;
I2C.uMode.bits.bSDA = INPUT;
_I2CPort = I2C.uMode.ucValue;
if (_SCL && _SDA)
{
_SDA = LOW;
I2C.uMode.bits.bSDA = OUTPUT;
_I2CPort = I2C.uMode.ucValue;
}
else
return ERROR;
return OK;
}
bit SendByte(void)
{
unsigned char i, j;
ucWatch3 = I2C.uSend.ucValue; I2C.ucPulseNumber = 9; //发送信号
PulseOut();
I2C.uSend.bits.bPrevious = _SCL;
for(i=0; i<255; i++) //接收ACK信号
{
I2C.uSend.bits.bCurrent = _SCL;
if (I2C.uSend.bits.bCurrent && !I2C.uSend.bits.bPrevious) //读取SCL上升沿时,SDA的值
{
if (_SDA == LOW)
{
for(j=0; j<255; j++) //收到ACK的上升沿信号,等待Slave放弃总线
{
if (_SDA && _SCL)
return OK;
}
ucWatch2 = 0x01; return ERROR;
}
else
{
ucWatch2 = 0x02; return ERROR;
}
}
I2C.uSend.bits.bPrevious = I2C.uSend.bits.bCurrent;
}
ucWatch2 = 0x03; return ERROR;
}
bit ReceiveByte(void)
{
unsigned char i;
unsigned char j;
I2C.uSend.ucValue = 0x80; //发送准备信息
I2C.ucPulseNumber = 1;
PulseOut();
I2C.uReceive.ucValue = 0;
for(i=0; i<8; i++)
{
I2C.uSend.bits.bPrevious = _SCL;
I2C.uReceive.ucValue <<= 1; //接收下一个BIT
for(j=0; j<0xFF; j++)
{
I2C.uSend.bits.bCurrent = _SCL;
if (I2C.uSend.bits.bCurrent && !I2C.uSend.bits.bPrevious) //读取SCL上升沿时,SDA的值
{
I2C.uReceive.bits.bData = _SDA;
break;
}
I2C.uSend.bits.bPrevious = I2C.uSend.bits.bCurrent;
}
if (j == 0xFF)
return ERROR;
}
I2C.uSend.bits.bPrevious = _SCL; //等待结束信号
for(i=0; i<0xFF; i++)
{
I2C.uSend.bits.bCurrent = _SCL;
if (I2C.uSend.bits.bCurrent && !I2C.uSend.bits.bPrevious) //读取SCL上升沿时,SDA的值
{
if (_SDA == LOW)
return ERROR;
else
break;
}
I2C.uSend.bits.bPrevious = I2C.uSend.bits.bCurrent;
}
if (i == 0xFF)
return ERROR;
I2C.ucPulseNumber = 1; //发送ACK信号
I2C.uSend.ucValue = 0;
PulseOut();
I2C.uMode.bits.bSDA = INPUT; //放弃I2C的发送权力
_I2CPort = I2C.uMode.ucValue;
I2C.uMode.bits.bSCL = INPUT;
_I2CPort = I2C.uMode.ucValue;
return OK;
}
bit Send(void)
{
unsigned char i, ucTemp;
if (SendStart())
{
I2C.uSend.ucValue = I2C.ucID << 4;
I2C.uSend.ucValue |= I2C.ucCommand;
if (SendByte())
{
switch(I2C.ucCommand)
{
case DISPLAY:
for(i=0; i<I2C.ucDataNumber; i++)
{
I2C.uSend.ucValue = I2C.ucData[i];
if (!SendByte())
{ucWatch = i;break;}
}
return OK;
break;
case KEYBOARD:
for(i=0; i<I2C.ucDataNumber; i++)
{
if(!ReceiveByte())
break;
I2C.ucData[i] = I2C.uReceive.ucValue;
}
I2C.uSend.ucValue = 0x80; //发送准备信息
I2C.ucPulseNumber = 1;
PulseOut();
return OK;
break;
}
ucWatch = 0xfd;
return ERROR;
}
ucWatch = 0xff; return ERROR;
}
ucWatch = 0xfe;return ERROR;
}
void MAIN(void)
{
unsigned char ucTemp1, ucTemp2, ucTemp3, ucTemp4;
unsigned char i1, i2, i3, i4, k,t1,t2;
unsigned long j, n;
SYSTEM_INITIAL();
GameInitial();
k = 0; t1 =0; t2 = 0; ucWatch = 0; ucWatch2 = 0;
while(1)
{
for(j=0, i1=1, i2=2, i3=3, i4=4; j<0xFFFE; j++, i1++, i2+=2, i3+=3, i4+=4)
{
I2C.ucID = 1;
I2C.ucCommand = DISPLAY;
I2C.ucDataNumber = 4;
I2C.ucData[0] = i1;
I2C.ucData[1] = i2;
I2C.ucData[2] = i3;
I2C.ucData[3] = i4;
ucTemp1 = I2C.ucData[0];
ucTemp2 = I2C.ucData[1];
ucTemp3 = I2C.ucData[2];
ucTemp4 = I2C.ucData[3];
if (!Send())
{t1 = 0x1; break;}
for(n=0; n<0xFFff; n++) ;
I2C.ucData[0] = 0x00;
I2C.ucData[1] = 0x00;
I2C.ucData[2] = 0x00;
I2C.ucData[3] = 0x00;
I2C.ucID = 1;
I2C.ucCommand = KEYBOARD;
I2C.ucDataNumber = 4;
if (!Send())
{t2 = 0x2; break;}
ucTemp1 = I2C.ucData[0];
ucTemp2 = I2C.ucData[1];
ucTemp3 = I2C.ucData[2];
ucTemp4 = I2C.ucData[3];
if (I2C.ucData[0] != i1)
{k = 0x1;break;}
if (I2C.ucData[1] != i2)
{k = 0x2;break;}
if (I2C.ucData[2] != i3)
{k = 0x3;break;}
if (I2C.ucData[3] != i4)
{k = 0x4;break;}
for(n=0; n<0xFFff; n++) ;
}
if (j != 0xFFFF)
I2C.ucData[0] = 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -