嗨,我在i2c设备上遇到了一个非常奇怪的错误。我使用eeprom AT24C02和实时计数器DS3231。因为它们具有相同的i2c配置(地址模式、字地址大小),所以我不必为ds3231开发库。我正试图从AT24C02和DS3231中读取7个字节。在i2c eeprom示例(非BLE)中,我可以成功读取。但是在ble\u sleepmode的例子中,在回调函数user\u app\u init()中,我放了一些代码行从AT24C02和DS3231读取7个字节。我可以从AT24C02(地址0x50)读取7个字节。当我将地址更改为DS3231地址(0x68)-->debug-->Run时,ide跳转到文件nmi\u handler.c并卡在第63行。我在PDF文件中有一些捕获。
62 if((GetWord16(SYS\u STAT\u REG)&DBG\u IS\u UP)==DBG\u IS\u UP)
63#asm(“BKPT#0\n”);
64其他
{
我已经花了两天时间,但我找不出原因。请帮帮我!
我盼望不久能收到你的来信。
谢谢!
设备:
你好,Thanhtu131,
我建议你先检查一下教程8:调试方法以便开始调试应用程序代码。你能找出触发NMI的代码的意义吗?
所以,如果我理解正确的话,它在不可行的项目上起作用,但在不可行的项目上不起作用。
您是否使用任何可用的睡眠模式?
谢谢,下午好
嗨,你理解错了。我可以正常读取eeprom在可编程和不可编程的例子。但我只能从ds3231中读取时间。在BLE休眠模式示例中,如果我将地址从0x50(eeprom)更改为0x68(ds3231),则会触发NMI。默认的睡眠模式是深度睡眠模式。事情变得更加神秘:我做了一个适配器板,RST按钮连接到DA14580基本套件上的RST引脚,如果我按下RST按钮,我可以运行代码并读取ds3231的数据,我每次调试程序时都必须这样做。
你好,Thanhtu131,
>>>如果我把地址从0x50(eeprom)改为0x68(ds3231),就会有什么东西触发NMI。
你必须开始调试你的项目。这就是为什么我之前的答案是遵循建议的教程。
请在调试模式下运行它,在read函数中添加一个断点并单步执行代码,这样您就可以找到错误所在。
谢谢,下午好
嗨,我已经按照建议的教程。而硬故障发生在DA14580的i2c\ U eepeom库驱动线路上。此外,当硬故障发生时,没有记录任何东西。如果我找到的代码行触发了NMI,那么序列监视器中一定有日志。我找不到放断点的地方。请检查附件PDF文件。
你好,Thanhtu131,
您能指出触发NMI的SDK函数是什么吗?
谢谢,下午好
正如您在i2c bug pdf文件中所看到的,触发NMI的SDK函数是WAIT \u UNTIL \u NO \u MASTER \u ACTIVEITY()(这是一个检查involve寄存器的宏)。我想知道为什么如果我按下重置按钮(我做了一个适配器板,其中有一个按钮连接到DA14580工具包中的RST引脚头),我可以运行和调试程序
你好,Thanhtu131,
在两个I2C API中调用WAIT \u UNTIL \u NO \u MASTER \u ACTIVITY(),并让应用程序等待,直到MASTER不再有活动。
从所附文件中,我假设引起NMI的WAIT \u UNTIL \u NO \u MASTER \u ACTIVITY()由i2c \u WAIT \u UNTIL \u eeprom \u ready()调用。
函数的作用是:在i2c就绪之前进行轮询。首先,此函数发送一个伪值,并等待Tx的FIFO为空。我强烈建议您探测您的PIN(SCL、SDA和RDY),并尝试读取地址。如果你试试看,我想问题会更清楚。
您可以省略的是i2c\u wait\u until\u eeprom\u ready(),因为这是为了向i2c设备发送一个额外的字节,以便检查您的设备是否准备好进行交互,但是除了i2c\u eeprom\u read\u byte()函数之外,您可以在总线上获得i2c设备的数据表所描述的内容。
谢谢,下午好
您好,非常感谢您的支持,我已经证实问题来自DS3231 PCB。更换另一个ds3231模块后,操作正常。
你好,Thanhtu131,
很高兴你发现了!
谢谢,下午好