[其他ST产品] STM32 HAL 硬件IIC+DMA+简单图形库控制OLED

[复制链接]
4193|45
 楼主| wangtaohui 发表于 2023-6-28 20:22 | 显示全部楼层
修改OLED_Init函数
  1. void OLED_Init(void)
  2. {
  3.         WriteCmd(0xAE); //display off

  4.         WriteCmd(0x20); //Set Memory Addressing Mode
  5. //        WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
  6.         WriteCmd(0x00); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid

  7.         WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
  8.         WriteCmd(0xc8); //Set COM Output Scan Direction
  9.         WriteCmd(0x00); //---set low column address
  10.         WriteCmd(0x10); //---set high column address
  11.         WriteCmd(0x40); //--set start line address
  12.         WriteCmd(0x81); //--set contrast control register
  13.         WriteCmd(0xff); //亮度调节 0x00~0xff
  14.         WriteCmd(0xa1); //--set segment re-map 0 to 127
  15.         WriteCmd(0xa6); //--set normal display
  16.         WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
  17.         WriteCmd(0x3F); //
  18.         WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
  19.         WriteCmd(0xd3); //-set display offset
  20.         WriteCmd(0x00); //-not offset
  21.         WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
  22.         WriteCmd(0xf0); //--set divide ratio
  23.         WriteCmd(0xd9); //--set pre-charge period
  24.         WriteCmd(0x22); //
  25.         WriteCmd(0xda); //--set com pins hardware configuration
  26.         WriteCmd(0x12);
  27.         WriteCmd(0xdb); //--set vcomh
  28.         WriteCmd(0x20); //0x20,0.77xVcc
  29.         WriteCmd(0x8d); //--set DC-DC enable
  30.         WriteCmd(0x14); //
  31.         WriteCmd(0xaf); //--turn on oled panel
  32.         OLED_CLS();
  33. }
 楼主| wangtaohui 发表于 2023-6-28 20:23 | 显示全部楼层
其中 WriteCmd(0x20); WriteCmd(0x00); 两句函数将SSD1306的寻址方式修改为了水平寻址,能够一次性对OLED内部Graphic Display Data RAM (GDDRAM)整体更新。
见firestaradmin大佬的
《STM32 DMA-IIC刷新OLED屏(理论可达42+帧率)》
和Coder_BCM大佬的
《基于STM32F407的 中景园0.96寸OLED(IIC)的程序升级(DMA+IIC + 显存Buffer)》)
若发现行错位,则修改

        WriteCmd(0xd3); //-set display offset
        WriteCmd(0x00 加或减 8的倍数);
 楼主| wangtaohui 发表于 2023-6-28 20:23 | 显示全部楼层
使用和验证
添加test.c,该文件源自原例程,有修改。
需要注意的是调用OLED_ShowCHinese函数的文件和oled_font.c文件的编码格式需一致:GBK。当一个为UTF-8,一个为GBK时会显示不出汉字。
  1. /*
  2.         Copyright (c) [2019] [一只程序缘 jiezhuo]
  3.         [https://gitee.com/jiezhuonew/oledlib] is licensed under the Mulan PSL v1.
  4.         You can use this software according to the terms and conditions of the Mulan PSL v1.
  5.         You may obtain a copy of Mulan PSL v1 at:
  6.                 http://license.coscl.org.cn/MulanPSL
  7.         THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
  8.         IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
  9.         PURPOSE.
  10.         See the Mulan PSL v1 for more details.

  11.         ==========此函数是oledlib图形库的综合测试函数 基本上使用到了里面的所有内容==================

  12.         目前接线说明:
  13.                 仅仅使用到0.96寸7引脚oled 使用SPI通信方式(具体见oled_drive.c)
  14.                 D0  = SCK  ->        PA4                (屏幕批次不同丝印可能不同)
  15.                 D1  = SDA  ->        PA5
  16.                 RES = RES  ->        PA6
  17.                 DC  = DC   ->        PA7
  18.                 CS  = SCS  ->        PA8

  19.         软件模块:
  20.                 oled        spi驱动
  21.                 beep        蜂鸣器 提示或作为led表示运行状态
  22.                 timer3        中断1ms 可为图形库提供时间基准
  23.                 uart        可作为串口连接电脑打印调试xinxi
  24.                 delay        系统自带的时间设置与提供延时函数

  25.         视频演示信息:
  26.                 单片机 --- STM32F103
  27.                 oled   --- 采用4线SPI的7引脚0.96寸黑白双色oled

  28.         图形库功能:
  29.                 在oledlib文件夹下作出多个c文件的分类 每个c文件的开头都有对该文件的简要说明
  30.                 包括打点 画线 矩形 三角形 圆 椭圆 圆角矩形 的边缘与填充
  31.                 还包括 字符显示 汉字显示 位图显示
  32.                 最后还有 oled模拟串口printf的debug

  33.         字符显示:
  34.                 针对于字符有4种大小0-1-2-3 具体参见SetFontSize()
  35.                 基于大家的使用习惯
  36.                 0是一般大家习惯用的                        此时y只能为0-7对应显示的7大行                 注意:此时x为地基大行 y为第几列
  37.                 2 3都是基于1的等比例放大        此时y能为0-6x对应显示的每一小行                此时为正常坐标系 x为第几小行 y为第几列

  38.         中文汉字显示:
  39.                 中文汉字的大小为16x16                此时y也只能为0-7对应显示的7大行                注意:此时x为地基大行 y为第几列

  40.         取模说明:
  41.                 取模软件采用PCtoLCD2002
  42.                 字符 汉字 和 位图的取模方式和设置都在font.c和bmp.c中有注释

  43.         用户调用函数:
  44.                 在draw_api.h中提供了所有函数的接口 可在其中查看所有函数的简要功能

  45.         移植说明:
  46.                 1.移植图形库仅需要准备好底层驱动 在oled_driver.c中作出修改即可 在该c文件开头有说明
  47.                 2.若需要对test.c中的动画效果进行测试 还需要为函数OledTimeMsFunc()提供时间基准
  48.                 3.库函数使用的延时函数是DelayMs() 移植后由单片机型号补充调整DelayMs()

  49.         图形库本质:
  50.                 该图形库本质为对一数组进行操作 然后刷新整个数组到屏幕中实现效果
  51.                 因此相似点阵屏(oled/TFT/大小尺寸/点阵/液晶)也可以使用 根据像素可参见oled_config.h

  52.         详细的注释:
  53.                 如果是使用为用途 了解test.c和draw_api.c即可 做出花里胡哨的UI界面
  54.                 在本人阅读代码和注释的过程中 发现很多结构和函数都值得学习 仔细理解理解

  55.         GUI和本图形库的关系:
  56.                 gui是一个以图形界面来进行人机交互的系统 gui是拥有窗口、菜单、控件、对话框等交互的图形接口
  57.                 这个只是一个图形库 类似于c++上的easyx图形库 是没有图形接口的 只提供绘图和显示的功能
  58.                 图形库可以算是gui的一部分,也可以自己以图形库继续封装为gui库

  59.         代码容量:
  60.                 除去位图 Code=26254 RO-data=3754 RW-data=100 ZI-data=4108

  61.         原作的话:
  62.                 为了做这个绘制图形库,我参考了很多其他的算法,花了大量时间去做移植
  63.                 优化,其中参考最多的是github中的arduboy游戏机,大部分图形是移植它的,
  64.                 现在是最初的初稿版本,还有很多地方需要优化改进。我想要将这个图形库做大,
  65.                 后续会加入更多有趣的东西,和模块,代码都是用最简单的方式编写的,都是开源的。
  66.                 后续也会加上注释说明,让更多人以单片机和oled屏来入门硬件编程,如果你
  67.                 使用了该库,请标明出处。b站关注oximeterg,可获取该库的最新版本和消息。
  68.                 注意:绘制填充或实心的图形,影响刷新效率(待优化中)
  69. */


  70. // #include "test.h"
  71. #include "draw_api.h"
  72. #include "../Delay/Delay.h"
  73. #include "stdlib.h"
  74. #include "stdio.h"
  75. #include "math.h"

  76. void ShowStars(void);
  77. void ShowWatch(void);
  78. void ShowPolygon(void);
  79. void ShowSnow(void);

  80. void demo(void)
  81. {
  82.     int i,j;
  83.     //demo演示
  84.     ClearScreen();
  85.     DrawBitmap(0,0,Panda,128,64);
  86.     UpdateScreen();
  87.     DelayMs(1000);

  88.     //字符
  89.     ClearScreen();
  90.     SetFontSize(1);
  91.     DrawString(0,0,"test");
  92.     UpdateScreen();
  93.     DelayMs(1000);

  94.     SetFontSize(2);
  95.     DrawString(0,8,"test");
  96.     UpdateScreen();
  97.     DelayMs(1000);

  98.     SetFontSize(3);
  99.     DrawString(0,24,"test");
  100.     UpdateScreen();
  101.     DelayMs(1000);

  102.     //汉字测试
  103.     ClearScreen();
  104.     OLED_ShowCHinese(0,0,"一只程序缘");
  105.     UpdateScreen();
  106.     DelayMs(1000);
  107.     OLED_ShowCHinese(2,0,"一只程序缘一只程序缘一只程序缘一只程序缘");
  108.     UpdateScreen();
  109.     DelayMs(1000);

  110.     //数字测试
  111.     ClearScreen();
  112.     for(i=0; i<300; i++)
  113.     {
  114.         SetFontSize(0);
  115.         DrawNum(0,96,i,4);
  116.         SetFontSize(1);
  117.         DrawNum(0,16,i,4);
  118.         SetFontSize(2);
  119.         DrawNum(0,24,i,4);
  120.         SetFontSize(3);
  121.         DrawNum(0,40,i,4);
  122.         UpdateScreen();
  123.     }

  124.     //串口debug
  125.     DelayMs(100);
  126.     ClearScreen();
  127.     for(i=0; i<256; i++)
  128.     {
  129.         OledPrintf("num:%d cha:%c hex:%x\r\n",i,i,i);
  130.     }
  131.     DelayMs(100);

  132.     //划线
  133.     ClearScreen();
  134.     for(i=0; i<20; i++)
  135.     {
  136.         DrawLine(0,0,i*10,63);
  137.         UpdateScreen();
  138.     }
  139.     for(i=0; i<20; i++)
  140.     {
  141.         DrawLine(128,0,128-i*10,63);
  142.         UpdateScreen();
  143.     }
  144.     DelayMs(100);

  145.     //矩形
  146.     for(j=0; j<2; j++)
  147.     {
  148.         if(j==0)
  149.             ClearScreen();
  150.         for(i=0; i<31; i+=2)
  151.         {
  152.             DrawRect2(i*2,i,128-i*4,64-2*i);//画矩形外框
  153.             UpdateScreen();
  154.         }
  155.         if(j==0)
  156.             ClearScreen();
  157.         DelayMs(100);
  158.         for(i=31; i>0; i-=2)
  159.         {
  160.             DrawFillRect2(i*2,i,128-i*4,64-2*i);//画实心矩形
  161.             UpdateScreen();
  162.         }
  163.         SetDrawColor(pix_black);//划线颜色
  164.         SetFillcolor(pix_black);//填充颜色
  165.     }
  166.     SetDrawColor(pix_white);
  167.     SetFillcolor(pix_white);

  168.     //圆角矩形
  169.     for(j=0; j<2; j++)
  170.     {
  171.         if(j==0)
  172.             ClearScreen();
  173.         for(i=0; i<25; i+=2)
  174.         {
  175.             DrawRoundRect(i*2,i,128-i*4,64-2*i,8);
  176.             UpdateScreen();
  177.         }
  178.         if(j==0)
  179.             ClearScreen();
  180.         DelayMs(100);
  181.         for(i=25; i>2; i-=2)
  182.         {
  183.             DrawfillRoundRect(i*2,i,128-i*4,64-2*i,8);
  184.             UpdateScreen();
  185.         }
  186.         SetDrawColor(pix_black);
  187.         SetFillcolor(pix_black);
  188.     }
  189.     SetDrawColor(pix_white);
  190.     SetFillcolor(pix_white);
  191.     DelayMs(100);

  192.     //椭圆
  193.     ClearScreen();
  194.     DrawEllipse(63,31,63,31);
  195.     UpdateScreen();
  196.     DelayMs(500);
  197.     ClearScreen();
  198.     DrawEllipse(63,31,16,31);
  199.     UpdateScreen();
  200.     DelayMs(500);
  201.     ClearScreen();
  202.     DrawFillEllipse(63,31,63,31);
  203.     UpdateScreen();
  204.     DelayMs(500);
  205.     ClearScreen();
  206.     DrawFillEllipse(63,31,16,31);
  207.     UpdateScreen();
  208.     DelayMs(500);

  209.     //圆
  210.     ClearScreen();
  211.     DrawCircle(63,31,30);
  212.     UpdateScreen();
  213.     DelayMs(500);
  214.     ClearScreen();
  215.     DrawFillCircle(63,31,30);
  216.     UpdateScreen();
  217.     DelayMs(500);

  218.     //三角形
  219.     ClearScreen();
  220.     DrawTriangle(5,10,100,30,60,50);
  221.     UpdateScreen();
  222.     DelayMs(500);
  223.     ClearScreen();
  224.     DrawFillTriangle(5,10,100,30,60,50);
  225.     UpdateScreen();
  226.     DelayMs(500);

  227.     //绘制图形图片 位图
  228.     ClearScreen();
  229.     DrawBitmap(0,0,BmpTest1,16,16);
  230.     UpdateScreen();
  231.     DelayMs(500);
  232.     DrawBitmap(16,0,BmpTest2,32,32);
  233.     UpdateScreen();
  234.     DelayMs(500);
  235.     DrawBitmap(48,0,BmpTest3,64,64);
  236.     UpdateScreen();
  237.     DelayMs(500);

  238.     //圆弧
  239.     ClearScreen();
  240.     for(i=0; i<360; i++)
  241.     {
  242.         DrawArc(63,31,30,0,i);        //画圆弧
  243.         UpdateScreen();
  244.                 DelayMs(25);
  245.         ClearScreen();
  246.     }
  247.     DrawCircle(63,31,30);                //画圆
  248.     UpdateScreen();
  249.     DelayMs(100);

  250.     for(i=0; i<10; i++)
  251.     {
  252.         DrawFillCircle(63,31,i);        //在中心填充圆
  253.         DrawCircle(63,31,30);
  254.         UpdateScreen();
  255.                 DelayMs(25);
  256.         ClearScreen();
  257.     }

  258.     //绕点
  259.     for(i=0; i<720; i++) //转720度2圈
  260.     {
  261.         TypeXY temp;
  262.         SetAngle(i);                                        //设置角度
  263.         SetRotateCenter(63,31);                        //设置圆心
  264.         temp=GetRotateXY(63,31+30);                //讲已知坐标旋转角度
  265.         DrawFillCircle(temp.x,temp.y,5);//画出算出的位置
  266.         DrawCircle(63,31,30);                        //画出轨迹
  267.         DrawFillCircle(63,31,10);                //填充中心
  268.         UpdateScreen();                                        //更新屏幕
  269.         ClearScreen();
  270.     }

  271.     //向右边平移
  272.     for(i=0; i<95; i++)
  273.     {
  274.         TypeXY temp;                                        //其实就是上面继续旋转
  275.         SetAngle(720+i);                                //画图的时候x+偏移量
  276.         SetRotateCenter(63+i,31);
  277.         temp=GetRotateXY(63+i,31+30);
  278.         DrawFillCircle(temp.x,temp.y,5);
  279.         DrawCircle(63+i,31,30);
  280.         DrawFillCircle(63+i,31,10);
  281.         UpdateScreen();
  282.         ClearScreen();
  283.     }

  284.     //动画
  285.     ShowStars();        //星空动画
  286.     ShowWatch();        //时钟动画
  287.     ShowPolygon();        //多边形动画
  288. //        ShowSnow();                //下雪动画
  289.     DelayMs(100);

  290.     //结束
  291.     ClearScreen();
  292.     SetFontSize(2);
  293.     DrawString(8,16," Show End ");        //显示字符串
  294.     UpdateScreen();
  295.     DelayMs(1000);

  296.     ClearScreen();
  297.     DrawBitmap(0,10,Like,128,40);        //三连图片
  298.     UpdateScreen();
  299.         DelayMs(1000);
  300. }

  301. /
  302. //星空动画
  303. void ShowStars(void)
  304. {
  305.     int i;
  306.     int count=0;
  307.     int fps=60;
  308.     typedef struct START
  309.     {
  310.         short x;
  311.         short y;
  312.         short speed;
  313.         unsigned char speedcount;
  314.         unsigned char isexist;
  315.     } Star;

  316.     Star star[128]= {0};
  317.     srand(2);
  318.     for(i=0; i<128; i++)
  319.     {
  320.         if(star[i].isexist==0)
  321.         {
  322.             //设置128个()星星的初始信息
  323.             star[i].x=rand()%127;                //随机生成初始x坐标
  324.             star[i].y=rand()%64;                //随机生成y的坐标
  325.             star[i].speedcount=0;
  326.             star[i].speed=rand()%8+1;        //1-8的数
  327.             star[i].isexist=1;
  328.         }
  329.     }
  330.     while(1)
  331.     {
  332.         if(FrameRateUpdateScreen(fps)==1)        //在此函数中定时刷新屏
  333.         {
  334.             count++;
  335.             if(count>=fps*10)                           //10秒钟时间到达之后跳出循环结束动画
  336.                 return;
  337.         }

  338.         //此段函数一直在运行
  339.         //依次画出128个星星
  340.         for(i=0; i<128; i++)
  341.         {
  342.             //如果这一个星星已经移动到退出屏幕界面
  343.             //则在最左侧重新生成一颗新星星
  344.             if(star[i].isexist==0)
  345.             {
  346.                 star[i].x=0;
  347.                 star[i].y=rand()%64;
  348.                 star[i].speed=rand()%6+1;
  349.                 star[i].speedcount=0;
  350.                 star[i].isexist=1;
  351.             }
  352.             else
  353.             {
  354.                 star[i].speedcount++;
  355.                 if(star[i].x>=124)                        //标记已经退出屏幕
  356.                     star[i].isexist=0;

  357.                 //清除上一个时刻画的星星(的尾巴) 不管有没有操作 都进行清除操作
  358.                 SetDrawColor(pix_black);
  359.                 DrawLine(star[i].x,star[i].y,star[i].x,star[i].y);

  360.                 SetDrawColor(pix_white);
  361.                 if(star[i].speedcount==star[i].speed)        //运行时间到了一定的长度
  362.                 {
  363.                     star[i].speedcount=0;                                //复位运行时间并向右移一格
  364.                     star[i].x+=1;                                                //总之星星的结束需要在这经历124次
  365.                 }                                                                                //只不过有的更快 就能移动更快
  366.                 //从头到尾画出整条星星 不管星星是否已经变化
  367.                 DrawLine(star[i].x, star[i].y, star[i].x+(6/star[i].speed)-1, star[i].y);
  368.             }
  369.         }
  370.     }
  371. }


  372. //时钟动画
  373. //钟 小时 分钟 秒,
  374. void RoundClock(int hours,int minute,int sec)
  375. {
  376.     unsigned char i=0;
  377.     TypeXY hourspoint,minutepoint,secpoint,tmp1,tmp2;

  378.     //时针
  379.     SetRotateValue(63,31,hours*30+(minute*30)/60,1);
  380.     hourspoint=GetRotateXY(63-14,31);
  381.     DrawLine(63,31,hourspoint.x,hourspoint.y);
  382.     //分针
  383.     SetRotateValue(63,31,minute*6+(sec*6)/60,1);
  384.     minutepoint=GetRotateXY(63-21,31);
  385.     DrawLine(63,31,minutepoint.x,minutepoint.y);
  386.     //秒针
  387.     SetRotateValue(63,31,sec*6,1);
  388.     secpoint=GetRotateXY(63-28,31);
  389.     DrawLine(63,31,secpoint.x,secpoint.y);
  390.     //表盘
  391.     for(i=0; i<12; i++)
  392.     {
  393.         SetRotateValue(63,31,i*30,1);
  394.         tmp1=GetRotateXY(63-29,31);
  395.         tmp2=GetRotateXY(63-24,31);
  396.         DrawLine(tmp1.x,tmp1.y,tmp2.x,tmp2.y);
  397.     }
  398.     DrawFillCircle(63,31,2);
  399.     DrawCircle(63,31,30);
  400.     UpdateScreen();
  401.         DelayMs(25);
  402.     ClearScreen();
  403. }

  404. void ShowWatch(void)
  405. {
  406.     int i,j,z;
  407.     int count=0;

  408.     for(i=0; i<12; i++)
  409.         for(j=0; j<60; j++)
  410.             for(z=0; z<60; z++)
  411.             {
  412.                 RoundClock(i,j,z);
  413.                 count++;
  414.                 if(count>=800)
  415.                     return;
  416.             }
  417. }

  418. /
  419. //多边形动画
  420. void ShowPolygon(void)
  421. {
  422.     int x0=63,y0=31;                //正多边形的外接圆的圆心
  423.     unsigned char i =0,j;
  424.     int n=1,r=31;                        //画正n边形 大小半径31
  425.     int v=1,count=0;                //每个相邻的多边形隔1 画count次后退出
  426.     int x[30],y[30];

  427.     while(1)
  428.     {
  429.         ClearScreen();
  430.         for(i=0; i<n; i++)
  431.         {
  432.             x[i]=r*cos(2*3.1415926*i/n)+x0;
  433.             y[i]=r*sin(2*3.1415926*i/n)+y0;
  434.         }
  435.         for(i=0; i<=n-2; i++)
  436.         {
  437.             for(j=i+1; j<=n-1; j++)
  438.                 DrawLine(x[i],y[i],x[j],y[j]);
  439.         }
  440.         n+=v;
  441.         if(n==20||n==0)
  442.             v=-v;

  443.         UpdateScreen();
  444.                 DelayMs(25);                //延时停顿100ms
  445.         if(++count==90)
  446.         {
  447.             count=0;
  448.             return ;
  449.         }
  450.     }
  451. }

  452. //下雪的函数 和星空类似
  453. void ShowSnow(void)
  454. {
  455.     int a[66],i,num=0;
  456.     int count=0;
  457.     int fps=60;
  458.     struct Snow
  459.     {
  460.         short x;
  461.         short y;
  462.         short speed;
  463.     } snow[100];

  464.     srand(1);
  465.     for(i=0; i<66; i++)
  466.         a[i]=(i-2)*10;
  467.     ClearScreen();
  468.     while(1)
  469.     {
  470.         if(FrameRateUpdateScreen(fps)==1)        //在此函数中定时刷新屏
  471.         {
  472.             count++;
  473.             if(count>=fps*10)                           //10秒钟时间到达之后跳出循环结束动画
  474.                 return;
  475.         }
  476.         if(num!=100)
  477.         {
  478.             snow[num].speed=1+rand()%4;
  479.             i=rand()%66;
  480.             snow[num].x=a[i];
  481.             snow[num].y=0;
  482.             num++;
  483.         }
  484.         for(i=0; i<num; i++)
  485.         {
  486.             snow[i].y+=snow[i].speed;
  487.             DrawPixel(snow[i].x,snow[i].y+1);
  488.             DrawPixel(snow[i].x+1,snow[i].y);
  489.             DrawPixel(snow[i].x,snow[i].y);
  490.             DrawPixel(snow[i].x-1,snow[i].y);
  491.             DrawPixel(snow[i].x,snow[i].y-1);
  492.             if(snow[i].y>63)
  493.             {
  494.                 snow[i].y=0;
  495.             }
  496.         }
  497.         UpdateScreen();
  498.                 DelayMs(25);
  499.         ClearScreen();
  500.     }
  501. }


 楼主| wangtaohui 发表于 2023-6-28 20:24 | 显示全部楼层
在main.c文件中包含必要的头文件
  1. //...
  2. #include "main.h"

  3. /* Private includes ----------------------------------------------------------*/
  4. /* USER CODE BEGIN Includes */
  5. #include "../Delay/Delay.h"
  6. #include "../oledlib/draw_api.h"
  7. /* USER CODE END Includes */
  8. //...
 楼主| wangtaohui 发表于 2023-6-28 20:24 | 显示全部楼层
添加初始化函数并测试demo
  1. //...
  2.   /* USER CODE BEGIN 2 */
  3.   delay_init();
  4.   InitGraph();
  5.   /* USER CODE END 2 */

  6.   /* Infinite loop */
  7.   /* USER CODE BEGIN WHILE */
  8.   while (1)
  9.   {
  10.     /* USER CODE END WHILE */

  11.     /* USER CODE BEGIN 3 */
  12.         void demo(void);
  13.         demo();
  14.   }
  15.   /* USER CODE END 3 */
  16. //...
 楼主| wangtaohui 发表于 2023-6-28 20:25 | 显示全部楼层
效果如下
13750649c269aed0d1.png
58282649c26a178170.png
9794649c26a99642c.png
 楼主| wangtaohui 发表于 2023-6-28 20:25 | 显示全部楼层
结论
相比于普通的硬件IIC控制屏幕,改用DMA驱动后,刷新率得到了很大提升。其速度提升的原理为《STM32 DMA-IIC刷新OLED屏(理论可达42+帧率)》
星辰大海不退缩 发表于 2023-6-30 09:30 | 显示全部楼层
看来还是HAL库更方便配置
Undshing 发表于 2023-7-1 23:08 | 显示全部楼层
hal库配置起来就是快
Jacquetry 发表于 2023-7-6 23:48 | 显示全部楼层
显示效果很不错
mmbs 发表于 2023-7-9 10:01 | 显示全部楼层
使用HAL库函数,配置DMA控制器以实现DMA传输。 可以将DMA配置为从内存到外设的传输模式,以便在发送数据时减少CPU的负载。
hearstnorman323 发表于 2023-7-9 14:38 | 显示全部楼层
要使用HAL硬件IIC和DMA控制OLED,并使用简单图形库进行操作
cemaj 发表于 2023-7-9 16:57 | 显示全部楼层
使用 DMA 控制器,控制数据传输,从而减少单片机的工作负担,提高数据传输速度和效率。
MessageRing 发表于 2023-7-9 22:52 | 显示全部楼层
DMA会提高多少帧啊?
xiaoyaodz 发表于 2023-7-10 22:13 | 显示全部楼层
使用 HAL 硬件 IIC 函数库,控制 IIC 总线的数据传输,例如发送数据、接收数据等。
modesty3jonah 发表于 2023-7-11 22:32 | 显示全部楼层
实现DMA,在最初的时候,换用硬件IIC极其的方便,换到HAL库的接口函数就好了
lihuami 发表于 2023-7-14 13:59 | 显示全部楼层
使用HAL库来控制通过硬件IIC接口连接的OLED液晶屏,并结合DMA传输和简单图形库,可以实现高效的图形显示。
公羊子丹 发表于 2024-2-9 07:25 | 显示全部楼层

一般PCB是V-CUT,
万图 发表于 2024-2-9 08:28 | 显示全部楼层

可对电路进行一个防护效果
帛灿灿 发表于 2024-2-9 11:27 | 显示全部楼层

不会达到该电压
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部