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

📄 wri2c.c

📁 I2C程序,自己写的一个I2C读写程序
💻 C
字号:
#ifndef WRI2C_C
#define WRI2C_C
#include "config.h"

#define		IIC_24C01		0
#define		IIC_24C02		0
#define		IIC_24C04		0
#define		IIC_24C16		0		//2K bytes
#define		IIC_24C32		1
#define		IIC_24C64		1
#define		IIC_24C128		1
#define		IIC_24C256		1

//定义对24C16访问的页,共8页,每页256个字节,每次页读、写可操做16个字节
#define		C16_PAGE1		0
#define		C16_PAGE2		2
#define		C16_PAGE3		4
#define		C16_PAGE4		6
#define		C16_PAGE5		8
#define		C16_PAGE6		10
#define		C16_PAGE7		12
#define		C16_PAGE8		14
/*==============================
;本程序应用于有,无高位子地址的IIC器件,通过SubAddrHiBit设定
;bit SubAddrHiBit=1说明器件为16位数据地址,=0说明器件为8位数据地址。
================================*/
//延时:用于w77e58,18.432M ,每指令=4/18.432=0.217us
void F1us(void){
		nop();nop();nop();nop();nop();nop();
}
void F5us(void){
uchar x=2;
	while(x--){
		F1us();
		F1us();
		F1us();
		F1us();
		F1us();
	}
}
void Delay10us(uchar x){
	while(x--){
		F5us();
		F5us();
	}
}
void Delay1ms(uchar x){
	while(x--){
		Delay10us(100);
	}
}

//extern void F1us(void);						//产生1us的延时时间
//extern void Delay5us(register uchar x);		//5us延时
//extern void Delay10us(register uchar x);	//10us延时
//extern void Delay1ms(register uchar x);		//1ms延时
//#define		F5us()  Delay5us(1)
/********************************
功能:i2c总线启动程序
入口:无
出口:无
反回:无
日期:03-9-29
***********************************/
void	Start_I2c(void){
 	pinSDA=1;F1us();
	pinSCL=1;F5us();	//发送起始条件的数据信号,发送起始条件的时钟信号
	pinSDA=0;F5us();	//发送起始信号
	pinSCL=0;F1us();F1us();	//钳住i2c 总线准备发送或接收数据
}
/*********************************
描述:停止i2c 总线子程序--发送i2c 总线停止条件
入口:无
出口:无
反回:无
日期:03-9-29
**********************************/
void	Stop_I2c(void){
	pinSDA=0;F1us();			//发送结束条件时钟信号
	pinSCL=1;F5us();		//发送停止条件的数据信号,发送停止条件的时钟信号
	pinSDA=1;F5us();		//发送i2c 总线停止信号
}
/*******************************************************************
                 字节数据发送函数
函数原型: void  SendByte(uchar c);
功能:     将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
          此状态位进行操作.(不应答或非应答都使ack=0)
     	  发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
bit  SendByte(uchar  c)small{
uchar idata BitCnt=8;
bit bdata ack;
	while(BitCnt--){  /*要传送的数据长度为8位*/
	     if(c&0x80)pinSDA=1;   /*判断发送位*/
	     else  pinSDA=0;
	     c<<=1;
	     pinSCL=1;               /*置时钟线为高,通知被控器开始接收数据位*/
	     F5us();
	     pinSCL=0;
	}
		F1us(); F1us();
	    pinSDA=1;                /*8位发送完后释放数据线,准备接收应答位*/
	    F1us();F1us();
	    pinSCL=1;
	    F1us();F1us();F1us();
	    if(pinSDA==1)ack=0;
	    else ack=1;        /*判断是否接收到应答信号*/
	    pinSCL=0;
	    F1us(); F1us();
	    return (ack);


}
/*******************************************************************
                 字节数据接收函数
函数原型: uchar  RcvByte();
功能:  	  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
          发完后请用应答函数应答从机。
********************************************************************/
uchar  RcvByte(){
uchar idata retc=0;
uchar idata BitCnt;
  pinSDA=1;             		/*置数据线为输入方式*/
  for(BitCnt=0;BitCnt<8;BitCnt++) {
      F1us();
      pinSCL=0;                  /*置时钟线为低,准备接收数据位*/
      F5us();
      pinSCL=1;                  /*置时钟线为高使数据线上数据有效*/
      F5us();
      retc=retc<<1;
      if(pinSDA==1)retc=retc+1;  /*读数据位,接收的数据位放入retc中 */
      F1us();F1us();
  }
  pinSCL=0;
  F1us();
  F1us();
  return(retc);
}
/********************************************************************
                     应答子函数
函数原型:  void Ack_I2c(bit a);
功能:      主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(bit a){
  if(a==0)pinSDA=0;     	     /*在此发出应答或非应答信号 */
        else pinSDA=1;
  F5us();
  pinSCL=1;
  F5us();
  pinSCL=0;                     /*清时钟线,钳住I2C总线以便继续接收*/
  F1us();F1us();
}

/*************************************
描述:发送bytecnt 个字节给被控器,
		发送的数据在以xmtdat的内容为地址的缓冲区中
入口:uchar	slvadr,subadr_hi,subadr_low,SlvAdr,byteCnt,xmtdat
出口:无
反回:返回bit,=1发送数据正常,=0表示被控器无应答或损坏
全局:SubAddrHiBit(如器件单元地址为16位则置1,否则置0)
日期:04-7-1
*****************修正*******************
04-12-27:加SubAddrHiBit进行器件地址控制,及数据结构
**************************************/
bit	SendDatai2c(bit SubAddrHiBit,uchar   slvadr,uchar   ByteCount,uchar   SadrHi,uchar  SadrLow,uchar  *  xmtdat)
{
uchar i;

	EnableWriteI2c();			//关闭写保护
    Delay10us(5);

	Start_I2c();
	slvadr&=0xfe;				//说明进行写操作
	if(SendByte(slvadr)==0)		//发送器件地址
		goto Sendi2cFalse;
	if(SubAddrHiBit)			//发送单元地址hi
	{
		if(SendByte(SadrHi)==0)
			goto Sendi2cFalse;
	}
	if(SendByte(SadrLow)==0)		//发送单元地址low
		goto Sendi2cFalse;
	Delay1ms(6);
	for(i=0;i<ByteCount;i++){		//发送缓冲区内的数据
		if(SendByte(*xmtdat)==0)
			goto Sendi2cFalse;
		xmtdat++;
	}
	Stop_I2c();				//;发送i2c 总线停止条件
	Delay1ms(10);			//;延时10ms,等待数据写完
	DisableWriteI2c();		//写保护
	//TR2=1;
	return(TRUE);
Sendi2cFalse:
	//TR2=1;
	DisableWriteI2c();		//写保护
	return(FALSE);
}

/**********************************
描述:接收bytecnt 个到缓冲区,
		接收的数据在以rcvdat的内容为地址的缓冲区
入口:uchar	slvadr,subadr_hi,subadr_low,bytecnt,rcvdat
出口:无
全居:ByteCount,slvadr
反回:返回bit,=1发送数据正常,=0表示被控器无应答或损坏
全局:SubAddrHiBit(如器件单元地址为16位则置1,否则置0)
日期:04-7-1
*****************修正*******************
04-12-27:加SubAddrHiBit进行器件地址控制,及数据结构
************************************/
bit	RcvDatai2c(bit SubAddrHiBit,uchar   slvadr,uchar   ByteCount,uchar   SadrHi,uchar   SadrLow,uchar  *  rcvdat)
{
uchar  i;
	//TR2=0;		//在读I2C时不允许定时器2中断
	pinSCL=1;
    pinSDA=1;
    Delay10us(5);
	Start_I2c();
				//说明进行写操作
	if(SendByte(slvadr&0xfe)==0) 	//发送器件地址
		goto Rcvi2cFalse;
	if(SubAddrHiBit)
		if(SendByte(SadrHi)==0) //发送单元地址hi
			goto Rcvi2cFalse;
	if(SendByte(SadrLow)==0) 	 //发送单元地址low
		goto Rcvi2cFalse;
	Start_I2c();			 /*重新启动总线*/
				//进行读操做
	if(SendByte(slvadr|1)==0)
		goto Rcvi2cFalse;

	for(i=0;i<ByteCount-1;i++){		//发送缓冲区内的数据
		*rcvdat=RcvByte();
		Ack_I2c(0);                /*发送就答位*/
		rcvdat++;
	}
	*rcvdat=RcvByte();
	Ack_I2c(1);                   /*发送非应位*/
	Stop_I2c();

	Delay1ms(10);
	//TR2=1;
	return(TRUE);
Rcvi2cFalse:
	//TR2=1;
	Delay1ms(10);
	return(FALSE);
}
#endif

⌨️ 快捷键说明

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