#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint;
typedef unsigned char uchar;
#define READ_CMD 1
#define WRITE_CMD 0
#define x24C16 //器件名称,x24C04、x24C08或x24C16
#define DEV_ADDR 0xA0 //设备硬件地址
#ifdef x24C04
#define PAGE_NUM 32 //页数
#define PAGE_SIZE 16 //页面大小(字节)
#define CAPACITY_SIZE (PAGE_NUM * PAGE_SIZE) //总容量(字节)
#define ADDR_BYTE_NUM 1 //地址字节个数
#endif
#ifdef x24C08
#define PAGE_NUM 64 //页数
#define PAGE_SIZE 16 //页面大小(字节)
#define CAPACITY_SIZE (PAGE_NUM * PAGE_SIZE) //总容量(字节)
#define ADDR_BYTE_NUM 1 //地址字节个数
#endif
#ifdef x24C16
#define PAGE_NUM 128 //页数
#define PAGE_SIZE 16 //页面大小(字节)
#define CAPACITY_SIZE (PAGE_NUM * PAGE_SIZE) //总容量(字节)
#define ADDR_BYTE_NUM 1 //地址字节个数
#endif
#define ADDR(u16Addr) (((uint8_t)((u16Addr >> 8) & 0x07)) << 1)
#define LEN 18
uchar code table[] = "write:";
uchar code table2[] = "read:";
sbit sda = P2^0;
sbit scl = P2^1;
sbit lcden = P3^4;
sbit lcdrs = P3^5;
uchar num;
void delay(){;;}
void delayms(uint xms){
uint i, j;
for(i = xms; i > 0; i--)
for(j = 110; j > 0; j--);
}
/*
在利于I2C总线进行一次数据传输时,首先由主机发出启动信号,启动I2C总线。
在SCL为高电平期间,SDA出现下降沿则为启动信号,此时,具有I2C总线接口的从器件会检测到该信号
*/
void start(){ //开始信号
sda = 1; //SDA初始化为高电平“1”
scl = 1; //SCL为高电平“1”
delayms(5);
sda = 0; //SDA的下降沿被认为是开始信号
delayms(5);
scl = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
delayms(5);
}
/*
SCL在高电平期间,SDA一个上升沿停止信号
*/
void stop(){
sda = 0; //SDA初始化为低电平“0”
delayms(5);
scl = 1;
delayms(5);
sda = 1; //SDA的上升沿被认为是结束信号
}
/*
SCL在高电平期间,SDA被从设备拉为低电平表示应答
*/
void host_wait_ask(){
uchar i;
scl = 1;
delay();
while(sda == 1 && i < 250)i++;
scl = 0;
delay();
}
/*
将总线拉高以释放总线
总线上各器件都采用漏极开路结构与总线相连,因此SCL和SDA均需接上拉电阻,
总线在空闲状态下均保持高电平,连到总线上的任一器件输出低电平,都将使总线信号变低
*/
void init(){
sda = 1;
delay();
scl = 1;
delay();
}
/*
发送到SDA线上的每个字节必须为8位,每次传输可以发送的字节数量不受限制。每个字节后必须跟一个响应位。首先传输的是数据的最高位(MSB)
发送一个字节:
SCL低电平期间,主机将数据位依次放到SDA线上(高位在前),然后拉高SCL,从机将在SCL高电平期间读取数据位,
所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节。
接收应答:
在发送完一个字节之后,主机在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答。
串行发送一个字节时,需要把这个字节中的8位一位一位地发出去,"temp=temp<<1;"
表示将temp左移一位,最高位将移入PSW寄存器的CY位中,然后将CY赋给SDA进而在SCL的控制下发送出去
*/
void write_byte(uchar date){
uchar i, temp;
temp = date;
/* 先发送字节的高位bit7 */
/*
for (i = 0; i < 8; i++){
if (temp & 0x80){
sda = 1;
}else{
sda = 0;
}
delay();
scl = 1;
delay();
scl = 0;
temp <<= 1; // 左移一个bit
delay();
}
*/
for(i = 0; i < 8; i++){
temp = temp << 1;
scl = 0;
delay();
sda = CY;
//sda = temp & (0x80 >> i);
delay();
scl = 1;
delay();
}
/* 如果从机要完成一些其他功能后(例如一个内部中断服务程序)才能接收或发送下一个完整的数据字节,可以使时钟线SCL保持低电平,
迫使主机进入等待状态,当从机准备好接收下一个数据字节并释放时钟线SCL后数据传输继续。 */
scl = 0;
delay();
sda = 1; //按照协议规定从设备需要发送ACK给主设备,所以此时主设备必须释放总线(也就是主设备把SDA总线置为高电平然后不要动)
delay();
}
/*
串行接收一个字节时需要将8位一位一位地接收,然后在组合成一个字节,下面代码中
我们定义一个临时变量k,将k左移一位后与SDA进行“或”运算,依次把8个独立的位放入一个字节中来完成接收
*/
uchar read_byte(){
uchar i, k = 0;
scl = 0;
delay();
sda = 1;
delay();
for(i = 0; i < 8; i++){
scl = 1; //SCL置为高电平
delayms(6);
k = (k<<1)|sda;
scl = 0;
delayms(6);
}
return k;
}
//I2C开始——先发送器件写地址——等待应答——发送页地址——等待应答——开始写入数据——结束I2C
void write_addr(uint16_t address, uchar date){
//1 主机发送启动信号
start();
/*
2 寻址信号 0xa0:1010 0000
24C02C的芯片地址1010,其地址控制格式:1010A2A1A0R/W
其中A2,A1,A0为可编程地址选择位。A2,A1,A0引脚接高、低电平后得到确定的三位编码(默认为接地。A2A1A0=000),
与1010形成7位编码,即为该器件的地址码,R/W为芯片读写控制位,为0,表示对芯片进行写操作
为1,表示对芯片进行读操作
*/
write_byte(DEV_ADDR | WRITE_CMD | ADDR(address));//器件寻址+写+页选择位
host_wait_ask();
write_byte(address & 0xFF);//只取地址的低字节,高字节如果有,已经按照页选择位处理过了
host_wait_ask();
write_byte(date);
host_wait_ask();
stop();
}
void page_write(uint16_t u16Addr, uint8_t *pData, uint8_t count)
{
uint8_t slaveAddr = 0, newAddr;
slaveAddr = DEV_ADDR | WRITE_CMD | ADDR(u16Addr);////器件寻址+写+页选择位
newAddr = u16Addr & 0xff;////只取地址的低字节,高字节如果有,已经按照页选择位处理过了
start();
write_byte(slaveAddr);
host_wait_ask();
write_byte(newAddr);
host_wait_ask();
while(count--)
{
write_byte(*pData);
delayms(6);
pData++;
host_wait_ask();
}
stop();
}
//首先检查写入总数据字节数是否大于一页
void at24xxWrite(uint16_t addr, const char* pBuff, uint16_t size)
{
uchar writeLen, pageOffset;
while(size > 0){
// AT24C16有128(2^7=128)页,需要7位地址,分为高3位和低4位, 页低4位和页内偏移地址(4位),组成word address 8位
// 如读写地址:1864 ,1864/16=116(0x74)页,1864%16=8(0x08),即116页的第8个字节
// 0x74=0 1 1 1 0 1 0 0, 最高位忽略,分为D6、D5、D4(高3位)和D3~D0(低4位)两个部分
// 设备地址:1010 111 0/1, word address: 0100 1000(页低4位 和 页内偏移地址(4位))
// addr & (PAGE_SIZE - 1) 取出低4位 页内偏移地址
pageOffset = PAGE_SIZE - (addr & (PAGE_SIZE - 1));
writeLen = size > pageOffset ? pageOffset : size;
page_write(addr, pBuff, writeLen);
size = size - writeLen;
if(size > 0){
pBuff = pBuff + writeLen;
addr = addr + writeLen;
}
}
}
void testPage(){
uchar pDataWrite[LEN];//用于写入的数组
for(num = 0; num < LEN; num++){
pDataWrite[num] = num+1;
}
at24xxWrite(0x64, pDataWrite, LEN);//从地址 开始写入多个数据
//delayms(6);//这里因为需要立即读取,所以需要添加6ms的延时用于等待数据搬运
}
int main(){
init();
testPage();
while(1){}
}
没有合适的资源?快使用搜索试试~ 我知道了~
proteus I2C Debugger AT24C16 页写多页写仿真
共18个文件
obj:2个
lst:2个
pdsbak:2个
需积分: 0 6 下载量 102 浏览量
2023-05-12
15:39:14
上传
评论
收藏 86KB RAR 举报
温馨提示
proteus I2C Debugger AT24C16 页写多页写 仿真 AT24C16有128(2^7=128)页只需要7位地址,分为高3位和低4位,高3位在设备地址中,低4位在字地址中。 设备地址:1010+页地址高3位+读写方向(1:读 0:写) 字地址:页地址高4位+4位页内偏移地址 例如读写地址:1864 ,首先计算该地址是多少页的多少个字节,1864/16=116(0x74)页,1864%16=8(0x08),即116页的第8个字节
资源推荐
资源详情
资源评论
收起资源包目录
AT24C16.rar (18个子文件)
AT24C16
Backup Of New Project.pdsbak 16KB
New Project.pdsprj.Lenovo-PC5.ttt.workspace 3KB
51
AT89C52.uvproj 14KB
Objects
AT89C52 11KB
AT89C52.lnp 121B
AT89C52.hex 2KB
STARTUP.obj 819B
AT89C52.build_log.htm 1KB
main.obj 12KB
STARTUP.A51 6KB
Listings
AT89C52.m51 14KB
main.lst 13KB
STARTUP.lst 14KB
AT89C52.uvgui.ttt 173KB
AT89C52.uvopt 6KB
main.c 8KB
New Project.pdsprj 16KB
Last Loaded New Project.pdsbak 17KB
共 18 条
- 1
资源评论
a3676212
- 粉丝: 39
- 资源: 17
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 老飞飞搭建基础通用数据库V19数据库.rar
- jquery.js
- 机械设计多工位ACF贴胶带&预压设备sw18可编辑非常好的设计图纸100%好用.zip
- 基于Pytorch复现Point-Transformer,用于ShapeNet数据集点云分割
- 【医学影像分析】2D超声图像的分割检测(Ultrasound Nerve Segmentation - Kaggle数据集)
- 嘎嘎香的五款神仙谷歌插件
- .arch书源导入教程.mp4
- 贪心算法介绍及代码示例讲解
- CR13SP35MSI64 Crystal 水晶报表运行组件最后版本64位
- 图像分类数据集:玉米叶是否感染分类数据集(2分类,包含训练集、验证集)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功