📄 i2c.c
字号:
#include "reg52.h"
#include "define.h"
#include "i2c.h"
/****************************************************************************
Project : LCD Display
Version : 1.0
File Name : VP_IIC.c
Functions : i2c interface routine
Revision :
1999-05-18 OriginalTeam First Created
2005-01-25 Alf Hsu Modified for Vipor
2005-03-08 Alf Hsu Released Version 1.0
****************************************************************************/
/**************************************************************************/
/* INCLUDE FILES */
/**************************************************************************/
#include <intrins.h>
/**************************************************************************/
/**************************************************************************/
#define SUCCESS 0
#define FAILURE 1
/**************************************************************************/
/**************************************************************************/
extern Bool WriteI2CData(Byte,Byte,Byte);
extern BYTE ReadI2CData(Byte,Byte,Byte);
extern Bool IIC_SendByte(Byte);
extern Byte IIC_ReadByte(Bool);
extern void IIC_Start(void);
extern void IIC_Stop(void);
Byte TrmBuf[16];
/**************************************************************************/
/**************************************************************************/
#if 0//(VIPOR_CHIP==VP77)
void IIC_NOP(Byte max)
{
#if (CPU_DOUBLE_RATE==2)
Byte i;
max = max<<1;
for(i=0; i<max; i++)
{
_nop_();
}
#else
max = 0;
#endif
}
#else
#define IIC_NOP(val)
#endif
#define IIC_ByteDelay()
/**************************************************************************/
/**************************************************************************/
Bool WriteI2CData(Byte slv_addr,Byte base_addr,Byte cValue)
{
Byte i,j;
Bool no_ack,fg_base_addr,fg_eeprom;
Bool fg_Byte_delay=1;
Byte Byte_cnt = 1;
no_ack = 1;
fg_eeprom = (slv_addr & 0xA0)==0xA0 ? 1 : 0;
fg_base_addr = (Byte_cnt & IIC_NO_BASE_ADDR)==0x00 ? 1 : 0;
Byte_cnt &= 0x0F;
for( i=0; i<10; i++) /* retry for 10 times */
{
IIC_NOP(10);
IIC_Start();
if( IIC_SendByte(slv_addr) )
{
IIC_Stop();
if( fg_eeprom ) ShortDelay(5);
continue;
}
if( fg_Byte_delay ) IIC_ByteDelay();
if( fg_base_addr )
{
if( IIC_SendByte(base_addr) != SUCCESS )
{
IIC_Stop();
if( fg_eeprom ) ShortDelay(5);
continue;
}
if( fg_Byte_delay ) IIC_ByteDelay();
}
no_ack = 0;
for(j=0; j<Byte_cnt; j++)
{
if( IIC_SendByte(cValue) != SUCCESS )
{
no_ack = 1;
break;
}
if( fg_Byte_delay ) IIC_ByteDelay();
}
IIC_Stop();
if( no_ack==0 ) break; /* complete */
if( fg_eeprom ) ShortDelay(5);
}
return no_ack;
}
/**************************************************************************/
/**************************************************************************/
BYTE ReadI2CData(Byte slv_addr,Byte base_addr,Byte Byte_cnt)
{
Byte i,j;
Bool no_ack,fg_base_addr,fg_last_Byte;
Bool fg_Byte_delay=1;
BYTE cValue;
Byte_cnt = 1;
no_ack = 1;
fg_base_addr = (Byte_cnt & IIC_NO_BASE_ADDR)==0x00 ? 1 : 0;
Byte_cnt &= 0x0F;
for( i=0; i<10; i++) /* retry for 10 times */
{
IIC_NOP(10);
if( fg_base_addr )
{
IIC_Start();
if( IIC_SendByte(slv_addr) )
{
IIC_Stop();
continue;
}
if( fg_Byte_delay ) IIC_ByteDelay();
if( IIC_SendByte(base_addr) != SUCCESS )
{
IIC_Stop();
continue;
}
if( fg_Byte_delay ) IIC_ByteDelay();
}
else // IIC_NO_BASE_ADDR, check base_addr for sub_address count in TrmBuf[4..n]
{
if( base_addr!=0 )
{
IIC_Start();
if( IIC_SendByte(slv_addr) )
{
IIC_Stop();
continue;
}
if( fg_Byte_delay )
{
IIC_ByteDelay();
}
no_ack = 0;
for(j=0; j<base_addr; j++)
{
if( IIC_SendByte(TrmBuf[4+j]) != SUCCESS )
{
no_ack = 1;
break;
}
if( fg_Byte_delay ) IIC_ByteDelay();
}
if( j!=base_addr )
{
IIC_Stop();
continue;
}
}
}
IIC_Start();
if( IIC_SendByte(slv_addr+1) )
{
IIC_Stop();
continue;
}
if( fg_Byte_delay ) IIC_ByteDelay();
for(j=0; j<Byte_cnt; j++)
{
fg_last_Byte = (j==(Byte_cnt-1)) ? 1 : 0;
cValue = IIC_ReadByte(fg_last_Byte);
if( fg_Byte_delay ) IIC_ByteDelay();
}
IIC_Stop();
no_ack = 0;
break;
}
return cValue;
}
/**************************************************************************/
/**************************************************************************/
Bool IIC_SendByte(Byte bval)
{
Byte i;
Bool no_ack = 0;
IIC_NOP(4);
for(i=8; i!=0; i--)
{
SDA_PIN = (bval & 0x80);
_nop_();
IIC_NOP(2);
SCL_PIN = 1;
bval <<= 1;
IIC_NOP(2);
SCL_PIN = 0;
IIC_NOP(2);
}
SDA_PIN = 1;
_nop_();
_nop_();
IIC_NOP(2);
SCL_PIN = 1;
for(i=64; i!=0; i--)
{
IIC_NOP(2);
if( SDA_PIN==0 ) break;
}
if( i==0 ) no_ack = 1;
IIC_NOP(2);
SCL_PIN = 0;
_nop_();
_nop_();
IIC_NOP(2);
SDA_PIN = 0;
return no_ack;
}
/**************************************************************************/
/**************************************************************************/
Byte IIC_ReadByte(Bool fg_last_Byte)
{
Byte i,bval;
bval = 0;
IIC_NOP(4);
SDA_PIN = 1;
IIC_NOP(4); // It's necessary
for(i=0; i<8; i++)
{
SCL_PIN = 1;
IIC_NOP(2);
bval = bval << 1;
if( SDA_PIN ) bval |= 0x01;
IIC_NOP(2);
SCL_PIN = 0;
_nop_();
_nop_();
_nop_();
IIC_NOP(2);
}
if( fg_last_Byte ) SDA_PIN = 1;
else SDA_PIN = 0;
_nop_();
IIC_NOP(1);
SCL_PIN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
IIC_NOP(4);
SCL_PIN = 0;
_nop_();
IIC_NOP(1);
SDA_PIN = 1;
return bval;
}
/**************************************************************************/
/**************************************************************************/
void IIC_Start(void)
{
SDA_PIN = 1;
_nop_();
IIC_NOP(1);
SCL_PIN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
IIC_NOP(4);
SDA_PIN = 0;
_nop_();
_nop_();
_nop_();
_nop_();
IIC_NOP(4);
SCL_PIN = 0;
IIC_NOP(4);
}
/**************************************************************************/
/**************************************************************************/
void IIC_Stop(void)
{
SDA_PIN = 0;
_nop_();
IIC_NOP(1);
SCL_PIN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
IIC_NOP(4);
SDA_PIN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
IIC_NOP(4);
}
/************************************************************************/
/************************************************************************/
void ShortDelay(Byte count)
{
Byte i,j;
#if 1//(CPU_DOUBLE_RATE==0)
for(i=0; i<count; i++)
{
for(j=0; j<169; j++)
{
_nop_();
_nop_();
}
}
#else
for(i=0; i<count; i++)
{
for(j=0; j<204; j++)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -