⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2cio.c

📁 CRT显示器的运行程序
💻 C
字号:
#include <reg52.h>
#include "I2C.h"
#include "gen.h"
#include <intrins.h>

#define  DISABLEINT0  0
bit  NoAck = 0; 
bit  BusFault = 0;
#if I2cBusType==0							
//	定义模拟I2c总线的引脚
sbit SDA=P3^4;
sbit SCL=P3^5;
bit Flg_I2c_Ack;
#endif
//#undef DisableInt		// 不允许在串行读写中禁止中断
#define DisableInt		// 表示在串行读写中禁止中断

#define I2cBusType		0	// 0:采用模拟的IIC总线
							// 1:采用MTV212的专用IIC总线 

void I2c_Wait(void);
void I2c_Start(void);
void I2c_Stop(void);
void SendByte(unsigned char SendData);
unsigned char RcvByte(void);
void I2c_Ack(bit ack);
void Write_TDA48XX_Reg(unsigned char reg_addr,unsigned char value);
void Write_TDA4886_Reg(unsigned char reg_addr,unsigned char value);
//void Delay20us(void);
void Delayms(int t);
void miscDelay(int t);


#if I2cBusType==1	// 采用MTV212的专用IIC总线接口
/********************************************************************  
* 	函 数 名: I2c_Wai
* 	功能描述: 等待IIC总线的传输,并有限时退出的功能,避免在IIC操作中死锁
* 	输    入:
* 	返    回:
**********************************************************************/
void I2c_Wait(void)
{
	register int i;

	for (i=0;i<512;i++)  {
		if (XFR_IIC_INTFLG&0x01)  break;
		_nop_();
		_nop_();
		_nop_();
		}
	XFR_IIC_INTFLG=0xfe;
}
#endif

void miscDelay(int n)
{
        unsigned int i;

    while (n--) {
            i = 1000/11 ;  // one loop below takes about 11 us
        while (i--);
    }
}


/********************************************************************  
* 	函 数 名: I2c_Start
* 	功能描述: 启动I2c总线
* 	输    入: 无
* 	返    回:
*********************************************************************/

void I2c_Start(void)
{
#if I2cBusType==0	// 采用模拟的IIC总线
	SDA=1;			// 发送起始条件的数据信号
	_nop_();
	SCL=1;
	_nop_();		// 起始条件建立时间要大于4.7us
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SDA=0;			// 发送起始信号
	_nop_();		// 起始条件锁定时间大于4.7us
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SCL=0;			// 锁住I2C总线,准备发送和接收数据
	_nop_();
	_nop_();
	
#elif I2cBusType==1	// 采用MTV212的专用IIC总线接口
	XFR_IIC_CTR=0x80;
//	Delay20us();
	XFR_IIC_CTR=0x81;
	I2c_Wait();
#endif
}

/********************************************************************  
* 	函 数 名: I2c_Stop
* 	功能描述: 结束I2c总线
* 	输    入: 无
* 	返    回: 无
*********************************************************************/
void I2c_Stop(void)
{
#if I2cBusType==0	// 采用模拟的IIC总线
	SDA=0;			// 发送结束条件的数据信号
	_nop_();
	SCL=1;			// 发送结束条件的时钟信号
	_nop_();		// 结束条件建立时间要大于4.7us
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SDA=1;			// 发送结束信号
	_nop_();		// 起始条件锁定时间大于4.7us
	_nop_();
	_nop_();
	_nop_();
	
#elif I2cBusType==1	// 采用MTV212的专用IIC总线接口
	XFR_IIC_CTR=0x82;
#endif
}


#if I2cBusType==0	// 采用模拟的IIC总线
/********************************************************************  
* 	函 数 名: SendByte
* 	功能描述: 发送单字节数据,该数据既可以是地址也可以是数据。发送完数据要等待应答,
*			  并根据是否应答来设置标志为:I2c_Ack
*				I2c_Ack=1	:数据发送正常
*				I2c_Ack=0	:被控器件无应答
* 	输    入:
* 	返    回:
**********************************************************************/
void SendByte(unsigned char SendData)
{    

	register unsigned char i;
	for (i=0;i<8;i++)  {	// 要发送的数据长度为8位
		if ((SendData<<i)&0x80)  SDA=1;
		else  SDA=0;
		_nop_();
		SCL=1;		// 置时钟线为高电平,通知被控器件开始接收数据位
		_nop_();	// 保证时钟高电平周期大于4us
		_nop_();
		_nop_();
		_nop_();
		SCL=0;
		}
	_nop_();
	_nop_();
	SDA=1;			// 8位数据发送完之后要释放数据线,准备接受应答位
	_nop_();
	_nop_();
	SCL=1;
	_nop_();
	_nop_();
	_nop_();
	if (SDA)  Flg_I2c_Ack=0;
	else  Flg_I2c_Ack=1;
	SCL=0;
	_nop_();
	_nop_();
}

/********************************************************************  
* 	函 数 名: I2c_Ack
* 	功能描述: 主控器发送应答或非应答信号
* 	输    入: 应答控制位: 0表示应答;1:表示非应答
* 	返    回: 无
**********************************************************************/
/*
void I2c_Ack(bit ack)
{
#if I2cBusType==0		// 采用模拟的IIC总线
	if (ack)  SDA=1;	// 发送非应答信号
	else  SDA=0;		// 发送应答信号
	_nop_();
	_nop_();
	_nop_();
	SCL=1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SCL=0;				// 清时钟线,钳住I2c总线以便继续接收
	_nop_();
	_nop_();
	
#elif I2cBusType==1	// 采用MTV212的专用IIC总线接口
	if (ack)	XFR_IIC_CTR=0x84;  
#endif

}
*/
/********************************************************************  
* 	功能描述: 从总线上接收一个字节的数据
* 	输    入: 无
* 	返    回: 从总线上接收的字节
**********************************************************************/
/*
unsigned char RcvByte(void)
{
	register unsigned char RcvData,i;

	RcvData=0;
	SDA=1;			// 设置数据线为输入方式
	for (i=0;i<8;i++)  {
		_nop_();
		SCL=0;		// 设置时钟线为低,准备接收数据位
		_nop_();	// 时钟低电平周期大于4.7us
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		SCL=1;		// 设置时钟线为高,使数据线上的数据有效
		_nop_();
		_nop_();
		RcvData=RcvData<<1;
		if (SDA)  RcvData+=1;
		_nop_();
		_nop_();
		}
	SCL=0;
	_nop_();
	_nop_();
	return RcvData;
}*/
#endif

//-------------------------------------------

#if I2cBusType==0	
void Write_TDA4886_Reg(unsigned char reg_addr,unsigned char value)
{
#ifdef DisableInt
	bit EAbak;
	EAbak=EA;
	EA=0;
#endif

	I2c_Start();
	SendByte(0x88);			
//	if (!I2c_Ack)  goto W4886RegEnd;

	SendByte(reg_addr);	
//	if (!I2c_Ack)  goto W4886RegEnd;

	SendByte(value);	

//W4886RegEnd:
	I2c_Stop();
	
#ifdef DisableInt
	EA=EAbak;
#endif
}

//------------------------------------------------------------------------
#elif I2cBusType==1	// 采用MTV212的专用IIC总线接口
void Write_TDA4886_Reg(unsigned char reg_addr,unsigned char value)
{
#ifdef DisableInt
	bit EAbak;
	EAbak=EA;
	EA=0;
#endif

	XFR_IIC_MBUF=0x88;		// 写入TDA4886的器件地址
	I2c_Start();
	if (XFR_IIC_STUS2&0x80)  goto W4886RegEnd;

	XFR_IIC_MBUF=reg_addr;	// 写入字地址的低8位
	I2c_Wait();
	if (XFR_IIC_STUS2&0x80)  goto W4886RegEnd;

	XFR_IIC_MBUF=value;		// 写入值
	I2c_Wait();

W4886RegEnd:
	I2c_Stop();
	
#ifdef DisableInt
	EA=EAbak;
#endif
}
#endif
/*--------------------------- Write_TDA4886_Reg 结束 ------------------------*/

       
/********************************************************************  
* 	函 数 名: Write_TDA48XX_Reg
* 	功能描述: 写入一个字节的数到TDA48XX(4857/4841/4856)的寄存器当中
* 	输    入: reg_addr	:寄存器地址
*			  value		:写入到寄存器的值
* 	返    回: 无
***********************************************************************/
#if I2cBusType==0		// 采用模拟的IIC总线
void Write_TDA48XX_Reg(unsigned char reg_addr,unsigned char value)
{
#ifdef DisableInt
	bit EAbak;
	EAbak=EA;
	EA=0;
#endif

	I2c_Start();
	SendByte(0x8c);			// 写入TDA48XX的器件地址
//	if (!I2c_Ack)  goto W48XXRegEnd;

	SendByte(reg_addr);	// 写入寄存器地址
//	if (!I2c_Ack)  goto W48XXRegEnd;

	SendByte(value);		// 写入值

//W48XXRegEnd:
	I2c_Stop();
	
#ifdef DisableInt
	EA=EAbak;
#endif
}

//------------------------------------------------------------------------
#elif I2cBusType==1	// 采用MTV212的专用IIC总线接口
void Write_TDA48XX_Reg(unsigned char reg_addr,unsigned char value)
{
#ifdef DisableInt
	bit EAbak;
	EAbak=EA;
	EA=0;
#endif

	XFR_IIC_MBUF=0x8c;		// 写入TDA48XX的器件地址
	I2c_Start();
	if (XFR_IIC_STUS2&0x80)  goto W48xxRegEnd;

	XFR_IIC_MBUF=reg_addr;	// 写入字地址的低8位
	I2c_Wait();
	if (XFR_IIC_STUS2&0x80)  goto W48xxRegEnd;

	XFR_IIC_MBUF=value;		// 写入值
	I2c_Wait();

W48xxRegEnd:
	I2c_Stop();
	
#ifdef DisableInt
	EA=EAbak;
#endif
}
#endif

#define SCLHigh() 	{ SCL  = 1; while(!SCL);  }
//#define SCLHigh2() 	{ SCL2 = 1; while(!SCL2); }



/*********************************************
* Send one byte of data to an I2C device     *
**********************************************/
void SendI2CByte(unsigned char val)
{
	unsigned char bmsk = 0x80;
    while (bmsk) 
	{
        SDA = (val & bmsk) ? 0x01 : 0x00;
        SCLHigh(); 
        bmsk >>= 1;
        SCL = 0; 
    }
    SDA = 1;
    SCLHigh();
    if (SDA) NoAck = 1;
    SCL = 0; 
	   
}         

/********************************************************
* Grasp the I2C bus, send slave address and command     *
*********************************************************/
void GoI2CMaster(unsigned char adr)
{
	if (!SCL) SCLHigh();
    NoAck = 0; 
    BusFault = 0;
    if (SCL & SDA) {
        SDA = 0; 
        _nop_();
        SCL = 0; 
        _nop_(); 
        SendI2CByte(adr);
    } 
	else
    BusFault = 1;
}


/*********************************************
* Receive byte of data from an I2C device    *
**********************************************/
unsigned char RcvI2CByte(unsigned char cnt)
{
                
    unsigned char bval = 0, b;

    for(b=0; b < 8; b++) {
        SCLHigh(); 
        bval <<= 1;
        bval |= SDA;
        SCL = 0;	
	}

    SDA = (cnt==1) ? 1 : 0;
    SCLHigh();
    SCL = 0;
    SDA = 1;         //Clear acknowledge bit.
    return bval;
}

/*************************************
* Send I2C STOP, release bus         *
**************************************/
void SendI2CStop(void)
{
    SDA = 0; 
    _nop_();  
    SCLHigh(); 
    _nop_();  
    SDA = 1; 
    _nop_();
}
/*********************************************
* Send bytes of data to standard device      *
**********************************************/

void eepByteOut(unsigned int index, unsigned char val)//对CPU来说是向EEPROM中发送数据对EEPROM来讲是存
{
   unsigned char slv;

#if DISABLEINT0
	bit IntFlag;

	/* disable interrupt 0 */
	IntFlag = EX0;
	EX0 = 0;
#endif

	PIN_EepWrite_eanable = 0;

   slv=0;
   slv=slv<<1;
   slv=slv|0xA0;

	/* I2C Start and send WRITE slave address */
 	GoI2CMaster(slv);
	if(NoAck | BusFault) goto buserror;

	/* Send index */
	SendI2CByte((unsigned char)index);
	if(NoAck) goto buserror;

	/* data transmit */
	SendI2CByte(val);
    //miscDelay(20);

    goto endi2c;

buserror:	

endi2c:
	SendI2CStop();
       miscDelay(15);
    
    PIN_EepWrite_eanable = 1;
    
#if DISABLEINT0
	EX0 =	IntFlag;
#endif    
}

unsigned char eepByteIn(unsigned int index)//对CPU来说是从EEPROM中往出读数据,对EEPROM来讲是取
{
   unsigned char bval;
   unsigned char slv;

   slv=index/256;
   slv=slv<<1;
   slv=slv|0xA0;

	/* I2C Start and send WRITE slave address */
 	GoI2CMaster(slv);
	if(NoAck | BusFault) goto buserror;

	/* Send index */
	SendI2CByte((unsigned char) index);
	if(NoAck) goto buserror;

	/* I2C Start and send READ slave address */
 	GoI2CMaster(slv | 0x01);
	if(NoAck) goto buserror;

	/* data transmit */
	bval = RcvI2CByte(1);

    goto endi2c;

buserror:	

endi2c:
	/* Finish trasmition */
	SendI2CStop();

	return(bval);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -