硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1698|回复: 13
收起左侧

[I2C] 求一个i2c模拟从机的例程

[复制链接]

16

主题

62

回帖

110

积分

初级会员

积分
110
发表于 2022-1-15 10:30:51 | 显示全部楼层 |阅读模式
本帖最后由 opsd999 于 2022-1-15 10:33 编辑

求一个i2c模拟从机的例程,最好在RTOS下运行的,不是也可以,项目要求需要stm32模拟eeprom通过SMBus上报的。有大神有这类的可以分享下吗。
回复

使用道具 举报

16

主题

62

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2022-1-15 10:38:34 | 显示全部楼层
类似的就行,学习下思路
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106840
QQ
发表于 2022-1-15 10:40:10 | 显示全部楼层
GitHub检索,很多,看看有没有做的比较好点的。
回复

使用道具 举报

16

主题

62

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2022-1-17 13:26:04 | 显示全部楼层
eric2013 发表于 2022-1-15 10:40
GitHub检索,很多,看看有没有做的比较好点的。

感谢,确实找到了一个还没验证。
还有个问题,这边模拟的是CAT24C08安森美的,我看时序和at24c08一样的,然后准备用模拟io先做一套主机的程序做测试,写命令连读连写都正常,就是在选择性读取的时候出现不对的地方,下图是手册的时序。
微信截图_20220117131109.png
发送完需要读的数据地址之后接ACK应答 然后重发START 开始读命令。
我的程序如下图
微信截图_20220117131818.png
先往0x00写 0x44,0x22,0x33,然后在用选择性读取时序去读 4次。
下图是第一次的波形。
微信截图_20220117131807.png
他第一次读取有问题,第二次才开始读当前地址的值。
硬汉哥有用过这类eeprom吗。能帮忙看下哪个地方有问题吗,如果先发读取的地址然后发送结束时序,过2ms发送,一条拆成两条也是正常的。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106840
QQ
发表于 2022-1-18 10:33:37 | 显示全部楼层
opsd999 发表于 2022-1-17 13:26
感谢,确实找到了一个还没验证。
还有个问题,这边模拟的是CAT24C08安森美的,我看时序和at24c08一样的 ...

你这个是要做页编程? 我一直用的AT系列的EEPROM 正常。
回复

使用道具 举报

16

主题

62

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2022-1-19 09:13:23 | 显示全部楼层
eric2013 发表于 2022-1-18 10:33
你这个是要做页编程? 我一直用的AT系列的EEPROM 正常。

不是页编程,是指定地址读,代码顺序是下面这个。如果把注释释放,就正常,这大概是哪个部分的问题。

        vI2C_Start();
        vI2C_Send_Byte(0xA0);
        if(u8I2C_Wait_Ack())
                while(1);
        vI2C_Send_Byte(writeaddr>>8);
        if(u8I2C_Wait_Ack())
                while(1);
        vI2C_Send_Byte(writeaddr%256);
        if(u8I2C_Wait_Ack())
                while(1);
//        vI2C_Stop();
//        HAL_Delay(2);
        vI2C_Start();
        vI2C_Send_Byte(0xA1);
        if(u8I2C_Wait_Ack())
                while(1);
        data2[0] = u8I2C_Read_Byte(0);
        vI2C_Stop();


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106840
QQ
发表于 2022-1-19 10:36:56 | 显示全部楼层
opsd999 发表于 2022-1-19 09:13
不是页编程,是指定地址读,代码顺序是下面这个。如果把注释释放,就正常,这大概是哪个部分的问题。

...

不知道你用的EEPROM有没有这个问题,写入后,判断是否写入完成。
QQ截图20220119103618.png
回复

使用道具 举报

16

主题

62

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2022-1-19 11:47:13 | 显示全部楼层
eric2013 发表于 2022-1-19 10:36
不知道你用的EEPROM有没有这个问题,写入后,判断是否写入完成。

判断是否写入完成,依据不是ACK应答吗,我前面的代码部分都没进入while(1)循环中,ack应答都正常。vI2C_Start();
/*写命令*/
        vI2C_Send_Byte(0xA0);
/*等待ACK应答*/
        if(u8I2C_Wait_Ack())
                while(1);
/*发送需要读取的内存地址前8位*/
        vI2C_Send_Byte(writeaddr>>8);
