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

📄 eep24c512.c

📁 avr单片机源码
💻 C
字号:
#include <iom16v.h>

#include "eep24c512.h"
//EEPROM数据接口PB4
#define SCL_set asm("sbi 0x18,4")
#define SCL_clr asm("cbi 0x18,4")
//EEPROM时钟接口PB3
#define SDA_set asm("sbi 0x18,3")
#define SDA_clr asm("cbi 0x18,3")

void delayus1(unsigned char i)
{
 while(i)
 i--;
 asm("nop");
}

void EEP_Start (void)         //I2C发送开始位
{
 DDRB|=0x18;                  //将PB4数据端口(SDA),PB3时钟端口(SCL)设为输出
 SCL_set;		          	  //将时钟端口(SCL)设为高
 asm("nop");	
 asm("nop");	
 asm("nop");
 SDA_set;		          	  //将数据端口(SDA)设为高
 asm("nop");	
 asm("nop");	
 asm("nop");	
 SDA_clr;		          	  //将数据端口(SDA)设为低
 asm("nop");	
 asm("nop");	
 asm("nop");
 SCL_clr;
}

void EEP_Stop (void)          //I2C发送停止位
{
 DDRB|=0x18;                 //将数据端口(SDA),时钟端口(SCL)设为输出
 SDA_clr;		          //将数据端口(SDA)设为低
 asm("nop");	
 asm("nop");	
 asm("nop");
 SCL_set;                //将时钟端口(SCL)设为高
 asm("nop");	
 asm("nop");	
 asm("nop");
 SDA_set;		          //将数据端口(SDA)设为高
 asm("nop");	
 asm("nop");	
 asm("nop");
}

//CPU接收完数据对EEPROM应答
void ack()
{
 DDRB|=0x18;
 SDA_clr;
 delayus1(5);
 SCL_set;
 delayus1(5);
 SCL_clr;
 delayus1(5);
 //SDA_set; 
}

//CPU接收完数据不对EEPROM应答
void noack()
{
 DDRB|=0x18;
 SDA_set;
 delayus1(5);
 SCL_set;
 delayus1(5);
 SCL_clr;
 delayus1(5);
}

//对EEPROM写完数据,检查EEPROM是否应答
void EEP_Ackn(void)
{
 SCL_clr;                	// 将时钟端口(SCL)设为低
 DDRB|=0x10;				//时钟端口为输出
 DDRB&=0xF7;       		    // 设置数据口(SDA)为输入	
 SCL_set;                	//将时钟端口(SCL)设为高
 while((PINB&0x08) == 0x08)			// 
 {
    asm("nop");
  }  
 SCL_clr;                	// 将时钟端口(SCL)设为低
}

void Write_EEP_Byte(unsigned char byte)     //写一个字节到I2C设备
{
 unsigned char i;
 DDRB|=0x18;   	              //将PA0数据端口(SDA)设为输出
 for (i = 0; i < 8; i++)      //传送8位数据
     {  	
	 SCL_clr;                 //将时钟端口(SCL)设为低	 
     if((byte & 0x80)==0x80) 
	 SDA_set;	       		  // 设置 SDA 位
	 else 
	 SDA_clr;		  	      // 清除 SDA 位
	 delayus1(5);	
	 SCL_set;                 //将时钟端口(SCL)设为高
     delayus1(5);	
 	 byte = byte << 1;		  //将输出数据左移一位
	}
 SCL_clr;                 	  // 校验标志位 (每传送8位,有一校验位)
 EEP_Ackn();
}

unsigned char Read_EEP_Byte(void)   //读取I2C设备的数据
{	
 unsigned char i,buff = 0;
 DDRB|=0x10;                 //PA1为时钟,输出
 DDRB&=0xF7;       		     //设置数据口(SDA)为输入
 asm("nop");	
 asm("nop");	
 for (i = 0; i < 8; i++)
    {
	 SCL_clr;                // 将时钟端口(SCL)设为低
	 delayus1(5);
	 SCL_set;                //将时钟端口(SCL)设为高
	 delayus1(5);
 	 // 在 SDA 位上读取数据
	 buff = (buff << 1);
	 if ( (PINB&0x08)==0x08 ) 
	 buff++;
	 asm("nop");	
    }
 SCL_clr;
 delayus1(5);
 return buff;				     // 返回读取值
}

//address为16位首地址,连续读
//data1为读入的数据的地址指针
//number为读入数据的字节个数
void eep_read(unsigned int address,unsigned char *data1,unsigned char number)
{
//unsigned char epp[6]={0,0,0,0,0,0};
unsigned char address_h;
unsigned char address_l;
address_h=address<<8;
address_l=address>>8;
EEP_Start();
Write_EEP_Byte(0xa0);
Write_EEP_Byte(address_h);
Write_EEP_Byte(address_l);
EEP_Start();
Write_EEP_Byte(0xa1);
while(number!=1)
{
  *data1=Read_EEP_Byte();
  ack();
  data1++;
  number--;
}
*data1=Read_EEP_Byte();
noack();
EEP_Stop();
}

//address为首地址,连续写
//data1为要写入的数据的首地址
//number为写入字节数
void eep_write(unsigned int address,unsigned char *data1,unsigned char number)
{
unsigned char address_h;
unsigned char address_l;
address_h=address<<8;
address_l=address>>8;
EEP_Start();
Write_EEP_Byte(0xa0);
Write_EEP_Byte(address_h);
Write_EEP_Byte(address_l);
for(;number!=0;number--)
{
   Write_EEP_Byte(*data1);
   data1++;
}
EEP_Stop();
}

⌨️ 快捷键说明

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