完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
你好, 测试I2C程序出现,24C02可以正常读写,但24C64却不可以。阅读代码,咨询一下问题, rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus, |
|
相关推荐
3个回答
|
|
24C64是16位寻址,读写有稍稍区别
|
|
|
|
尝试修改了
msh /> msh />at24cxx_eeprom_sample EEPROM write data is: a,b,c,d,e,f,g,h EEPROM read data is: 代码如下,不知哪里出了问题。 /* at24cxx设备结构体 / struct at24cxx_device { struct rt_device parent; struct rt_i2c_bus_device *bus; }; /* at24cxx设备用户操作配置结构体 / struct at24cxx_config { rt_uint32_t size; //设备的总容量 rt_uint16_t addr; //设备地址 rt_uint16_t flags; //I2C操作标志 }; static rt_size_t at24cxx_read(rt_device_t dev, rt_off_t pos, void buffer, rt_size_t size) { struct at24cxx_device at24cxx; const struct at24cxx_config *cfg; struct rt_i2c_msg msg[2]; rt_uint8_t mem_addr[2] = {0,}; rt_size_t ret = 0; RT_ASSERT(dev != 0); at24cxx = (struct at24cxx_device *) dev; RT_ASSERT(at24cxx->parent.user_data != 0); cfg = (const struct at24cxx_config *) at24cxx->parent.user_data; if(pos >= cfg->size) //寻址地址超标 { return 0; } if(pos + size > cfg->size) // size超标 { size = cfg->size - pos; } msg[0].addr = cfg->addr; msg[0].flags = cfg->flags | RT_I2C_WR; if(cfg->size < 257) // at24c01 at24c02, 一页8字节,寻址地址8位 { mem_addr[0] = (rt_uint8_t) pos; msg[0].buf = (rt_uint8_t *) mem_addr; msg[0].len = 1; } else // at24c04/08/16 一页16字节,寻址地址9/10/11位 { mem_addr[0] = (pos >> 8); mem_addr[1] = (rt_uint8_t) pos; msg[0].buf = (rt_uint8_t *) mem_addr; msg[0].len = 2; } msg[1].addr = cfg->addr; msg[1].flags = cfg->flags | RT_I2C_RD; msg[1].buf = (rt_uint8_t *) buffer; msg[1].len = size; ret = rt_i2c_transfer(at24cxx->bus, msg, 2); return (ret == 2) ? size : 0; } static rt_size_t at24cxx_write(rt_device_t dev, rt_off_t pos, const void buffer, rt_size_t size) { struct at24cxx_device at24cxx; const struct at24cxx_config *cfg; struct rt_i2c_msg msg[2]; rt_uint8_t mem_addr[2] = {0,}; rt_size_t ret = 0; RT_ASSERT(dev != 0); at24cxx = (struct at24cxx_device *) dev; RT_ASSERT(at24cxx->parent.user_data != 0); cfg = (const struct at24cxx_config *) at24cxx->parent.user_data; if(pos > cfg->size) { return 0; } if(pos + size > cfg->size) { size = cfg->size - pos; } // 写入寻址地址 msg[0].addr = cfg->addr; msg[0].flags = cfg->flags | RT_I2C_WR; if(cfg->size < 257) // at24c01 at24c02, 一页8字节,寻址地址8位 { mem_addr[0] = (rt_uint8_t) pos; msg[0].buf = (rt_uint8_t *) mem_addr; msg[0].len = 1; } else // at24c04/08/16 一页16字节,寻址地址9/10/11位 { mem_addr[0] = (pos >> 8); mem_addr[1] = (rt_uint8_t) pos; msg[0].buf = (rt_uint8_t *) mem_addr; msg[0].len = 2; } // 使用RT_I2C_NO_START,直接写入buffer数据 msg[1].addr = cfg->addr; msg[1].flags = cfg->flags | RT_I2C_WR | RT_I2C_NO_START; msg[1].buf = (rt_uint8_t *) buffer; msg[1].len = size; ret = rt_i2c_transfer(at24cxx->bus, msg, 2); return (ret == 2) ? size : 0; } / RT-Thread device interface / static rt_err_t at24cxx_init(rt_device_t dev) { return RT_EOK; } static rt_err_t at24cxx_open(rt_device_t dev, rt_uint16_t oflag) { return RT_EOK; } static rt_err_t at24cxx_close(rt_device_t dev) { return RT_EOK; } static rt_err_t at24cxx_control(rt_device_t dev, int cmd, void *args) { return RT_EOK; } ifdef RT_USING_DEVICE_OPS /* at24cxx设备操作ops / const static struct rt_device_ops at24cxx_ops = { at24cxx_init, at24cxx_open, at24cxx_close, at24cxx_read, at24cxx_write, at24cxx_control }; endif /** @Brief at24cxx设备注册 @param[in] *fm_device_name 设备名称 @param[in] *i2c_bus i2c总线设备名称 @param[in] *user_data 用户数据 at24cxx_config @Return 函数执行结果 RT_EOK 执行成功 Others 失败 / rt_err_t at24cxx_register(const char fm_device_name, const char i2c_bus, void user_data) { static struct at24cxx_device at24cxx_drv; struct rt_i2c_bus_device *bus; bus = rt_i2c_bus_device_find(i2c_bus); if (bus == RT_NULL) { return RT_ENOSYS; } at24cxx_drv.bus = bus; at24cxx_drv.parent.type = RT_Device_Class_Block; ifdef RT_USING_DEVICE_OPS at24cxx_drv.parent.ops = &at24cxx_ops; else at24cxx_drv.parent.init = at24cxx_init; at24cxx_drv.parent.open = at24cxx_open; at24cxx_drv.parent.close = at24cxx_close; at24cxx_drv.parent.read = at24cxx_read; at24cxx_drv.parent.write = at24cxx_write; at24cxx_drv.parent.control = at24cxx_control; endif at24cxx_drv.parent.user_data = user_data; return rt_device_register(&at24cxx_drv.parent, fm_device_name, RT_DEVICE_FLAG_RDWR); } static struct at24cxx_config at24c64_config = { .size = 8192, // 容量,单位字节 .addr = 0x50, // 注意该地址为没有移位之前的地址不是0xA0 .flags = 0, }; static int at24cxx_eeprom_sample(void) { rt_err_t ret; rt_uint8_t read_buf[8]={0}; rt_uint8_t write_buf[8] = {‘a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’}; ret = at24cxx_register("at24c64", "i2c1", &at24c64_config); //寻找设备 rt_device_t at24c64_dev = rt_device_find("at24c64"); if (at24c64_dev == RT_NULL) { rt_kprintf("at24c64 sample run failed! can't find %s device!\n", "at24c64"); } rt_device_open(at24c64_dev, RT_DEVICE_FLAG_RDWR); if(4 == rt_device_write(at24c64_dev, 0, write_buf, 4)) { rt_kprintf("EEPROM write data is: %c,%c,%c,%c,%c,%c,%c,%c \r\n",write_buf[0],write_buf[1],write_buf[2],write_buf[3],write_buf[4],write_buf[5],write_buf[6],write_buf[7]); } else { rt_kprintf("EEPROM write data faild! \n"); } if(4 == rt_device_read(at24c64_dev, 0, read_buf, 4))//0x08地址读数据 { rt_kprintf("EEPROM read data is: %c,%c,%c,%c,%c,%c,%c,%c \r\n",read_buf[0],read_buf[1],read_buf[2],read_buf[3],read_buf[4],read_buf[5],read_buf[6],read_buf[7]); } else { rt_kprintf("EEPROM read data faild! \n"); } return 0; } |
|
|
|
一、既然一个可以,一个不行,那就找差别;
1.地址不一致;需要修改地址的相关函数; 2.既然不一样,对应的存储方式是否也不一致;也就是查询、确定地址的方式是否也不一致; 二、建议查询一下对应存储芯片的相关数据手册; |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
498 浏览 0 评论
1405 浏览 0 评论
如何使用python调起UDE STK5.2进行下载自动化下载呢?
2111 浏览 0 评论
开启全新AI时代 智能嵌入式系统快速发展——“第六届国产嵌入式操作系统技术与产业发展论坛”圆满结束
2636 浏览 0 评论
获奖公布!2024 RT-Thread全球巡回线下培训火热来袭!报名提问有奖!
28720 浏览 11 评论
72063 浏览 21 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-7 23:23 , Processed in 0.920362 second(s), Total 74, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号