📄 eep24c512.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 + -