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

📄 fm24c16.c

📁 C51的FM24c256的驱动程序 C51的FM24c256的驱动程序
💻 C
字号:
#include <reg51f.h>
#include <intrins.h>
#include <string.h>
#include <absacc.h>

#define IIC_READ  0xA1                                 //定义读指令
#define IIC_WRITE  0xA0                                //定义写指令
#define  uchar  unsigned char                          //宏定义 
#define  uint   unsigned int                           ///宏定义
#define SomeNOP(); _nop_();_nop_();_nop_();_nop_();                   

sbit SDA=P0^1;            	                           //I2C2数据传送位 
sbit SCL=P0^2;                          	           //I2C2时钟控制位 
sbit WP=P0^3;                                         //eerom掉电写保护
bit ack;	                                           //应答标志位 


/***************************起动总线函数***************************                                 
函数原型: 	  void  Start_I2c();  
功能描述:     启动I2C总线,即发送I2C起始条件.  
********************************************************************/
void Start_I2c()
{
  EA=0;          //关中断
  WP = 0;        //关写保护
  SomeNOP();     //待高电平稳定 
  SDA=1;   	    //发送起始条件的数据信号  
  SCL=1;
  SomeNOP();     //待高电平稳定    
  SDA=0;   	    //发送起始信号 
  SomeNOP();       
  SCL=0;   	    //钳住I2C总线,准备发送或接收数据   
}

/******************************结束总线函数**************************                                    
函数原型:   void  Stop_I2c();  
功能描述:   结束I2C总线,即发送I2C结束条件.  
********************************************************************/
void Stop_I2c()
{
  SCL=0;
  SDA=0;    	//发送结束条件的数据信号  
  SomeNOP();   	
  SCL=1;  	    //发送结束条件的时钟信号 
  SomeNOP();
  SDA=1;  	    //发送I2C总线结束信号 
  WP = 1;       //写保护
  SomeNOP();     //待高电平稳定 
  EA=1;         //开中断
}

/********************************应答子函数***************************                     
函数原型:  void Ack_I2c(bit a);
功能描述:      主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(bit a)
{
  
  if(a==0)
     SDA=0;     	         //在此发出应答或非应答信号 
  else 
    SDA=1;
      
  SCL=1;  
  SCL=0;                    //清时钟线,钳住I2C总线以便继续接收
     
}



/****************************字节数据发送函数*************************
                                
函数原型:   void  SendByte(uchar c);
功能描述:   将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
            此状态位进行操作.(不应答或非应答都使ack=0)     
     	    发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void  SendByte(uchar c)
{
 uchar BitCnt;
 
 for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位 
    {
      if((c<<BitCnt)&0x80)SDA=1;   //判断发送位 
        else  SDA=0;             
      SCL=1;                       //置时钟线为高,通知被控器开始接收数据位               
      SCL=0; 
    }      
    SDA=1;                        //8位发送完后释放数据线,准备接收应答位      
    SCL=1;  
    if(SDA==1)ack=0;       
       else ack=1;               //判断是否接收到应答信号,如果正确第九个sda为零
    SCL=0; 
}

/******************************单个字节数据接收函数 *************************************
                               
函数原型:    uchar  RcvByte();
功能描述:  	 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
             发完后请用应答函数应答从机。  
********************************************************************/
	
uchar  RcvByte()
{
  uchar retc;
  uchar BitCnt;
  
  retc=0; 
  SDA=1;             		         //置数据线为输入方式
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {
                  
        SCL=0;                       //置时钟线为低,准备接收数据位       
        SCL=1;                       //置时钟线为高使数据线上数据有效        
        retc=retc<<1;
        if(SDA==1)retc=retc+1;       //读数据位,接收的数据位放入retc中        
      }
  SCL=0;    
  return(retc);
}

/************************向有子地址器件发送字节数据函数*******************                                
函数原型:    bit  ISendByte(uchar sla,uchar c);  
功能描述:    从启动总线到发送命令,地址,数据,结束总线的全过程,器件子地址sbua.
             如果返回1表示操作成功,否则操作有误。
********************************************************************/
bit ISendByte(uint suba,uchar c)   //写字节
{
	uchar temp,tempw;

	temp=(uchar)(suba>>8);        //temp=0 0 0 0  0 a10 a9 a8
	tempw=(IIC_WRITE|(temp<<1));  //tempw=1 0 1 0 a10 a9 a8 0
    Start_I2c();                  //启动总线
    SendByte(tempw);              //发送命令            
    if(ack==0)return(0);
	SendByte((uchar)suba);               //发送地址
    if(ack==0)return(0);
    SendByte(c);                  //发送数据
    if(ack==0)return(0);
    Stop_I2c();                   //结束总线
    return(1);
}


/****************向有子地址器件发送多字节数据函数*******************                                   
函数原型: bit  ISendStr(uchar suba,uchar *s,uchar no);  
功能:     从启动总线到发送命令,子地址,数据,结束总线的全过程           
          如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
bit ISendStr(uint suba,uchar *s,uchar no)
{
	uchar i;
	uchar temp,tempw;

	temp=(uchar)(suba>>8);      //temp=0 0 0 0  0 a10 a9 a8
	tempw=(IIC_WRITE|(temp<<1));//tempw=1 0 1 0 a10 a9 a8 0
    Start_I2c();               //启动总线
    SendByte(tempw);           //发送命令
    if(ack==0)return(0);
    SendByte((uchar)suba);            //发送器件子地址
    if(ack==0)return(0);
    for(i=0;i<no;i++)
    {   
     	SendByte(*s);            //发送数据
     	if(ack==0)return(0);
     	s++;
    } 
    Stop_I2c();                //结束总线 
    return(1);
}
/***********************向有子地址器件读字节数据函数 **************
                                  
函数原型:    bit  IRcvByte(uchar sbua ,ucahr *c);  
功能描述 :   从启动总线到发送命令,地址,读数据,结束总线的全过程,器件子地
             址sbua ,返回值在c.
             如果返回1表示操作成功,否则操作有误。
********************************************************************/
bit IRcvByte(uint sbua,uchar *c)         //读字节
{
	uchar temp,tempw,tempr;
	
	temp=(uchar)(sbua>>8);              //temp=0 0 0 0  0 a10 a9 a8
	tempw=(IIC_WRITE|(temp<<1));      //tempw=1 0 1 0 a10 a9 a8 0
	tempr=(IIC_READ|(temp<<1));  //tempr=1 0 1 0 a10 a9 a8 1
    Start_I2c();                      //启动总线
	SendByte(tempw);                  //写命令
	if(ack==0)return(0);
	SendByte((uchar)sbua);                   //写地址
	if(ack==0)return(0);

	Start_I2c();                      //重新启动总线
    SendByte(tempr);                  //读命令
    if(ack==0)return(0);
    *c=RcvByte();                     //读取数据
    Ack_I2c(1);                       //发送非就答位
    Stop_I2c();                       //结束总线 
    return(1);
}


/*********************向有子地址器件读取多字节数据函数 **********************************************
                                
函数原型:   bit  ISendStr(uchar suba,uchar *s,uchar no);  
功能描述:   从启动总线到发送命令,子地址,读数据,结束总线的全过程,         
            如果返回1表示操作成功,否则操作有误。
********************************************************************/
bit IRcvStr(uint suba,uchar *s,uchar no)
{
    uchar i;
    uchar temp,tempw,tempr;
	
	temp=(uchar)(suba>>8);              //temp=0 0 0 0  0 a10 a9 a8
	tempw=(IIC_WRITE|(temp<<1));      //tempw=1 0 1 0 a10 a9 a8 0
	tempr=(IIC_READ|(temp<<1));  //tempr=1 0 1 0 a10 a9 a8 1
    Start_I2c();                      //启动总线
    SendByte(tempw);                    //写命令
    if(ack==0)return(0);
    SendByte((uchar)suba);                   //写地址
    if(ack==0)return(0);

    Start_I2c();			          //重新启动总线
    SendByte(tempr);
    if(ack==0)return(0);
    for(i=0;i<no-1;i++)
    {   
    	 *s=RcvByte();               //发送数据
     	 Ack_I2c(0);                //发送就答位
     	s++;
    } 
    *s=RcvByte();
    Ack_I2c(1);                   //发送非应位
    Stop_I2c();                   //结束总线 
    return(1);
}

/*******************
void main(void)
{

	while(1)
	{
		//uchar a[4]={0xed,0xaa,0x55,0xcc};
		uchar a[4]={0xDc,0x55,0xaa,0xed};
		uchar d=0xAa;       
		ISendStr(0x400,a,4);			
		IRcvStr(0x400,b,4);
        ISendByte(0x300,d);
        IRcvByte(0x300,c);    
		IRcvStr(0x400,b1,4);	
	}
}
**********************/

⌨️ 快捷键说明

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