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

求助帖—如何使用擎天柱AI8051最小系统板驱动iic0.96OLED屏幕

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-03-14 12:08:00
已绑定手机

5

主题

48

回帖

277

积分

中级会员

积分
277
发表于 2024-12-25 21:04:20 | 显示全部楼层 |阅读模式
本人已经研究2天还是不能驱动屏幕,最多只能驱动屏幕显示雪花屏,
请各位大佬指教,该如何学习i2c屏幕,看过一下开源项目都不能成功复现
,希望能看下能成功驱动屏幕的源代码

截图202412252104065492.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-03-14 12:08:00
已绑定手机

5

主题

48

回帖

277

积分

中级会员

积分
277
发表于 2024-12-25 21:06:18 | 显示全部楼层
软键i2c和硬件i2c都尝试过,我的代码是东拼西凑来的,就不展示我的愚见了

点评

能显示雪花点,说明驱动部分没有问题,正常驱动屏幕了。问题必然就是出在显示函数的使用上。正确顺序是在初始化屏幕之后,先调用清屏函数,熄灭屏幕上所有的点,然后再用显示字符或者图片的函数。  详情 回复 发表于 2024-12-26 09:19
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-12-25 23:52:14 | 显示全部楼层
我是这样学习的
根据OLED屏的COG IC (Chip On Glass Integrated Circuit)找到原厂数据手册(Datasheet),翻译一遍,尤其是指令集部分,看懂这个芯片有哪些功能,如何工作的,寄存器每个bit都要弄懂
还有OLED需要的工作条件,电压,时钟,扫描顺序方向,对比度,反白,滚动等等
单片机也是,IO如何配置,硬件I2C如何使用,时钟速度,上升沿下降沿,指令数据是如何传输的,哪个字节哪个位代表什么,每个bit都要弄懂
然后用单片机通过I2C把OLED的寄存器都配置一遍,接个逻辑分析仪看I2C信号,有没有按照预期工作,都正确配置了就能正常工作了,随便显示什么
然后是如何让OLED按照你的想法点亮或熄灭某个像素,显示一个点,一条线,一个字符,行列排列方式,数据发送顺序,字模和图片的显示
到处抄代码东拼西凑是学不会的
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-12-26 00:01:40 | 显示全部楼层
截图202412260001333105.jpg

  1. #include <STC8G.H>
  2. #include "define.h"
  3. #include <intrins.h>
  4. #define         RXD                P30
  5. #define         TXD                P31
  6. #define         SCL                P32
  7. #define         SDA                P33
  8. bit I2C_Busy;
  9. unsigned char code BMP[]=
  10. {
  11.         #include <0.h>
  12. };
  13. void Delay_10ms(void)
  14. {
  15.         unsigned char i,j;
  16.         _nop_();
  17.         _nop_();
  18.         i=144;
  19.         j=157;
  20.         do
  21.         {
  22.                 while(--j);
  23.         }
  24.         while(--i);
  25.         WDT_CONTR=CLR_WDT;
  26. }
  27. void Delay_x10ms(unsigned char x)
  28. {
  29.         while(--x)
  30.                 Delay_10ms();
  31. }
  32. void I2C_Start(void)
  33. {
  34.         I2C_Busy=1;
  35.         I2CMSCR=0x81;
  36.         while(I2C_Busy);
  37. }
  38. void I2C_SendData(unsigned char dat)
  39. {
  40.         I2CTXD=dat;
  41.         I2C_Busy=1;
  42.         I2CMSCR=0x82;
  43.         while(I2C_Busy);
  44. }
  45. void I2C_RecvACK(void)
  46. {
  47.         I2C_Busy=1;
  48.         I2CMSCR=0x83;
  49.         while(I2C_Busy);
  50. }
  51. //unsigned char I2C_RecvData(void)
  52. //{
  53. //        I2C_Busy=1;
  54. //        I2CMSCR=0x84;
  55. //        while(I2C_Busy);
  56. //        return I2CRXD;
  57. //}
  58. //void I2C_SendACK(void)
  59. //{
  60. //        I2CMSST=0x00;
  61. //        I2C_Busy=1;
  62. //        I2CMSCR=0x85;
  63. //        while(I2C_Busy);
  64. //}
  65. //void I2C_SendNAK(void)
  66. //{
  67. //        I2CMSST=0x01;
  68. //        I2C_Busy=1;
  69. //        I2CMSCR=0x85;
  70. //        while(I2C_Busy);
  71. //}
  72. void I2C_Stop(void)
  73. {
  74.         I2C_Busy=1;
  75.         I2CMSCR=0x86;
  76.         while(I2C_Busy);
  77. }
  78. void SSD1316_Write_CMD(unsigned char cmd)
  79. {
  80.         I2C_Start();
  81.         I2C_SendData(0x78);
  82.         I2C_RecvACK();
  83.         I2C_SendData(0x00);
  84.         I2C_RecvACK();
  85.         I2C_SendData(cmd);
  86.         I2C_RecvACK();
  87.         I2C_Stop();
  88. }
  89. void SSD1316_Write_DATA_A(void)
  90. {
  91.         I2C_Start();
  92.         I2C_SendData(0x78);
  93.         I2C_RecvACK();
  94.         I2C_SendData(0x40);
  95.         I2C_RecvACK();
  96. }
  97. void SSD1316_Write_DATA_B(unsigned char dat)
  98. {
  99.         I2C_SendData(dat);
  100.         I2C_RecvACK();
  101. }
  102. void SSD1316_Write_DATA_C(void)
  103. {
  104.         I2C_Stop();
  105. }
  106. void SSD1316_Clear(void)  
  107. {  
  108.         unsigned char i,n;                    
  109.         for(i=0;i<4;i++)  
  110.         {  
  111.                 SSD1316_Write_CMD(0xb0+i);        //设置页地址(0~3)
  112.                 SSD1316_Write_CMD(0x00);        //设置显示位置—列低地址
  113.                 SSD1316_Write_CMD(0x10);        //设置显示位置—列高地址  
  114.                 SSD1316_Write_DATA_A();               
  115.                 for(n=0;n<128;n++)
  116.                 {
  117.                         SSD1316_Write_DATA_B(0x00);
  118.                 }
  119.                 SSD1316_Write_DATA_C();
  120.         }
  121. }
  122. void SSD1316_Display_128x32(void)
  123. {
  124.         unsigned int i;
  125.         SSD1316_Write_CMD(0x20);        //Set Memory Addressing Mode(设置内存寻址模式)
  126.         SSD1316_Write_CMD(0x01);        //0x01(垂直寻址模式)
  127.         SSD1316_Write_CMD(0x21);        //Set Column Address(设置列地址)
  128.         SSD1316_Write_CMD(0);                //(列开始地址)
  129.         SSD1316_Write_CMD(127);                //(列结束地址)
  130.         SSD1316_Write_CMD(0x22);        //Set Page Address(设置页地址)
  131.         SSD1316_Write_CMD(0x00);        //0
  132.         SSD1316_Write_CMD(0x03);        //3
  133.         SSD1316_Write_DATA_A();
  134.         for(i=0;i<512;i++)
  135.         {
  136.                 SSD1316_Write_DATA_B(BMP[i]);
  137.         }
  138.         SSD1316_Write_DATA_C();
  139.         SSD1316_Write_CMD(0x20);        //Set Memory Addressing Mode(设置内存寻址模式)
  140.         SSD1316_Write_CMD(0x02);        //0x02(页寻址模式)
  141. }
  142. void SSD1316_Init(void)
  143. {
  144.         SSD1316_Write_CMD(0xAE);        //Set Display OFF(设置显示关)
  145.         SSD1316_Write_CMD(0xA1);        //Set Segment Remap(设置列重映射)
  146.         SSD1316_Write_CMD(0xA8);        //Set Multiplex Ratio(设置行通道数)
  147.         SSD1316_Write_CMD(0x1F);        //31
  148. //        SSD1316_Write_CMD(0xC8);        //Set COM Output Scan Direction(设置行重映射)
  149.         SSD1316_Write_CMD(0xD3);        //Set Display Offset(设置垂直偏移量)
  150.         SSD1316_Write_CMD(0x00);        //0
  151.         SSD1316_Write_CMD(0xD5);        //Set Display Clock Divide Ratio/Oscillator Frequency(设置显示时钟分频器、振荡器频率)
  152.         SSD1316_Write_CMD(0xF0);        //0xF0
  153.         SSD1316_Write_CMD(0x8D);        //Charge Pump Setting(设置电荷泵)
  154.         SSD1316_Write_CMD(0x14);        //0x14
  155.         SSD1316_Write_CMD(0xAF);        //Set Display ON(设置显示开)
  156.         SSD1316_Clear();
  157. //        SSD1316_Write_CMD(0x81);        //Set Contrast Control(设置对比度)
  158. //        SSD1316_Write_CMD(0x7F);        //127
  159. //        SSD1316_Write_CMD(0xA7);        //Set Normal/Inverse Display(设置反相显示)
  160. }
  161. void Init(void)
  162. {
  163.         P_SW2|=EAXFR;
  164.         P3M0=0x00;
  165.         P3M1=0x00;
  166.         P5M0=0x00;
  167.         P5M1=0x00;
  168.         P3PU=0x0c;
  169.         I2CCFG=0xC1;        //921.6K@11.0592M
  170.         I2CMSCR=EMSI;
  171.         I2CMSST=0x00;
  172.         EA=1;
  173.         Delay_x10ms(10);
  174.         SSD1316_Init();
  175. }
  176. void main(void)
  177. {
  178.         Init();
  179.         SSD1316_Display_128x32();
  180.         while(1)
  181.         {
  182.                 SSD1316_Write_CMD(0xA6);
  183.                 Delay_x10ms(50);
  184.                 SSD1316_Write_CMD(0xA7);
  185.                 Delay_x10ms(50);
  186.         }
  187. }
  188. void I2C_Isr(void) interrupt 24
  189. {
  190.         _push_(P_SW2);
  191.         P_SW2|=EAXFR;
  192.         if(I2CMSST&MSIF)
  193.         {
  194.                 I2CMSST&=~MSIF;
  195.                 I2C_Busy=0;
  196.         }
  197.         _pop_(P_SW2);
  198. }