/*等待ACK应答*/
        if(u8I2C_Wait_Ack())
                while(1);
/*发送需要读取的内存地址后8位*/
        vI2C_Send_Byte(writeaddr%256);
/*等待ACK应答*/
        if(u8I2C_Wait_Ack())
                while(1);
//        vI2C_Stop();
//        HAL_Delay(2);
        vI2C_Start();
/*读命令*/
        vI2C_Send_Byte(0xA1);
/*等待ACK应答*/
        if(u8I2C_Wait_Ack())
                while(1);
/*接收芯片回复*/
        data2[0] = u8I2C_Read_Byte(0);
        vI2C_Stop();

上述接收到的数据是0x00,而实际内存中并不是,把注释的vI2C_Stop();HAL_Delay(2);放出,接收到的数据就正常了
这个指定地址读 的时序,我看了AT和安森美的CAT一样的,不知道哪里有问题。
回复

使用道具 举报

0

主题

25

回帖

25

积分

新手上路

积分
25
发表于 2022-1-19 12:49:03 | 显示全部楼层
写操作完了主机需要发一个STOP命令,另外从机每一次回复ACK只代表这一次数据或指令响应了。实际上你写一次数据需要等待5ms左右,eeprom内部才能真正写入完成。
回复

使用道具 举报

16

主题

62

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2022-1-19 13:13:20 | 显示全部楼层
zm2622 发表于 2022-1-19 12:49
写操作完了主机需要发一个STOP命令,另外从机每一次回复ACK只代表这一次数据或指令响应了。实际上你写一次 ...

微信截图_20220117131109.png 微信截图_20220119130619.png
1图是CAT24C08的手册,2图是AT24C08的,这个第一次写操作完他就没有STOP命令呀,是我理解有问题吗。
他是先对器件做 写操作 ,发送需要读取的内存地址,然后不产生stop命令,直接继续重新发送start,进行一次读当前内存地址的操作。
回复

使用道具 举报

16

主题

62

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2022-1-19 13:30:31 | 显示全部楼层
zm2622 发表于 2022-1-19 12:49
写操作完了主机需要发一个STOP命令,另外从机每一次回复ACK只代表这一次数据或指令响应了。实际上你写一次 ...

之前一直用的spi flash,eeprom没怎么用过,想问下是单个字节数据写入需要5ms还是单次完整写操作完成后需要等5ms,如果我一次写操作连续写200个数据,是等待5ms还是1s。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106840
QQ
发表于 2022-1-20 09:58:49 | 显示全部楼层
opsd999 发表于 2022-1-19 11:47
判断是否写入完成,依据不是ACK应答吗,我前面的代码部分都没进入while(1)循环中,ack应答都正常。vI2C ...

是ack,关键是ack完毕了,EERPOM内部还没有实际操作完成,所以判断下非常有必要。
回复

使用道具 举报

16

主题

62

回帖

110

积分

初级会员

积分
110
 楼主| 发表于 2022-2-11 15:50:27 | 显示全部楼层
eric2013 发表于 2022-1-20 09:58
是ack,关键是ack完毕了,EERPOM内部还没有实际操作完成,所以判断下非常有必要。

硬汉哥我这边遇到一个问题,前面的模拟eeprom完成了,问题出在 客户保证i2c间隔10ms,而f301数据手册擦除一页flash就需要20-40ms,我实际就保存6个字节的数据,所以大头的时间都是用在擦除上。
但是好像 擦写flash是不是会占用总线?中断都会停止。
如果我i2c命令是写命令,那我就需要20-40ms擦除然后写入,但客户可能10ms之后就发第二条命令了,这时候硬件i2c直接OVR溢出了。
这种 内部flash擦写和i2c等外设中断的冲突 有什么好办法处理吗。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106840
QQ
发表于 2022-2-12 09:49:05 | 显示全部楼层
opsd999 发表于 2022-2-11 15:50
硬汉哥我这边遇到一个问题,前面的模拟eeprom完成了,问题出在 客户保证i2c间隔10ms,而f301数据手册擦除 ...

内部Flash做擦写期间,程序是暂停执行的,包含中断服务程序。

可以尝试DMA方式做定时器I2C。DMA是独立执行的,不受CPU是否运行的影响。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-7 01:46 , Processed in 0.381913 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表