找回密码
 立即注册
查看: 307|回复: 12

(问题总结在13楼)关于用AiCube配置I2C_DMA的遇到的问题

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:433
  • 最近打卡:2025-06-15 14:30:03

28

主题

336

回帖

2888

积分

荣誉版主

积分
2888
发表于 2025-6-4 17:48:09 | 显示全部楼层 |阅读模式
打算使用AiCube重新学习I2C的DMA功能的时候,遇到几个问题。

1、AiCube生成的DMA配置代码里,“发送接收总字节数”和“需要发送的字节数”对不上。

为了验证,在AiCube的I2C配置界面随便填写了DMA的发送和接收的字节数。
标签上是“I2C DMA发送字节数”和“I2C DMA接收字节数”,
而下面的说明栏里写的是“I2C DMA发送总字节数”和“I2C DMA接收总字节数”。
1.1.I2C_8051U_设置发送字节数.jpg 1.2.I2C_8051U_设置接收字节数.jpg


在生成的配置代码里,发送部分的
45行 “设置I2C DMA发送总字节数” 是上面填写的发送总字节数499,

44行 “使能I2C DMA发送/接收总字节数” 却是上面填写的接收总字节数199。

接收部分的54、55两行都是上面填写的199。

注释里都是“总字节数”,看着很迷糊。
试验箱例程包里的注释是“发送接收总字节数”、“需要发送的字节数”,更一目了然。
另外数据手册里对这三组寄存器的描述是“需要进行读写的字节数”、“需要传输的字节数”,看着也有些懵。

2.I2C_8051U_代码.jpg


、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

2、发送数据程序卡死

用带AiCube生成的DMA配置代码的程序编译之后,程序会卡死。
注释掉则可以运行其它代码(用了一颗LED闪烁测试程序是否在运行)。

在论坛帖子里找到了乘风和冲哥两个版本的I2C_DMA的OLED例程,
试了下,在STC32G上正常运行。
6.jpg 正常32G.jpg


然后移植进AiCube生成的框架里(需要去掉REMOVEUNUSED,否则会反复重启),
先用不带DMA的函数显示一个字符串,然后再用DMA的函数发送一个全屏的图案。
结果是
冲哥版本的也是直接卡死(LED不闪烁);
乘风版本的发送一次数据之后会卡死(屏幕上可以显示出第一轮发送的第一行的128个数据的图案,LED不闪烁)。
冲哥.jpg chengfeng.jpg


能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:207
  • 最近打卡:2025-06-15 14:11:16
已绑定手机

67

主题

1906

回帖

4279

积分

荣誉版主

无情的代码机器

积分
4279
发表于 2025-6-4 18:11:16 | 显示全部楼层

点评

收到!晚上试一下  详情 回复 发表于 2025-6-4 18:24
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:433
  • 最近打卡:2025-06-15 14:30:03

28

主题

336

回帖

2888

积分

荣誉版主

积分
2888
发表于 2025-6-4 18:24:04 | 显示全部楼层
erci*** 发表于 2025-6-4 18:11
试下这个
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=18053&pid=166996

收到!晚上试一下
能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:433
  • 最近打卡:2025-06-15 14:30:03

28

主题

336

回帖

2888

积分

荣誉版主

积分
2888
发表于 2025-6-6 13:57:47 | 显示全部楼层
尝试AiCube的工程添加I2C_DMA,汇报一下这几天的尝试结果

1、首先是移植论坛里的STC32G的例程到Ai8051U,不用AiCube生成的框架。
1.1测试函数.jpg 1.2测试函数2.jpg

先用 函数test00(),直接发送数据的方式显示一个背景图案。效果:正常显示
这种方式不受OLED的地址模式限制。

然后用I2C_DMA发送数据的函数 WriteNbyte(u8 *pData, u16 number)  和定位函数 OLED_Set_Pos(u8 x,u8 y)

分多次显示出一张128×64的图片,其中:

test01(),是每次发送图片中的256字节数据,发送四次。效果:正常显示
这种方式只适合OLED的水平地址模式,显示满一行自动拐到下一行开头继续显示。

test02(),是每次发送图片里的128字节数据,发送八次。效果:正常显示
这种方式同样不受OLED的地址模式限制。

然后是清屏函数 CLearOLED(),是连续发送1024字节数据0,清空屏幕。
这种方式也只适合OLED的水平地址模式。


1.3测试函数3.jpg

在while(1)循环里,调用的是 PrintOK( flag ) 函数,在屏幕右上角闪烁一个“OK”。
这时遇到了问题。
在显示完“OK”的上半部分之后,程序就卡死了,下半部分没有显示,LED也不闪烁。
但是如果不调用 PrintOK 函数,则程序依旧可以正常运行,没有卡死现象。

观察发现,在前面的那些调用过 WriteNbyte 函数的地方,后面都跟着一个延时函数,
而闪烁“OK”的 PrintOK 函数里,第一个 WriteNbyte 函数之后紧跟着一个定位函数,并没有延时函数。

猜测问题是不是在这里,于是在 PrintOK 函数的  WriteNbyte 函数和定位函数之间试着添加了一个延时函数,
果然可以继续显示,并且“OK”和LED都能闪烁了。

经过实验,中间加的延时函数, 时长最少是 delay_ms(2),如果是 delay_ms(1) 则依旧会卡死。

但是用延时函数总感觉不太美好,是因为“OK”每次只发送16个字节,速度太快了吗?于是在 WriteNbyte 函数里继续尝试。
在 WriteNbyte 的DMA忙检测 语句后面,又添加了一个 I2C忙检测 的语句之后,终于正常了。
1.4.jpg


效果视频如下:



==================================================================

2、尝试将上面正常显示的程序,搬到AiCube生成的框架里。

同样的配置代码,不用DMA的函数的时候,可以正常显示,而调用 WriteNbyte 函数时,依旧会卡死。

效果视频:前面 显示字符串、清屏、显示完整图片、清屏,调用的都是不用DMA的函数,最后一次是调用 WriteNbyte 函数显示完整图片,从画面看只发送了一百多个字节就卡死了。


突然想到,AiCube在配置DMA的时候有一项发送等待的设置,于是添加进DMA的初始化函数里。
3.1.jpg

再试了一下,DMA的图片也显示出来了,但是依旧会卡死。


因为AiCube配置的时候添加了USB下载,所以“卡死”的现象之一就是电脑会弹出无法识别USB设备的提示,说明真卡死了。
4.1.jpg


=============================================
这是上面用到的两个工程文件,实在想不到原因了
不用AiCube框架的: 20250606_1Ai8051U_I2C_DMA_noAiCube.rar (23.64 KB, 下载次数: 6)
用AiCube框架的: 20250606_5AI8051U_I2C_DMA_AiCube.rar (80.57 KB, 下载次数: 6)









能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:207
  • 最近打卡:2025-06-15 14:11:16
已绑定手机

67

主题

1906

回帖

4279

积分

荣誉版主

无情的代码机器

积分
4279
发表于 2025-6-6 20:10:49 | 显示全部楼层
代码里 混用了 查询模式 和 中断模式

截图202506062010206846.jpg
截图202506062009497541.jpg
截图202506062009323874.jpg
截图202506062009212053.jpg


点评

这个 WriteNbyte 函数还有硬件I2C和I2C_DMA配置,是Ai8051U试验箱里的例程-66 里的写法,另外乘风和冲哥在另一个讨论题里提供的OLED例程里也都是这样写的 https://www.stcaimcu.com/forum.php?mod=redirect&goto=fin  详情 回复 发表于 2025-6-7 12:55
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:433
  • 最近打卡:2025-06-15 14:30:03

28

主题

336

回帖