复制代码


DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-12-26 00:05:27 | 显示全部楼层

截图202412260009473272.jpg


  1. #include <STC8.H>
  2. #include <intrins.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <math.h>
  6. #define                A0                        P30
  7. #define                CS_O                P31
  8. #define                CLK                        P32
  9. #define                MISO                P33
  10. #define                MOSI                P54
  11. #define                CS_F                P55
  12. #define                FOSC                11059200UL
  13. #define                Command                0
  14. #define                Data                1
  15. #define                Enable                0
  16. #define                Disable                1
  17. unsigned char FPS;
  18. unsigned int Temp,Frame,Video;
  19. unsigned char xdata Buffer[4][64];
  20. unsigned char code String[10][5]=
  21. {
  22.         /*----------------------------数字----------------------------*/
  23.         0x7E,0x81,0x81,0x81,0x7E,
  24.         0x00,0x82,0xFF,0x80,0x00,
  25.         0xC2,0xA1,0x91,0x89,0x86,
  26.         0x42,0x81,0x89,0x89,0x76,
  27.         0x18,0x14,0x12,0xFF,0x10,
  28.         0x4F,0x89,0x89,0x89,0x71,
  29.         0x7C,0x8A,0x89,0x89,0x70,
  30.         0x01,0xC1,0x31,0x0D,0x03,
  31.         0x76,0x89,0x89,0x89,0x76,
  32.         0x0E,0x91,0x91,0x51,0x3E,
  33. };
  34. /*----------------------------延时10us@STC-Y6@11.0592MHz----------------------------*/
  35. //void Delay_10us(void)
  36. //{
  37. //        unsigned char i;
  38. //        i=35;
  39. //        while(--i);
  40. //}
  41. /*----------------------------延时x10us----------------------------*/
  42. //void Delay_x10us(unsigned char x)
  43. //{
  44. //        while(x--)
  45. //                Delay_10us();
  46. //}
  47. /*----------------------------延时10ms@STC-Y6@11.0592MHz----------------------------*/
  48. void Delay_10ms(void)
  49. {
  50.         unsigned char i,j;
  51.         _nop_();
  52.         _nop_();
  53.         i=144;
  54.         j=157;
  55.         do
  56.         {
  57.                 while(--j);
  58.         }while(--i);
  59. }
  60. /*----------------------------延时x10ms----------------------------*/
  61. //void Delay_x10ms(unsigned char x)
  62. //{
  63. //        while(x--)
  64. //                Delay_10ms();
  65. //}
  66. void SPI_Write(unsigned char temp)
  67. {
  68.         unsigned char i;
  69.         for(i=0;i<8;i++)
  70.         {
  71.                 CLK=0;
  72.                 temp<<=1;
  73.                 MOSI=CY;
  74.                 CLK=1;
  75.         }
  76. }
  77. unsigned char SPI_Read(void)
  78. {
  79.         unsigned char i,temp;
  80.         for(i=0;i<8;i++)
  81.         {
  82.                 temp<<=1;
  83.                 CLK=0;
  84.                 CLK=1;
  85.                 if(MISO)
  86.                         temp|=0x01;
  87.         }
  88.         return temp;
  89. }
  90. void SH1106_Init(void)
  91. {
  92.         A0=Command;
  93.         SPI_Write(0xae);        //关闭显示
  94.         SPI_Write(0xa8);        //设置驱动路数为32路
  95.         SPI_Write(0x1f);        //设置驱动路数为32路
  96.         SPI_Write(0xc8);        //设置Common输出扫描方向
  97.         SPI_Write(0xa1);        //设置镜像
  98. //        SPI_Write(0xa7);        //设置反白
  99.         SPI_Write(0xaf);        //打开显示
  100. }
  101. void SH1106_Set_Posi(unsigned char page,unsigned char column)
  102. {
  103.         A0=Command;
  104.         SPI_Write(0xb0+(page&0x0f));
  105.         SPI_Write(0x00+(column&0x0f));
  106.         SPI_Write(0x12+((column&0xf0)>>4));
  107. }
  108. void SH1106_Clear_Screen(void)
  109. {
  110.         unsigned char i,j;
  111.         for(i=0;i<4;i++)
  112.         {
  113.                 A0=Command;
  114.                 SPI_Write(0xb0+i);
  115.                 SPI_Write(0x00);
  116.                 SPI_Write(0x12);
  117.                 A0=Data;
  118.                 for(j=0;j<64;j++)
  119.                 {
  120.                         SPI_Write(0x00);
  121.                 }
  122.         }
  123. }
  124. void Display_String(unsigned char page,unsigned char column,unsigned char temp)
  125. {
  126.         unsigned char i;
  127.         SH1106_Set_Posi(page,column);
  128.         A0=Data;
  129.         for(i=0;i<5;i++)
  130.         {
  131.                 SPI_Write(String[temp][i]);
  132.         }
  133. }
  134. void Display_Buffer(void)
  135. {
  136.         unsigned char i,j;
  137.         CS_O=Enable;
  138.         for(i=0;i<4;i++)
  139.         {
  140.                 SH1106_Set_Posi(i,0);
  141.                 A0=Data;
  142.                 for(j=0;j<64;j++)
  143.                 {
  144.                         SPI_Write(Buffer[i][j]);
  145.                 }
  146.         }
  147.         CS_O=Disable;
  148. }
  149. void Flash_Read(unsigned int temp)
  150. {
  151.         unsigned char i,j;
  152.         CS_F=Enable;
  153.         SPI_Write(0x03);
  154.         SPI_Write(temp/256);
  155.         SPI_Write(temp%256);
  156.         SPI_Write(0x00);
  157.         for(i=0;i<4;i++)
  158.         {
  159.                 CS_F=Enable;
  160.                 for(j=0;j<64;j++)
  161.                 {
  162.                         Buffer[i][j]=SPI_Read();
  163.                 }
  164.         }
  165.         CS_F=Disable;
  166. }
  167. void Config_Read(void)
  168. {
  169.         CS_F=Enable;
  170.         SPI_Write(0x03);
  171.         SPI_Write(0);
  172.         SPI_Write(0);
  173.         SPI_Write(0x00);
  174.         FPS=SPI_Read();
  175.         Video=SPI_Read();
  176.         Video<<=8;
  177.         Video|=SPI_Read();
  178.         CS_F=Disable;
  179. }
  180. void Init_OLED(void)
  181. {
  182.         CS_O=Enable;
  183.         SH1106_Init();
  184.         SH1106_Set_Posi(0,0);
  185.         SH1106_Clear_Screen();
  186.         CS_O=Disable;
  187. }
  188. void Init(void)
  189. {
  190.         P3M0=0x04;
  191.         P3M1=0x08;
  192.         P5M0=0x30;
  193.         P5M1=0x00;
  194.         P3PU=0x03;
  195.         P5PU=0x00;
  196.         Config_Read();
  197.         Temp=0x10000-FOSC/12/FPS;
  198.         TH0=Temp>>8;        //设置定时初始值
  199.         TL0=Temp;                //设置定时初始值
  200.         TF0=0;                        //清除TF0标志
  201.         ET0=1;                        //打开定时器0中断
  202.         EA=1;                        //打开总中断
  203. }
  204. void main(void)
  205. {
  206.         Init();
  207.         if(P30)
  208.         {
  209.                 Init_OLED();
  210.                 TR0=1;                //打开定时器0
  211.                 while(1);
  212.         }
  213.         else
  214.         {
  215.                 while(!P30);
  216.                 Delay_10ms();
  217.                 Init_OLED();
  218.                 Delay_10ms();
  219.                 CS_O=Enable;
  220.                 Display_String(0,0,FPS/100);
  221.                 Display_String(0,6,FPS%100/10);
  222.                 Display_String(0,12,FPS%10);
  223.                 Display_String(1,0,Video/10000);
  224.                 Display_String(1,6,Video%10000/1000);
  225.                 Display_String(1,12,Video%1000/100);
  226.                 Display_String(1,18,Video%100/10);
  227.                 Display_String(1,24,Video%10);
  228.                 CS_O=Disable;
  229.                 P3M0=0x00;
  230.                 P3M1=0x0C;
  231.                 P5M0=0x00;
  232.                 P5M1=0x30;
  233.                 P3PU=0x03;
  234.                 P5PU=0x00;
  235.                 while(1);
  236.         }
  237. }
  238. void Timer0(void) interrupt 1
  239. {
  240.         unsigned char i;
  241.         Flash_Read(Frame);
  242.         if(Frame==0)
  243.         {
  244.                 for(i=0;i<3;i++)
  245.                 {
  246.                         Buffer[0][i]=0x00;
  247.                 }
  248.         }
  249.         Display_Buffer();
  250.         Frame++;
  251.         if(Frame==Video)
  252.                 Frame=0;
  253. }
复制代码


DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-12-26 00:14:05 | 显示全部楼层
你的应该是SSD1306的,自己研究吧,显示雪花屏已经成功一半了
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-03-14 12:08:00
已绑定手机

5

主题

48

回帖

277

积分

中级会员

积分
277
发表于 2024-12-26 08:46:54 | 显示全部楼层
Debu*** 发表于 2024-12-25 23:52
我是这样学习的
根据OLED屏的COG IC (Chip On Glass Integrated Circuit)找到原厂数据手册(Datasheet), ...

好的谢谢佬
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-03-14 12:08:00
已绑定手机

5

主题

48

回帖

277

积分

中级会员

积分
277
发表于 2024-12-26 08:47:12 | 显示全部楼层
wnag*** 发表于 2024-12-26 07:11
贡献我自己翻译的1306文件

谢谢佬
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:392
  • 最近打卡:2025-05-01 15:00:39

24

主题

305

回帖

2556

积分

荣誉版主

积分
2556
发表于 2024-12-26 09:19:42 | 显示全部楼层
何*** 发表于 2024-12-25 21:06
软键i2c和硬件i2c都尝试过,我的代码是东拼西凑来的,就不展示我的愚见了

能显示雪花点,说明驱动部分没有问题,正常驱动屏幕了。问题必然就是出在显示函数的使用上。正确顺序是在初始化屏幕之后,先调用清屏函数,熄灭屏幕上所有的点,然后再用显示字符或者图片的函数。

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

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:154
  • 最近打卡:2025-04-30 08:40:57
已绑定手机

15

主题

630

回帖

730

积分

高级会员

积分
730
发表于 2024-12-26 23:49:35 来自手机 | 显示全部楼层
大明狐 发表于 2024-12-26 09:19
能显示雪花点,说明驱动部分没有问题,正常驱动屏幕了。问题必然就是出在显示函数的使用上。正确顺序是在 ...

他的是SSD1306的iic屏。我也有一块,最左边是VCC的

点评

我正在用的I2C的也是VCC在最左边的。这根是否点亮没关系。只要驱动程序对上了,屏幕就会亮。不出内容就要从程序本身找原因,要么是函数使用不对,要么是时序配置有误差。  详情 回复 发表于 2024-12-27 08:57
STC 666 888
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-1 19:43 , Processed in 0.243312 second(s), 112 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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