找回密码
 立即注册
楼主: zhp

AiCube自动生成【SPI,SPI-DMA,I2C,I2C-DMA】代码,驱动OLED-12864, @Ai8051U

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:447
  • 最近打卡:2025-06-29 12:08:05

29

主题

344

回帖

2873

积分

荣誉版主

积分
2873
发表于 2025-6-19 11:58:36 | 显示全部楼层
看到楼上的I/O口配置部分,突然想起一个问题,补充在这里就不另开帖子了。
之前论坛上有些朋友提过,使用论坛上的老刘示波器等等例程的时候,

屏幕会花屏或者内容错乱。
大家一直在程序方面寻找原因。

前段时间发现,可能是市面上的OLED屏幕模块质量问题,
如果IO口启用了内部上拉电阻(PxPU),有些屏幕模块可以正常显示,

有些屏幕模块就会显示混乱,关掉上拉电阻就又能正常显示。
不知道具体原因,但并不是程序本身的问题。





点评

SPI-OLED12864, 抗干扰 强: #SS, SCLK, MOSI, 都设置成强推挽,抗干扰肯定强 !!! I2C-OLED12864, 抗干扰 弱: SCL, SDA, 都设置成【准双向口/弱上拉 + 上拉电阻】,抗干扰一般,容易【高 被拉 低】 ===准双  详情 回复 发表于 2025-6-19 13:21
能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:112
  • 最近打卡:2025-06-29 00:35:48

741

主题

1万

回帖

1万

积分

管理员

积分
17190
发表于 2025-6-19 13:21:31 | 显示全部楼层
大*** 发表于 2025-6-19 11:58
看到楼上的IO口配置部分,突然想起一个问题,补充在这里就不另开帖子了。
之前论坛上有些朋友提过,使用论 ...

SPI-OLED12864, 抗干扰
#SS, SCLK, MOSI, 都设置成强推挽,抗干扰肯定强 !!!

I2C-OLED12864, 抗干扰
SCL, SDA, 都设置成【准双向口/弱上拉 + 上拉电阻】,抗干扰一般,容易【被拉
===准双向口/弱上拉 的输出 低的能力 和强推挽输出低的能力一样强,外界干扰打不过这个低

SCL, SDA, 都设置成【开漏 + 上拉电阻】,抗干扰一般,容易【高 被拉 低】
===开漏 输出 低的能力 和强推挽输出低的能力一样强,外界干扰打不过这个低

所以 I2C 的问题是 容易被干扰到,解决方案:
===1,卓教授,外加 500欧到 1K的强上拉,这样不容易被干扰到低
              卓老师后来重新布线,干扰小了,I2C 加 3K ~ 10K 上拉电阻即可

===2,直接改用 SPI 接口
              #SS, SCLK, MOSI, 都设置成强推挽,抗干扰肯定 !!!

截图202506191323166442.jpg


截图202506191324157561.jpg


截图202506191324491570.jpg


截图202506191325135839.jpg



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:112
  • 最近打卡:2025-06-29 00:35:48

741

主题

1万

回帖

1万

积分

管理员

积分
17190
发表于 2025-6-19 20:42:40 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:34
  • 最近打卡:2025-06-29 07:44:31
已绑定手机

1

主题

53

回帖

172

积分

注册会员

积分
172
发表于 7 天前 | 显示全部楼层
非常实用的内容。感谢分享!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:447
  • 最近打卡:2025-06-29 12:08:05

29

主题

344

回帖

2873

积分

荣誉版主

积分
2873
发表于 7 天前 | 显示全部楼层
试了一下SSD1306芯片的OLED12864屏幕专有的显示方式


把43张 76×64像素的图片取模成一个大数组 DANCER[26144];

屏幕的寻址模式设置成 【水平地址模式】

用OLED的设置显示范围的指令 0x21和 0x22 把屏幕控制范围缩小到图片的大小
  1. void DMA_OLED_Set_Area( u8 x, u8 y, u8 width, u8 height )
  2. {
  3.     u8 CMD[6];
  4.    
  5.     u8 page = ( height % 8 ) ? ( height/8+1 ) : ( height/8 );
  6.    
  7.     if( x<0 || (x+width-1)>127 ) return;    //坐标范围不可以超出屏幕范围
  8.     if( y<0 || (y+ page-1)>  7 ) return;
  9.    
  10.     CMD[0]= 0x21;                //设置列范围
  11.     CMD[1]= x;                       //设置起始列
  12.     CMD[2]= x+width-1;          //设置结束列
  13.    
  14.     CMD[3]= 0x22;                //设置行范围
  15.     CMD[4]= y;                       //设置起始行
  16.     CMD[5]= y+page-1;           //设置结束行
  17.     DMA_SendCommand( CMD, 6 );
  18. }
复制代码

然后直接发送图片里的所有数据

  1.     DMA_OLED_Set_Area ( 26, 0, 76, 64 );        // 设置显示区域
  2.             
  3.     DMA_SendData ( DANCER, 76*8*43 );        // 发送所有数据
  4.             
  5.     DMA_OLED_Set_Area( 0, 0, 128, 64 );        // 恢复全屏区域
复制代码


显示完一组内容之后,就可以重新设置其他显示区域

显示效果:




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

还可以直接创建一个显示图片的函数

  1. void DMA_OLED_ShowImage( u8 x, u8 y, u8 *pic, u8 width, u8 height )
  2. {
  3.         u16 bytes = ( height % 8 ) ? ( (height/8+1)*width ) : ( height/8*width );        //计算图片总字节数
  4.         DMA_OLED_Set_Area( x, y, width, height );        //设置将控制区域为图片大小
  5.         DMA_SendData ( pic, bytes );                           //发送图片所有数据
  6.         DMA_OLED_Set_Area( 0, 0, 128, 64 );               //恢复控制区域为全屏
  7. }
复制代码



不过这两个指令并不是通用指令
SSD1036、SSD1315、SSD1309等等支持,
SH1306等等不支持,还是要老老实实一行一行发送

定位函数

  1. void DMA_OLED_Set_Pos( u8 x, u8 y )
  2. {
  3.         u8 CMD[3];
  4.         x += 0;
  5.         CMD[0] = ( 0xB0 + y );                                        // 设置起始列地址
  6.         CMD[1] = ( x & 0x0F );                                        // 设置起始行地址低八位
  7.         CMD[2] = ( 0x10 + ( x >> 4 ) );        // 设置起始行地址高八位
  8.         DMA_SendCommand( CMD, 3 );
  9. }
复制代码



两种清屏函数

  1. void DMA_OLED_Clear() // 通用
  2. {
  3.         u8 DAT[128]={0};
  4.         u8 i;
  5.         for(i=0;i<8;i++)
  6.         {
  7.                 DMA_OLED_Set_Pos( 0, i );
  8.                 DMA_SendData( DAT, 128 );
  9.         }
  10. }
  11. void DMA_OLED_Clear() // 适合SSD1306等,不适合SH1106
  12. {
  13.         u8 DAT[1024]={0};
  14.         DMA_OLED_Set_Pos( 0, 0 );
  15.         DMA_SendData( DAT, 1024 );
  16. }
复制代码




通用的显示图片函数

  1. void DMA_OLED_ShowImage( u8 x, u8 y, u8 *pic, u8 width, u8 height )
  2. {
  3.         u8 i;
  4.         u8 pages = ( height % 8 ) ? ( height/8+1 ) : ( height/8 );
  5.         
  6.         for( i=0; i<pages; i++ )
  7.         {
  8.                         DMA_OLED_Set_Pos( x, y+i );
  9.                         DMA_SendData ( pic + width*i, width );
  10.         }
  11. }
复制代码









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

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:30
  • 最近打卡:2025-06-23 08:41:18
已绑定手机

16

主题

77

回帖

474

积分

中级会员

积分
474
发表于 6 天前 | 显示全部楼层
大*** 发表于 2025-6-17 15:33
I2C的发送和接收数据共用一条线(SDA),SPI是分成发送(MOSI)和接收(MISO)两条线。
因为控制OLED只需 ...

您解释的准确,精炼,易懂,非常感谢,又学到新知识了。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:30
  • 最近打卡:2025-06-23 08:41:18
已绑定手机

16

主题

77

回帖

474

积分

中级会员

积分
474
发表于 6 天前 | 显示全部楼层
神*** 发表于 2025-6-19 09:56
进行了 MOSI / MISO 切换

加油,我对 www.STCAI.com 充满期待,这两年确实发展的很快,
STCAI 是目前我认为单片机圈内生态做的最好的,
有问必答,真的是贴心。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-06-29 08:18:45
已绑定手机

0

主题

2

回帖

24

积分

新手上路

积分
24
发表于 5 天前 来自手机 | 显示全部楼层
学习了,真的好
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-06-28 17:35:22
已绑定手机

0

主题

1

回帖

28

积分

新手上路

积分
28
发表于 昨天 17:35 来自手机 | 显示全部楼层
为什么不转向vscode开发?

点评

那只是一个 编辑器,我们论坛有这个版块,很多坛友在用  详情 回复 发表于 昨天 21:54
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:112
  • 最近打卡:2025-06-29 00:35:48

741

主题

1万

回帖

1万

积分

管理员

积分
17190
发表于 昨天 21:54 | 显示全部楼层
41044*** 发表于 2025-6-28 17:35
为什么不转向vscode开发?

那只是一个 编辑器,我们论坛有这个版块,很多坛友在用
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-29 15:54 , Processed in 1.468585 second(s), 112 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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