ercircle 发表于 2025-6-8 20:00:45

大明狐 发表于 2025-6-8 19:54
关了中断会影响其它功能,那就只能放弃普通显示的那些函数和DMA中断混用了,都改成全刷和局刷的缓存方式显 ...一样的都是开关中断的,实验箱66例程只开关I2C主机中断:





大明狐 发表于 2025-6-9 08:58:15

ercircle 发表于 2025-6-8 20:00
一样的都是开关中断的,实验箱66例程只开关I2C主机中断:
豁然开朗!
把暂停总中断,替换成暂停DMA发送数据的中断,的确也成功显示了!
{:4_189:}
红色是直接操作寄存器的方式关闭和开启DMA主机模式中断,
蓝色是AiCube命令的方式



784



大明狐 发表于 2025-6-9 12:59:34

在ercircle老师提示下,解决了在AiCube框架中用I2C_DMA点亮OLED的问题,然后好奇对不正常的代码做了下比较:


下图是 实验箱例程里的 和 AiCube生成的 I2C_DMA 的初始化配置的代码。
使用前者可以正常显示,使用后者则会卡死。


然后把实验箱版的配置代码通过对照寄存器和赋值,按照AiCube的命令逐一进行替换。
下图是替换结果


最后将替换完的正常运行的代码(左),跟AiCube生成的代码(右)逐一作了下对比


对比结果是大部分都能一一对应,只有三处不一样的地方。
1、AiCube里的收发间隔在实验箱里没有;
2、实验箱的 DMA_I2CT_STA = 0x00; 对应的 DMA_I2C_ClearTxFlag(); 和 DMA_I2C_ClearOverWriteFlag(); 这两条命令,在AiCube里没有;
3、AiCube里的使能I2C_DMA,在实验箱里没有。
其中:
第一处,有和没有在这个程序里效果一样;
第二处,缺少这两个命令,显示部分内容之后就会卡死;
多了第三处的话,上电后直接卡死。


所以1楼提到的硬件I2C_DMA驱动移植进AiCube会卡死问题,大概就是目前版本AiCube生成的DMA初始化代码的原因。


=====================================================
另外在这里留个笔记

1、如果每次发送的数据长度不固定,
DMA_I2C_SetTxAmount( number );                                       
DMA_I2C_SetDMAAmount( number );
这两条命令可以不放在DMA初始化里,可以放在发送函数里每次指定长度。

2、在做上面对比的时候,好奇在初始化和发送函数里都不用
DMA_I2C_SetTxAddress( I2CDmaTxBuffer );      
这条命令,结果发现依旧可以正常显示。
读取了一下I2CDmaTxBuffer数组的内存地址,结果是0x10000(65536),恰好是xdata区的首地址。
可见DMA_I2C_SetTxAddress默认值是xdata的首地址。
然后尝试指定了一下I2CDmaTxBuffer数组的内存地址
u8 xdata I2CDmaTxBuffer _at_ 0x7800;
再次编译果然就显示不正常了,显示出来的是这个地址之前的混乱的图片内容,
恢复DMA_I2C_SetTxAddress命令就显示正常了。
所以这条命令不能省。

附上代码:





页: 1 [2]
查看完整版本: (问题总结在13楼)关于用AiCube配置I2C_DMA的遇到的问题