📄 iic.c
字号:
/*****************************************************************************
*function: IIC start condition
*IIC起始条件
*****************************************************************************/
void I2CStart(void)
{
SDA = 1;
SCL = 1;
SDA = 0;
_nop_();
SCL = 0;
}
/*****************************************************************************
*function: IIC stop condition
*IIC停止条件
*****************************************************************************/
void I2CStop(void)
{
SCL = 0;
SDA = 0;
_nop_();
SCL = 1;
SDA = 1;
}
/*****************************************************************************
*function: IIC wait ACK
*等待IIC从器件的"ACK"
*****************************************************************************/
bit I2CWaitAck(void)
{
unsigned char cErrTime = 255;
SDA = 1;
_nop_();
SCL = 1;
while(SDA)
{
cErrTime--;
if (0 == cErrTime)
{
I2CStop();
return FAILURE;
}
}
SCL = 0;
return SUCCESS;
}
/*****************************************************************************
*function: IIC send ACK
*发送"ACK"
*****************************************************************************/
void I2CSendAck(void)
{
SDA = 0;
_nop_();
SCL = 1;
SCL = 0;
}
/*****************************************************************************
*function: IIC send Not ACK
*发送"NOT ACK"
*****************************************************************************/
void I2CSendNotAck(void)
{
SDA = 1;
_nop_();
SCL = 1;
SCL = 0;
}
/*****************************************************************************
*function: send a byte over IIC bus
*发送一个字节
*****************************************************************************/
void I2CSendByte(unsigned char cSendByte)
{
unsigned char data i = 8;
while (i--)
{
SCL = 0;
SDA = (bit)(cSendByte & 0x80);
cSendByte += cSendByte;
_nop_();
SCL = 1;
}
SCL = 0;
}
/*****************************************************************************
*function: receive a byte over IIC bus
*接收一个字节
*****************************************************************************/
unsigned char I2CReceiveByte(void)
{
unsigned char data i = 8;
unsigned char data cR_Byte = 0;
SDA = 1;
while (i--)
{
cR_Byte += cR_Byte;
SCL = 0;
_nop_();
_nop_();
SCL = 1;
cR_Byte |= (unsigned char)SDA;
}
SCL = 0;
return cR_Byte;
}
/*****************************************************************************
*function: read data from JMY-5xx over IIC bus
*从模块读取返回的数据,所有的数据均通过此函数读取
*****************************************************************************/
unsigned char IicReadJMY5xx(unsigned char *cP)
{
unsigned char cCnt;
unsigned char cCheckSum = 0;
for (cCnt=0; cCnt<0xFF; cCnt++) //等待模块工作(操作卡片),如果超时则返回“失败”
{
Delay100uS(1); //100微秒延时程序
I2CStart(); //发送起始条件
I2CSendByte(READ_JMY5xx); //发送IIC的“读”命令
if (I2CWaitAck() == SUCCESS) //如果正确收到了模块返回的"ACK",则模块的工作(操作卡片)已经完成,可以读取返回结果了
{
break;
}
}
if (0xFF == cCnt) //如果等待模块工作达到了25毫秒,则认为模块工作超时,返回失败
{
return FAILURE;
}
cP[0]=2; //赋予读取字节数 初值“2”,但实际读取的字节数会大于此值,因为读到的第一个字节就是数据包的实际值,而后会被覆盖
for (cCnt=0; cCnt<cP[0]; cCnt++) //以接收到的第一个字节为长度,读取模块的返回数据
{
cP[cCnt] = I2CReceiveByte(); //接收一个字节
I2CSendAck(); //发送"ACK"
cCheckSum ^= cP[cCnt]; //计算校验和
}
cP[cCnt] = I2CReceiveByte(); //接收校验和
I2CSendNotAck(); //发送"NOT ACK"
I2CStop(); //IIC 停止条件
if (cCheckSum != cP[cCnt]) //比较校验和
{
return FAILURE; //如果比较不等,则返回“失败”
}
else
{
return SUCCESS; //如果相等,则返回成功
}
}
/*****************************************************************************
*function: send data to JMY-5xx over IIC bus
*这是向模块发送数据的函数,所有操作模块的命令均由此函数发送
*程序输入的参数是一个指针,由通讯协议所定,指针指向的第一个字节是发送的数据包的长度(不包含最后的校验字节)
*在所有的数据发送完毕之后,再发送校验字节
*****************************************************************************/
unsigned char IicSendJMY5xx(unsigned char *cP)
{
unsigned char i;
unsigned char cCheckSum = 0;
I2CStart(); //IIC 起始条件
I2CSendByte(WRITE_JMY5xx); //发送IIC的“写”指令
if (I2CWaitAck() == SUCCESS) //如果从器件有正确的"ACK"回应
{
for(i=0; i<cP[0]; i++) //发送数据字节,长度为输入的指针的第一个字节
{
cCheckSum ^= cP[i]; //计算“异或”的校验和
I2CSendByte(cP[i]); //发送一个字节
if (I2CWaitAck() != SUCCESS) //等待从器件的"ACK"
{
return FAILURE; //如果从器件没有正确的"ACK"则返回
}
}
I2CSendByte(cCheckSum); //发送完数据字节之后,发送计算出的异或校验和
if (I2CWaitAck() != SUCCESS) //如果没有收到"ACK"则返回
{
return FAILURE;
}
I2CStop(); //发送IIC停止条件
return SUCCESS; //返回“成功”
}
else
{
return FAILURE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -