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

📄 fm24c64.c

📁 AVR单片机ATMEGA162的IIC模拟控制铁电FM24C64子程序
💻 C
字号:
*-------------------------------------------------------------
2007-05-06
CPU:atmega162
晶振:4MHz	
FRAM:FM24C64
IIC模拟控制铁电子程序 
---------------------------------------------------------------*/
                                                 
#define IIC_READ   0xa1      //定义读指令
#define IIC_WRITE  0xa0      //定义写指令     

#define SDA        PORTC.2              
#define SDA_IN     PINC.2
#define SCL        PORTC.1  
#define WP         PORTC.0

bit IFACK;	                 //record the SDA state to confirn if ACK has happened 
bit NO_ACK;	                 //no ack flag
//bit BUS_FAULT;	     //bus fault flag

//========================================
// Declare your global variables here
void Delay_NOP(void)
{
     delay_us(5); 
}

//========================================
//FUNCTION:ROUTES TO PROVIDE A START SIGNAL
void start(void)
{
     DDRC.0=1;
     DDRC.1=1;
     DDRC.2=1;
     WP=0;
     SCL=0;
     Delay_NOP();
     SDA=1;  
     Delay_NOP();
     SCL=1;      
     Delay_NOP();
     SDA=0;      
     Delay_NOP();
     SCL=0;   
     Delay_NOP();
}
      
//=======================================
//FUNCTION:ROUTES TO PROVIDE A STOP SIGNAL
void stop(void)
{
     DDRC.2=1;
     SCL=0;
     Delay_NOP();
     SDA=0;      
     Delay_NOP();
     SCL=1;      
     Delay_NOP();
     SDA=1;      
     Delay_NOP();
     SCL=0;      
     Delay_NOP(); 
     WP=1;
}    
 
/*
//=====================================
//FUNCTION:ROUTES TO PROVIDE ACK SINGAL
void ack(void)
{
     DDRC.2=1;
     SCL=0;
     Delay_NOP();
     SDA=0;      
     Delay_NOP();
     SCL=1;      
     Delay_NOP();
     SCL=0;
     Delay_NOP();
}
*/
 
//=====================================
//FUNCTION:ROUTES TO RELEASE THE SDA TO RECEIVE A ACK SIGNAL 
//	             OR TO PROVIDE A NO_ACK SIGNAL
//type=1等待应答信号
//type=0 产生无应答信号
void nack(unsigned char type)
{
     DDRC.2=1;
     SCL=0;    
     Delay_NOP();
     SDA=1;      
     Delay_NOP();
     SCL=1;      
     DDRC.2=0;
     Delay_NOP();
     IFACK= SDA_IN;
     Delay_NOP();
     SCL=0;      
     Delay_NOP();
     if(type)
     {
           if(IFACK)//如果无应答信号,则置标志位NO_ACK,程序中止
           {	
                NO_ACK=1;//用户可以加入自己的异常处理程序
           }
           else NO_ACK=0;
     }
}

//=======================================================
//FUNCTION:THE IIC DEVICE SHIFT OUT A BYTE  TO THE MASTER
unsigned char inbyte(void) 
{                          //从IIC器件中读出数据
     unsigned char a0,a1,a2,a3,a4,a5,a6,a7;
     unsigned int acc;
     unsigned char bbyte;
     DDRC.2=1;
     SDA=1;Delay_NOP();
     DDRC.2=0;
     SCL=1;Delay_NOP();a7=SDA_IN;SCL=0;Delay_NOP();
     SCL=1;Delay_NOP();a6=SDA_IN;SCL=0;Delay_NOP();
     SCL=1;Delay_NOP();a5=SDA_IN;SCL=0;Delay_NOP();
     SCL=1;Delay_NOP();a4=SDA_IN;SCL=0;Delay_NOP();
     SCL=1;Delay_NOP();a3=SDA_IN;SCL=0;Delay_NOP();
     SCL=1;Delay_NOP();a2=SDA_IN;SCL=0;Delay_NOP();
     SCL=1;Delay_NOP();a1=SDA_IN;SCL=0;Delay_NOP();
     SCL=1;Delay_NOP();a0=SDA_IN;SCL=0;Delay_NOP();
     acc=a0;
     acc=acc+(a1<<1);
     acc=acc+(a2<<2);
     acc=acc+(a3<<3);
     acc=acc+(a4<<4);
     acc=acc+(a5<<5);
     acc=acc+(a6<<6);
     acc=acc+(a7<<7);
     bbyte=acc%256;
     return(bbyte);
}
   
//=======================================================
//FUNCTION:THE IIC DEVICE SHIFT IN A BYTE FROM THE MASTER 
void outbyte(unsigned char outdata) 
{                          //将数据写放IIC器件
     unsigned char a0,a1,a2,a3,a4,a5,a6,a7;  
     unsigned char bbyte;
     DDRC.2=1;
     
     bbyte=outdata;
     a7=bbyte>>7;
     bbyte&=0x7f;
     a6=bbyte>>6;
     bbyte&=0x3f;
     a5=bbyte>>5;
     bbyte&=0x1f;
     a4=bbyte>>4;
     bbyte&=0x0f;
     a3=bbyte>>3;
     bbyte&=0x07;
     a2=bbyte>>2;
     bbyte&=0x03;
     a1=bbyte>>1;
     bbyte&=0x01;
     a0=bbyte;
     
     SDA=a7;SCL=1;Delay_NOP();SCL=0;Delay_NOP();
     SDA=a6;SCL=1;Delay_NOP();SCL=0;Delay_NOP();
     SDA=a5;SCL=1;Delay_NOP();SCL=0;Delay_NOP();
     SDA=a4;SCL=1;Delay_NOP();SCL=0;Delay_NOP();
     SDA=a3;SCL=1;Delay_NOP();SCL=0;Delay_NOP();
     SDA=a2;SCL=1;Delay_NOP();SCL=0;Delay_NOP();
     SDA=a1;SCL=1;Delay_NOP();SCL=0;Delay_NOP();
     SDA=a0;SCL=1;Delay_NOP();SCL=0;Delay_NOP();
}

//======================================================
//FUNCTION:BYTE WRITE.  'add'     THE WRITE ADDRESS, 'wbyte'   THE DATA WANT TO WRITE
void writebyte(unsigned int add,unsigned char wbyte)//add为写入地址,wbyte为写入数据
{
      unsigned char temph,templ;
      temph=(unsigned char)(add/256);
      templ=(unsigned char)(add%256);
      start(); 			//开始信号
      outbyte(IIC_WRITE);	            //写命令
      nack(1);			//等待应答
      outbyte(temph);		            //写地址
      nack(1);			//等待应答
      outbyte(templ);		            //写地址
      nack(1);
      outbyte(wbyte);			//写数据
      nack(1);			//等待应答
      stop();			//停止信号
}
   

//=====================================================
//FUNCTION:RANDOM READ.'add' IS THE ADDRESS WANT TO READ
unsigned char readbyte (unsigned int add)       //add为读地址
{
      unsigned char temp,temph,templ;	
      temph=(unsigned char)(add/256);
      templ=(unsigned char)(add%256);
      start();			//开始信号
      outbyte(IIC_WRITE);		//写命令
      nack(1);			//等待应答
      outbyte(temph);		            //写地址
      nack(1);			//等待应答
      outbyte(templ);		            //写地址
      nack(1);
      start();			//开始信号
      outbyte(IIC_READ);		//读命令
      nack(1);			//等待应答
      temp=inbyte();			//读数据
      nack(0);			//无应答
      stop();			//停止信号
      return(temp);
}

//=================================================
//连写函数
//add为读起始地址,ptr数据保存指针,writelen为写入数据长度
void writebyteseq(unsigned int add,unsigned char *ptr,unsigned int writelen)
{
      unsigned char temph,templ;
      unsigned int i;
      temph=(unsigned char)(add/256);
      templ=(unsigned char)(add%256);
      start(); 		
      outbyte(IIC_WRITE);		
      nack(1);		
      outbyte(temph);
      nack(1);
      outbyte(templ);
      nack(1);
      for(i=0;i<writelen;i++)
      {
              outbyte(*(ptr+i));
              nack(1);
      }
      stop();	
}

//=================================================
//连读函数
//add为读起始地址,ptr数据保存指针,writelen为读出数据长度
void readbyteseq(unsigned int add,unsigned char *ptr,unsigned int readlen)
{
      unsigned char temph,templ;
      unsigned int i;
      temph=(unsigned char)(add/256);
      templ=(unsigned char)(add%256);
      start();
      outbyte(IIC_WRITE);
      nack(1);
      outbyte(temph);
      nack(1);
      outbyte(templ);
      nack(1);
      start();
      outbyte(IIC_READ);
      nack(1);
      for(i=0;i<readlen-1;i++)
      {
               *(ptr+i)=inbyte();
               ack();	
      }
      *(ptr+readlen-1)=inbyte();
      nack(0);
      stop();
}




⌨️ 快捷键说明

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