2888

积分

荣誉版主

积分
2888
发表于 2025-6-7 12:55:08 | 显示全部楼层
erci*** 发表于 2025-6-6 20:10
代码里混用了查询模式和中断模式

这个 WriteNbyte 函数还有硬件I2C和I2C_DMA配置,是Ai8051U试验箱里的例程-66 里的写法,另外乘风和冲哥在另一个讨论题里提供的OLED例程里也都是这样写的
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=5917&pid=49717
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=5917&pid=49824

这三个例程移植到手动创建的工程里都可以运行,OLED顺利显示,并且不会卡死。但是移植到AiCube生成的工程里,调用WriteNbyte之后就会卡死,不调用就可以正常显示。

另外试过不用中断的方式,在AiCube的框架里,效果也是一样的


能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:433
  • 最近打卡:2025-06-15 14:30:03

28

主题

336

回帖

2888

积分

荣誉版主

积分
2888
发表于 2025-6-8 13:56:46 | 显示全部楼层
官方能否提供一个可以正常运行的I2C_DMA演示例程?不一定是OLED的,任何收发的都行。 _-_Zzzzzzz

点评

上面已经发过了DMA的例子 https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=18258&pid=169141 另外这个帖子的问题原因也发过了,中断和查询模式混用导致的。 20250606_5AI8051U_I2C_DMA_AiCube  详情 回复 发表于 2025-6-8 15:40
明请内部提供 AiCube 支持的: I2C-OLED12864; DMA-I2C-OLED12864; SPI-OLED12864; DMA-SPI-OLED12864;  详情 回复 发表于 2025-6-8 14:15
能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:98
  • 最近打卡:2025-06-15 09:46:00

733

主题

1万

回帖

1万

积分

管理员

积分
16603
发表于 2025-6-8 14:15:12 | 显示全部楼层
大*** 发表于 2025-6-8 13:56
官方能否提供一个可以正常运行的I2C_DMA演示例程?不一定是OLED的,任何收发的都行。 _-_Zzzzzzz ...

明请内部提供 AiCube 支持的:

I2C-OLED12864;
DMA-I2C-OLED12864;

SPI-OLED12864;
DMA-SPI-OLED12864;


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:207
  • 最近打卡:2025-06-15 14:11:16
已绑定手机

67

主题

1906

回帖

4279

积分

荣誉版主

无情的代码机器

积分
4279
发表于 2025-6-8 15:40:53 | 显示全部楼层
大*** 发表于 2025-6-8 13:56
官方能否提供一个可以正常运行的I2C_DMA演示例程?不一定是OLED的,任何收发的都行。 _-_Zzzzzzz ...

上面已经发过了DMA的例子
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=18258&pid=169141

另外这个帖子的问题原因也发过了,中断和查询模式混用导致的。
20250606_5AI8051U_I2C_DMA_AiCube这个工程里验证 :用查询模式前将中断关掉就可以了
截图202506081538324512.jpg

点评

关了中断会影响其它功能,那就只能放弃普通显示的那些函数和DMA中断混用了,都改成全刷和局刷的缓存方式显示。  详情 回复 发表于 2025-6-8 19:54
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:433
  • 最近打卡:2025-06-15 14:30:03

28

主题

336

回帖

2888

积分

荣誉版主

积分
2888
发表于 2025-6-8 19:54:16 | 显示全部楼层

关了中断会影响其它功能,那就只能放弃普通显示的那些函数和DMA中断混用了,都改成全刷和局刷的缓存方式显示。

另外主要就是好奇为什么试验箱例程可以那样用,放进AiCube的框架就不行了。

点评

一样的都是开关中断的,实验箱66例程只开关I2C主机中断: [attachimg]103084[/attachimg] [attachimg]103085[/attachimg]  详情 回复 发表于 2025-6-8 20:00
能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-16 04:41 , Processed in 1.691399 second(s), 110 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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