📄 at24c512.h
字号:
/*
AT24C512驱动头文件:
注:本头文件默认单片机频率为8M,I2C传输速率为400K,如果改变单片机频率,
需要将i2cdelay()函数 BIT率寄存器TWBR的值进行修改
AT24C512最大传输速率:1 MHz (5V), 400 kHz (2.7V), 100 kHz (1.8V)
AT24C512拥有128-byte的页面缓存空间
AT24C512读写安全时间间隔为5 ms
使用此头文件前,首先必须在main()函数中调用I2cinit()以初始化通信接口
发送:
1.选择需要写入的器件号icnumber,范围1--4,格式:icnumber=1;
(AT24C512允许4片并行使用,空间可以扩展到512*4=1024 BIT位)
2.选择写入data首地址,范围0x0000--0xffff,格式:address=0x0000;
3.输入需要发送的字节数total,范围1--128,格式:total=12;
注:前面3步可以直接调用
i2control(char i2cicnumber,unsigned int i2caddress,char i2ctotal);
4.给发送缓存Send_buffer[]赋值,最多128个8位变量
5.调用Send_i2c_data();函数来完成对data数据的发送
接收:
1.选择需要读取的器件号icnumber,范围1--4,格式:icnumber=1;
2.选择接收data首地址,范围0x0000--0xffff,格式:address=0x0000;
3.输入需要接收的字节数total,范围1--128,格式:total=12;
注:前面3步可以直接调用
i2control(char i2cicnumber,unsigned int i2caddress,char i2ctotal);
4.调用Read_i2c_data();函数来完成对data数据的接收,
接收数据将存入Receive_buffer[];
编写:李科 2006-02-25
修改:李科 2006-10-16 */
/******************************定义变量区**************************************/
char Send_buffer[128]; //(主控mcu/通信模块中设置的)发送缓冲区
char Load_point=0; //中断内,发送数据存储位置
char SendI2c_data=0; //需要发送I2c数据
char newpoint=0; //已经发送个数标志位
char Receive_buffer[128]; //(主控mcu/通信模块中设置的)接收缓冲区
char Get_point=0; //中断内,接收数据存储位置
char ReceiveI2c_data=0; //接收到的I2c数据
char Error_flag=0; //出错标志位
char icnumber=0; //ic地址号码A1 A0
unsigned int address=0; //数据储存地址
unsigned int laddress=0; //数据储存地址低8位数据
char addresstime=0; //地址高低位发送判断
char total=0; //需要发送接收的数据数量
char total1=0; //第一次需要发送的数据数量
char total2=0; //第二次需要发送的数据数量
char mt=1; //master 发送接收切换标志
/******************************函数声明区**************************************/
void twi_isr(void); //判断TWI状态子程序
void I2cinit(void); //初始化I2C
void Send_i2c_data(void); //I2C发送函数
void Read_i2c_data(void); //I2C读取函数
void I2CReset(void); //I2C复位函数
void i2cdelay(char x); //延时间函数
void i2control(char i2cicnumber,unsigned int i2caddress,char i2ctotal);//变量赋值
/****************************I2c事件中断***************************************/
/*为进入主机模式,必须发送START信号。紧接着的地址包格式决定进入MT或MR模式
如果发送 SLA+W 进入MT 模式;如果发送SLA+R 则进入MR 模式。
在MT模式下再次发送START信号,再发送SLA+R可以进入MR模式 */
#pragma interrupt_handler twi_isr:18
void twi_isr(void) //判断TWI状态子程序
{
if((TWSR&0xf8)==0x08) //读取TWI状态:START已发送
{
TWDR=(0b10100000+icnumber);//主机选择发送器件号码
TWCR=0X85;//启动发送(TWINT置位,TWI使能标志TWEN置位,中断允许TWIE置位)
}
else if((TWSR&0XF8)==0x10)//重复START信号发送,转换为主机接收模式
{
TWDR=(0b10100001+icnumber); //主机向器件指定器件接收数据;
TWCR=0X85;//启动发送(TWINT置位,TWI使能标志TWEN置位,中断允许TWIE置位)
}
else if((TWSR&0XF8)==0x18)//读取TWI状态:SLA+W 已发送;且接收到ACK
{
newpoint=0; //复位发送个数变量
Error_flag=0; //错误标志清0
TWDR=(address>>8); //发送起始地址高8位
addresstime=1; //起始地址高8位已经发送,标志位置1
TWCR=0X85;//启动发送(TWINT置位,TWI使能标志TWEN置位,中断允许TWIE置位)
}
else if(((TWSR&0XF8)==0x28)&&(addresstime==1))//接收到ACK,发送低8位地址
{
TWDR=address; //发送起始地址低8位
addresstime=0; //起始地址低8位已经发送,标志位清0
TWCR=0X85;//启动发送(TWINT置位,TWI使能标志TWEN置位,中断允许TWIE置位)
}
else if(((TWSR&0XF8)==0x28)&&(addresstime==0))//读取TWI状态:页地址已发送;接收到ACK;
{
if(mt==1) //主机发送模式
{
SendI2c_data=Send_buffer[Load_point];//载入数据
TWDR=SendI2c_data; //发送数据
if(newpoint<total) //判断是否已经发送了total个数据
{
newpoint++; //发送个数变量自加1
Load_point++; //储存空间位置自加1
TWCR=0X85; //启动发送(TWINT置位,TWI使能标志TWEN置位,中断允许TWIE置位)
}
else
{
Error_flag=0x28; //发送结束标识
TWCR=0X95;//启动停止位发送(TWINT置1,TWSTO置1,TWI使能标志TWEN置1,中断允许TWIE置1)
}
}
else if(mt==0) //准备转换成主机接收模式:发送重复START信号
{
TWCR=0XA5;//重复START信号发送(TWINT置位,START信号发送,TWI使能标志TWEN置位,中断允许TWIE置位)
}
}
else if((TWSR&0XF8)==0x38)//SLA+W 或数据的仲裁失败;释放总线
{
TWCR=0XA5;//TWINT置位,START信号发送,TWI使能标志TWEN置位,中断允许TWIE置位
}
else if((TWSR&0XF8)==0x40)//进入主机接收模式,清除start标志
{
Get_point=0; //储存缓冲区指针归0
TWCR=0xc5;//进行应答(TWINT置1,应答允许,TWI使能标志TWEN置位,中断允许TWIE置位)
}
else if((TWSR&0XF8)==0x50)//主机接收模式接收数据
{
Error_flag=0x00;
ReceiveI2c_data=TWDR; //赋值接收到的I2c数据
Receive_buffer[Get_point]=ReceiveI2c_data;//将收到的数据存入接收缓存区
Get_point++; //储存空间位置自加1
if(Get_point<total) //判断是否已经接收了total个数据
{TWCR=0xc5;}//进行应答(TWINT置位,TWI使能应答,TWI使能标志TWEN置位,中断允许TWIE置位)
else //已经接收了total个数据
{
Get_point=0; //储存缓冲区指针归0
Error_flag=0x50;
TWCR=0x00;//启动停止位发送(TWINT置0,TWSTO置0,TWI使能标志TWEN置0,中断允许TWIE置0)
}
}
else //错误处理。重新启动
{
Error_flag=0; //置位错误标志
TWCR=0x00; //清0
}
}
/*********************************初始化I2C************************************/
void I2cinit(void)
{
TWCR=0x00;
TWBR=0x02; //设置BIT率400k (单片机晶振为8M)
TWSR=0x00; //设置分频1
TWAR=0x01; //允许识别TWI 总线广播(高7位为从机地址)
TWCR=0x45; //TWI使能应答,TWI使能标志TWEN置位,中断允许TWIE置位
}
/*****************************I2C变量赋值函数**********************************/
void i2control(char i2cicnumber,unsigned int i2caddress,char i2ctotal)
{
icnumber=i2cicnumber;
address=i2caddress;
total=i2ctotal;
laddress=((address<<8)>>8); //将低8位地址赋给laddress
}
/*******************************I2C发送函数************************************/
void Send_i2c_data(void) //I2C发送函数1
{
SEI(); //允许中断
I2CReset(); //i2c复位
Error_flag=0x00;
Load_point=0; //复位缓存地址
mt=1; //打开MCU发送标志
icnumber--; //IC器件地址校正
icnumber<<=1; //IC器件地址校正
if((laddress+total)>256) //如果发送地址超过了256,则分2次发送
{
total2=(laddress+total)-256;//计算第二次发送的数据个数
total1=total-total2; //计算第一次发送的数据个数
total=total1; //准备第一次发送个数
TWCR=0XA5;//开始发送(TWINT置位,start发送,TWI使能标志TWEN置位,中断允许TWIE置位)
while(Error_flag!=0x28) //等待发送完成
{;}
i2cdelay(30); //200us X 30
address+=total1; //第二次发送首地址更新
total=total2; //准备第二次发送个数
TWCR=0XA5;//开始发送(TWINT置位,start发送,TWI使能标志TWEN置位,中断允许TWIE置位)
while(Error_flag!=0x28) //等待发送完成
{;}
i2cdelay(30); //200us X 30
}
else //如果发送地址没有超过256,则按照常规发送
{
TWCR=0XA5;//开始发送(TWINT置位,start发送,TWI使能标志TWEN置位,中断允许TWIE置位)
while(Error_flag!=0x28) //等待发送完成
{;}
i2cdelay(30); //200us X 30
}
}
/*************************读取接收到的I2C数据**********************************/
void Read_i2c_data(void)
{
SEI(); //允许中断
I2CReset(); //i2c复位
Error_flag=0x00;
mt=0; //打开MCU接收标志
icnumber--; //IC器件地址校正
icnumber<<=1; //IC器件地址校正
TWCR=0XA5;//开始发送(TWINT置位,start发送,TWI使能标志TWEN置位,中断允许TWIE置位)
while(Error_flag!=0x50) //等待接收完成
{;}
i2cdelay(30);
}
/*************************I2C软件延时函数**************************************/
void i2cdelay(char x) //200us延时
{
char i=0,j=0;
for(i=0;i<x;i++)
{
for(j=0;j<200;j++)
{;}
}
}
/******************************I2C复位函数*************************************/
void I2CReset(void)
{
TWCR=0x45; //TWI使能应答,TWI使能标志TWEN置位,中断允许TWIE置位
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -