OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 286|回复: 1

OLED 128X64 0.96和1.3英寸 测试过程中问题分享

[复制链接]

5

主题

63

帖子

0

精华

高级会员

Rank: 4

积分
536
金钱
536
注册时间
2016-7-29
在线时间
120 小时
发表于 5 天前 | 显示全部楼层 |阅读模式
本帖最后由 小迷哥 于 2026-9-13 12:08 编辑

一共测试了2个驱动芯片的OLED,
0.96英寸的SSD1306,这个用的中景园电子的的SPI和IIC模块
1.3英寸的SH1106,这个单独买的30pin裸屏,焊接到测试板上测的,

两者都支持5种通信方式,通过驱动芯片的IM0:2电平进行设置
6800总线, 8080总线, 4线SPI, 3线SPI, IIC

一:两种驱动芯片的区别
1)接口选择和功能
SSD1306
ScreenShot_2026-09-13_110849_133.png
注意:IIC通信时,需要将D1和D2短接,才能正常通信
因硬件条件限制:实际我只测试了4线SPI, 3线SPI和IIC

SH1106
ScreenShot_2026-09-13_110816_649.png
注意:按手册描述6800, 8080, IIC这3种方式都支持数据读和写,实际我只测试了6800和8080

其他:这个3线SPI接口比较巧妙,所有这5种通信方式都要干的1件事情就是,需要区分当前这个字节到底发的命令字节还是数据字节
1)6800, 8080, 4线SPI 的比较好理解,D/C为0时,表明当前读/写为命令, 为1时,表示当前读/写为数据
什么是命令字节呢?就是手册里面设置或配置驱动芯片,反馈状态的哪些命令表字节

2)3线SPI,它这个是将1帧数据分成2部分共9位,最高位就是D/C位,定义和1)一样,接着就是命令字节/数据

3)IIC, 这个也很巧妙,它和标准的IIC有些差异,这个实际硬件的D/C脚是从机器件地址的1个位,表示如下:
D/C#脚接1:SA0=1, 0x7A/0x7B
           接0:SA0=0, 0x78/0x79

IIC协议里面新增了1个控制字节,如果为0x00表示数据, 0x40表示为命令,这个Co位我没去测
ScreenShot_2026-09-13_112114_052.png


二:程序
主要实现的功能,任意坐标点ASCII字符显示,屏幕旋转滚动等设置,状态读取,GRAM数据读出和写入对比
参考的原子例程,自己新改了一些
1)//设置OLED模式
//OLED模式设置,和手册SSD1306一致
//0: 并行6800模式 (BS0/BS1/BS2:001b),可读可写
//1: 并行8080模式 (BS0/BS1/BS2:011b),可读可写
//2: 4线串行模式  (BS0/BS1/BS2:000b),只写
//3: 3线串行模式  (BS0/BS1/BS2:100b),只写
//4: IIC模式      (BS0/BS1/BS2:010b),只写
//type:0表示驱动的0.96英寸
//     1表示驱动的1.3英寸
void myOLED_ModeSet(u8 mode, u8 type)

2)实际使用6800/8080总线读取状态命令字节数据如下:
开显示的时候为0x28
关显示的时候为0x68

3)读出GRAM 和 写GRAM的数据对比,完全一致,1024B;


三:调试方法oled.h里面的宏#define OLED_MODE_MACRO     5//使用预处理方式确定1种
不要修改,我们不使用这个宏进行测试,
因为我们使用的void myOLED_ModeSet(u8 mode, u8 type);来进行设置总线和器件型号,切记切记!!!!

1) 移植USMART组件;
2)全功能使用USMART测试,测试函数,直接复制使用;
  1. //OLED 全功能测试
  2.     (void*)OLED_Display_On,     "void OLED_Display_On(void)",
  3.     (void*)OLED_Display_Off,    "void OLED_Display_Off(void)",
  4.     (void*)OLED_Refresh_Gram,   "void OLED_Refresh_Gram(void)",                     
  5.     (void*)OLED_Clear,          "void OLED_Clear(void)",
  6.     (void*)OLED_DrawPoint,      "void OLED_DrawPoint(u8 x,u8 y,u8 t)",
  7.     (void*)OLED_Fill,           "void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot)",
  8.     (void*)OLED_ShowChar,       "void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)",
  9.     (void*)OLED_ShowNum,        "void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)",
  10.     (void*)OLED_ShowString,     "void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size)",
  11.     (void*)OLED_WR_Byte,        "void OLED_WR_Byte(u8 dat,u8 cmd)",
  12.     (void*)OLED_SUSPEND_Display,"void OLED_SUSPEND_Display(u8 cmd)",
  13.     (void*)OLED_Fill_ALL,       "void OLED_Fill_ALL(void)",
  14.     (void*)OLED_SCAN_Dir,       "void OLED_SCAN_Dir(u8 mode)",

  15.     (void*)myOLED_Read,         "void myOLED_Read(u8 type)",
  16.     (void*)myOLED_ModeSet,      "void myOLED_ModeSet(u8 mode, u8 type)",
复制代码
main.c
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "key.h"
  4. #include "sys.h"
  5. #include "oled.h"
  6. #include "oled_iic.h"
  7. #include "usmart.h"
  8. #include "w25qxx.h"
  9. #include "usart.h"
  10.         
  11. int main(void)
  12. {        
  13.     u8 t;
  14.         delay_init();                     //延时函数初始化         
  15.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);         //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  16.          LED_Init();                             //LED端口初始化
  17.     W25QXX_Init();
  18.     uart_init(115200);
  19.     usmart_dev.init(72);

  20. //        OLED_Init();                        //初始化OLED  
  21. //  OLED_ShowString(0,0,"ALIENTEK",24);  
  22. //        OLED_ShowString(0,24, "0.96' OLED TEST",16);  
  23. //         OLED_ShowString(0,40,"ATOM 2015/1/14",12);  
  24. //         OLED_ShowString(0,52,"ASCII:",12);  
  25. //         OLED_ShowString(64,52,"CODE:",12);  

  26.     OLED_Init_IIC();  
  27.     OLED_ShowString_IIC(0,0,"ALIENTEK",24);  
  28.         OLED_ShowString_IIC(0,24, "0.96' OLED TEST",16);  
  29.          //OLED_ShowString_IIC(0,40,"ATOM 2015/1/14",12);  
  30.          OLED_ShowString_IIC(0,52,"ASCII:",12);  
  31.          OLED_ShowString_IIC(64,52,"CODE:",12);
  32.         t=' ';  
  33.         while(1)
  34.         {               
  35.         if(oled_suspend)
  36.         {
  37.             OLED_ShowChar(48,48,t,16,1);//显示ASCII字符           
  38.             OLED_Refresh_Gram();

  39.             OLED_ShowChar_IIC(48,48,t,16,1);//显示ASCII字符           
  40.             OLED_Refresh_Gram_IIC();
  41.             t++;
  42.             if(t>'~')t=' ';
  43.             OLED_ShowNum(103,48,t,3,16);//显示ASCII字符的码值
  44.             OLED_ShowNum_IIC(103,48,t,3,16);//显示ASCII字符的码值  
  45.         }
  46.                 delay_ms(500);
  47.                 LED0=!LED0;
  48.         }         
  49.         
  50. }
复制代码
上电后OLED屏什么都不会显示,必须先设置型号
myOLED_ModeSet(0,0);//0.96英寸 6800总线,这个可以添加初始化程序里面,也可以通过USMART直接发测试
myOLED_ModeSet(1,0);//0.96英寸 8080总线,按实际的通信接口和OLED型号来设置

读取GRAM过程
1)OLED_SUSPEND_Display(0);暂停当前显示
2)OLED_Refresh_Gram();刷新下GRAM
3)myOLED_Read(1);读取GRAM并和写入的对比,对比后会same or not same
printf("\r\nWrtie and Read data same!!! num:%d", t);
printf("\r\nWrtie and Read data not same,fail!!! num:%d", t);


读取状态过程
1)myOLED_Read(0)
同时可以
OLED_Display_On();开显示后读取1次

OLED_Display_Off();关显示后读取1次
就能看到返回结果了
ScreenShot_2026-09-13_114614_169.png

其他功能就不多说了,自己动手去验证,实践出真知

OLED V0.02.rar (15.09 KB, 下载次数: 1)
Planets, no limit!
回复

使用道具 举报

5

主题

63

帖子

0

精华

高级会员

Rank: 4

积分
536
金钱
536
注册时间
2016-7-29
在线时间
120 小时
 楼主| 发表于 5 天前 | 显示全部楼层
cool                  
Planets, no limit!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-9-18 22:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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