📄 24c16.c
字号:
#include <main.h>
#include <REG52.H>
//通道0 温度 TEMPERATURE
//记录存储标志存储在第0页第一个字节 无记录时为0xAA 有记录时为0x55
//数据存储在第0页 低位第二字节为温度下限 高位第三字节为温度上限
//通道1 压力 PREASURE
//记录存储标志存储在第1页 第一个字节 无记录时为0xAA 有记录时为0x55
//数据存储在第1页 低位第二字节为压力下限 高位第三字节为压力上限
//通道2 流量 FLUX
//记录存储标志存储在第2页 第一个字节 无记录时为0xAA 有记录时为0x55
//数据存储在第2页 低位第二字节为流量下限 高位第三字节为流量上限
//8页×256字节=16k bit
#define WRITE 0xA0 //定义24c16的器件地址和方向位W
#define READ 0xA1 //定义24c16的器件地址和方向位R
//单片机与AT24c16之间的引脚定义
sbit WP=P2^1;
sbit SCL=P2^2;
sbit SDA=P2^3;
//延时子程序 延时14us
void d14us()
{
uchar i;
for(i=0;i<5;i++);
}
//开始位
void start_bit(void)
{
SCL=1;d14us();
SDA=1;d14us();
SDA=0;d14us();
SCL=0;d14us();
}
//停止位
void stop_bit(void)
{
SDA=0;d14us();
SCL=1;d14us();
SDA=1;d14us();
}
//主答函数 在接收数据时用
void mast_ack(void)
{
SCL=0;d14us();
SDA=0;d14us();
SCL=1;d14us();
SCL=0;d14us();
SDA=1;d14us();
}
//从应答函数 在发送数据时用
void ack(void)
{
SDA=1; //输出口置1 等待SDA上 24c16发出的应答信号
SCL=0;d14us();
SCL=1;d14us();
while(SDA){;}
SCL=0;d14us();
}
//无需应答位,在读程序中用到 (最后一个数据时)
//主器件(即cpu)在接收到最后一个字节后不发应答信号
void no_ack(void)
{
SDA=1;d14us();
SCL=1;d14us();
SCL=0;d14us();
}
//写一个字节(8位)数据 把一次写拆分成多次8位数据发送
write_8bit(uchar ch)
{
uchar i=8;
SCL=0;d14us();
while(i--)
{
SDA=(bit)(ch&0x01);d14us(); //强制类型转换
ch<<=1;
SCL=1;d14us();
SCL=0;d14us();
}
}
//读24c16指定地址数据(任意地址的字节读)
//参数:address 长整型 11位二进制
#pragma disable //避免与串口通讯等中断冲突
uchar read24c16(uint address) //长整型 11位二进制
{
uchar data rdata; //读数据存储单元
uchar data SlvAdrHigh,SlvAdrLow; //地址的高八位 低八位单元
uchar i=8;
SlvAdrHigh=((address&0x0700)>>7)|WRITE;
SlvAdrLow=(address&0xFF);
start_bit();
write_8bit(SlvAdrHigh);
ack();
write_8bit(SlvAdrLow);
ack();//伪写
start_bit();
write_8bit(SlvAdrHigh|0x01);
ack();
while(i--)
{
rdata<<=1;
SCL=0;d14us(); SCL=1;
if(SDA) rdata|=0x01;
}
no_ack();
stop_bit();
return rdata;
}
//写数据到24c16的指定地址(字节写)
//源数据:ddata 目的地址: address
#pragma disable //避免与串口通讯等中断冲突
void write24c16(uint address,uchar ddata)
{
uchar data SlvAdrHigh,SlvAdrLow; //地址的高八位 低八位单元
SlvAdrHigh=((address&0x0700)>>7)|WRITE;
SlvAdrLow=(address&0xFF);
start_bit();
write_8bit(SlvAdrHigh);
ack();
write_8bit(SlvAdrLow);
ack();
write_8bit(ddata);
ack();
stop_bit();
}
//页面写函数,firstw_ad为需写入数据存储单元的首地址(11位),
// firstr_ad为被写入数据所在首地址
// counter为写入数据字节数 <=16个字节
void page_wr(uint firstw_ad,uint counter,uchar firstr_ad)
{
uchar data *ufirstr_ad;
uchar data SlvAdrHigh,SlvAdrLow; //地址的高八位 低八位单元
SlvAdrHigh=((firstw_ad&0x0700)>>7)|WRITE;
SlvAdrLow=(firstw_ad&0xFF);
ufirstr_ad=firstr_ad; //把cpu中地址赋给指针
start_bit();
write_8bit(SlvAdrHigh); //1010 0010
ack();
write_8bit(SlvAdrLow);
ack();
while(counter--)
{
write_8bit(*ufirstr_ad);
ufirstr_ad++;
ack();
}
stop_bit();
}
//页面读函数,firstrd_ad为所读字节首地址,count为读字节数
// *ufirstwr_ad为读出数据存储首地址指针 firstwr_ad为被读出数据单元所在首地址
void page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad)
{
uchar j=8;
uchar data *ufirstwr_ad;
uchar data SlvAdrHigh,SlvAdrLow; //地址的高八位 低八位单元
SlvAdrHigh=((firstrd_ad&0x0700)>>7)|WRITE;
SlvAdrLow=(firstrd_ad&0xFF);
ufirstwr_ad=firstwr_ad;
start_bit();
write_8bit(SlvAdrHigh);
ack();
write_8bit(SlvAdrLow);
ack();
start_bit();
write_8bit(SlvAdrHigh|0x01);
ack();
while(count--)
{
uchar i=8;
while(i--)
{
(*ufirstwr_ad)<<=1;
SCL=0;d14us();d14us();SCL=1;
if(SDA) (*ufirstwr_ad)|=0x01;
}
ufirstwr_ad++;
mast_ack();
}
while(j--) //不需要应答的最后一位数据
{
(*ufirstwr_ad)<<=1;
SCL=0;d14us();d14us();SCL=1;
if(SDA) (*ufirstwr_ad)|=0x01;
}
no_ack();
stop_bit();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -