STM32学习笔记——OLED屏

  OLED屏的特点:

    1.  模块有单色和双色可选,单色为纯蓝色,双色为黄蓝双色(本人选用双色);

    2.  显示尺寸为0.96寸

    3.  分辨率为128*64

    4.  多种接口方式,该模块提供了总共 5 种接口包括: 6800、 8080 两种并行接口方式、 3线或4线的SPI接口,IIC接口方式

    5.  不需要高压,直接接3.3V就可以工作;(可以与stm32的引脚直接相接)

   

  OLED图片:

    

  OLED引脚介绍:

    CS:OLED片选信号

    RST:OLED复位端口

    DC: 命令/数据选择端口(0:读写命令, 1: 读写数据)

    SCLK(D0):串口时钟线

    SDIN(D1): 串口数据线  

                              4线SPI写操作时序图:

          

    OLED的常用命令:

            

    设置OLED显示内存的寻址方式:

        设置的命令:

  0x00: 表示水平寻址方式

  0x01: 表示垂直寻址方式 

  0x10: 表示页寻址方式(默认方式)

     

  stm32与OLED屏接口的引脚介绍:

      CS————GPIOD3;

      RST————GPIOD4;

      DC—————GPIOD5;

      D0——————GPIOD6;

      D1——————GPIOD7;

   

  程序代码:

      1.   相关宏定义

  1. #define OLED_CS(X) X?GPIO_SetBits(GPIOD, GPIO_Pin_3):GPIO_ResetBits(GPIOD, GPIO_Pin_3) //X为1时对应GPIO端口输出高电平,X为0时对应GPIO端口输出低电平
  2.  
  3. #define OLED_RST(X) X?GPIO_SetBits(GPIOD, GPIO_Pin_4):GPIO_ResetBits(GPIOD, GPIO_Pin_4)
  4.  
  5. #define OLED_DC(X) X?GPIO_SetBits(GPIOD, GPIO_Pin_5):GPIO_ResetBits(GPIOD, GPIO_Pin_5)
  6.  
  7. #define OLED_D0(X) X?GPIO_SetBits(GPIOD, GPIO_Pin_6):GPIO_ResetBits(GPIOD, GPIO_Pin_6)
  8.  
  9. #define OLED_D1(X) X?GPIO_SetBits(GPIOD, GPIO_Pin_7):GPIO_ResetBits(GPIOD, GPIO_Pin_7)
  10.  
  11. #define OLED_Order 0     //定义写命令
  12. #define OLED_Data 1     //定义写数据

      2.  GPIO初始化代码:      

  1. void OLED_GPIO_Init(void)
  2. {
  3. GPIO_InitTypeDef GPIO_InitStruct;
  4.  
  5. //开启GPIOD的时钟
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
  7. //设置GPIO的基本参数
  8. GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  9. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  10. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //输出速度50MHz
  11.  
  12. GPIO_Init(GPIOD, &GPIO_InitStruct);
  13.  
  14. GPIO_SetBits(GPIOD, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7);
  15. }

    3. SPI 写数据/命令

  1. /* SPI写数据/命令
  2. * Mode :O:写命令 1:写数据
  3. * data :数据/命令
  4. *
  5. */
  6. void SPI_Write(char data, int Mode)
  7. {
  8. int i = ;
  9. if(Mode)
  10. {
  11. OLED_DC(); //DC引脚输入高,表示写数据
  12. }
  13. else
  14. {
  15. OLED_DC(); //DC引脚输入低,表示写命令
  16. }
  17. OLED_CS(); //CS引脚输入低,片选使能
  18. for(i = ; i < ; i++)
  19. {
  20. OLED_D0(); //D0引脚输入低
  21. if(data & 0x80) //判断传输的数据最高位为1还是0
  22. {
  23. OLED_D1(); //D1引脚输入高
  24. }
  25. else
  26. {
  27. OLED_D1(); //D1引脚输入低
  28. }
  29. OLED_D0(); //D1引脚输入高
  30. data <<= ; //将数据左移一位
  31. }
  32. OLED_DC(); //DC引脚输入低
  33. OLED_CS(); //CS引脚输入高,片选失能
  34. }

    4. 设置OLED屏的显示坐标:

      

    例如:设置页地址为0xB2; 列地址的低4位为0x03,列地址的高4位为0x00;则显示的位置如下图:

    代码:

  1. /* 设置OLED屏的显示坐标
  2. *    X : 表示OLED的水平坐标(0—127)
  3. *    Y : 表示OLED的页(0—7)
  4. *
  5. */
  6. void OLED_Coord(unsigned char x, unsigned char y)
  7. {
  8. SPI_Write((0xb0+(y & 0x0f)), OLED_Order); //设置OLED显示的页
  9. SPI_Write((((x & 0xf0)>>) | 0x10), OLED_Order);//设置OLED水平坐标的高4位
  10. SPI_Write((x & 0x0f)|0x01, OLED_Order); //设置OLED水平坐标的低4位
  11. }

    清除OLED的显示代码:

  1. /*
  2. * 清除OLED的显示
  3. *
  4. *
  5. */
  6. void OLED_Clear(void)
  7. {
  8. int i = , j = ;
  9. for(i = ; i < ; i++)
  10. {
  11. OLED_Coord(, i);
  12. for(j = ; j < ; j++)
  13. {
  14. SPI_Write(0x00, OLED_Data);
  15. }
  16. }
  17. }

      关闭OLED显示代码:

  1. /* 关闭OLED显示
  2. *
  3. *
  4. */
  5. void OLED_Display_Off(void)
  6. {
  7. //电荷泵设置(初始化时必须打开,否则看不到显示)
  8. SPI_Write(0x8D, OLED_Order);
  9. SPI_Write(0x10, OLED_Order);//bit2 0:关闭 1:打开
  10. SPI_Write(0xAE, OLED_Order);//0xAE:关闭显示
  11. }

      开启OLED显示代码:

  1. /*
  2. * 开启OLED显示
  3. *
  4. */
  5. void OLED_Display_On(void)
  6. {
  7. //电荷泵设置(初始化时必须打开,否则看不到显示)
  8. SPI_Write(0x8D, OLED_Order);
  9. SPI_Write(0x14, OLED_Order);//bit2 0:关闭 1:打开
  10. SPI_Write(0xAF, OLED_Order);//0xAF:开显示
  11. }

    OLED显示的参数的初始化:

      1. 在设置OLED的参数时,并不需要把所有的参数都设置一次;有些参数是默认的(可以不进行设置),只是需要设置一写必要的参数;

        (如:0xAF: 开显示, 0x8D:电荷泵设置(初始化是必须打开,否则看不到显示))

      2.代码(初始化代码中,介绍了大部分命令):

  1. /* OLED显示参数的初始化
  2. *
  3. *
  4. *
  5. */
  6. void OLED_Init(void)
  7. {
  8. OLED_GPIO_Init();
  9.  
  10. OLED_RST();
  11. delay_ms();
  12. OLED_RST();
  13. delay_ms();
  14. OLED_RST();
  15.  
  16. SPI_Write(0xAE, OLED_Order);//0xAE:关显示
  17.  
  18. SPI_Write(0x00, OLED_Order);//设置低列地址
  19. SPI_Write(0x10, OLED_Order);//设置高列地址
  20.  
  21. //设置行显示的开始地址(0-63)
  22. //40-47: (01xxxxx)
  23. SPI_Write(0x40, OLED_Order);
  24.  
  25. //设置对比度
  26. SPI_Write(0x81, OLED_Order);
  27. SPI_Write(0xff, OLED_Order);//这个值越大,屏幕越亮(和上条指令一起使用)(0x00-0xff)
  28.  
  29. SPI_Write(0xA1, OLED_Order);//0xA1: 左右反置, 0xA0: 正常显示(默认0xA0)
  30. SPI_Write(0xC8, OLED_Order);//0xC8: 上下反置, 0xC0: 正常显示(默认0xC0)
  31.  
  32. //0xA6: 表示正常显示(在面板上1表示点亮,0表示不亮)
  33. //0xA7: 表示逆显示(在面板上0表示点亮,1表示不亮)
  34. SPI_Write(0xA6, OLED_Order);
  35.  
  36. SPI_Write(0xA8, OLED_Order);//设置多路复用率(1-64)
  37. SPI_Write(0x3F, OLED_Order);//(0x01-0x3f)(默认为3f)
  38.  
  39. //设置显示抵消移位映射内存计数器
  40. SPI_Write(0xD3, OLED_Order);
  41. SPI_Write(0x00, OLED_Order);//(0x00-0x3f)(默认为0x00)
  42.  
  43. //设置显示时钟分频因子/振荡器频率
  44. SPI_Write(0xD5, OLED_Order);
  45. //低4位定义显示时钟(屏幕的刷新时间)(默认:0000)分频因子= [3:0]+1
  46. //高4位定义振荡器频率(默认:1000)
  47. SPI_Write(0x80, OLED_Order);//
  48.  
  49. //时钟预充电周期
  50. SPI_Write(0xD9, OLED_Order);
  51. SPI_Write(0xF1, OLED_Order);//[3:0],PHASE 1; [7:4] PHASE 2
  52.  
  53. //设置COM硬件应脚配置
  54. SPI_Write(0xDA, OLED_Order);
  55. SPI_Write(0x12, OLED_Order);//[5:4] 默认:01
  56.  
  57. SPI_Write(0xDB, OLED_Order);//
  58. SPI_Write(0x40, OLED_Order);//
  59.  
  60. //设置内存寻址方式
  61. SPI_Write(0x20, OLED_Order);
  62. //00: 表示水平寻址方式
  63. //01: 表示垂直寻址方式
  64. //10: 表示页寻址方式(默认方式)
  65. SPI_Write(0x02, OLED_Order);//
  66.  
  67. //电荷泵设置(初始化时必须打开,否则看不到显示)
  68. SPI_Write(0x8D, OLED_Order);
  69. SPI_Write(0x14, OLED_Order);//bit2 0:关闭 1:打开
  70.  
  71. //设置是否全部显示 0xA4: 禁止全部显示
  72. SPI_Write(0xA4, OLED_Order);
  73.  
  74. //0xA6: 表示正常显示(在面板上1表示点亮,0表示不亮)
  75. //0xA7: 表示逆显示(在面板上0表示点亮,1表示不亮)
  76. SPI_Write(0xA6, OLED_Order);//
  77.  
  78. SPI_Write(0xAF, OLED_Order);//0xAF:开显示
  79.  
  80. SPI_Write(0xAF, OLED_Order);//0xAF:开显示
  81.  
  82. OLED_Clear();
  83. }

      显示16*16的汉字函数代码:

  1. /* 显示汉字
  2. * x:表示显示的水平坐标
  3. * y: 表示显示的垂直坐标
  4. * *p: 表示要显示汉字模组的首地址
  5. */
  6. void OLED_ShowChinese(int x, int y, const unsigned char *p)
  7. {
  8. int i = ;
  9. OLED_Coord(x, y);
  10. for(i = ; i < ; i+=)
  11. {
  12. SPI_Write(p[i], OLED_Data);
  13. }
  14. OLED_Coord(x, y+);
  15. for(i = ; i < ; i+=)
  16. {
  17. SPI_Write(p[i], OLED_Data);
  18. }
  19. }

      显示ASCII码的函数代码:

  1. /* 显示ASCII
  2. * x:表示显示的水平坐标
  3. * y: 表示显示的垂直坐标
  4. * *p: 表示要显示汉字模组的首地址
  5. */
  6. void OLED_ShowChar(int x, int y, const unsigned char *p)
  7. {
  8. int i = ;
  9. OLED_Coord(x, y);
  10. for(i = ; i < ; i+=)
  11. {
  12. SPI_Write(p[i], OLED_Data);
  13. }
  14. OLED_Coord(x, y+);
  15. for(i = ; i < ; i+=)
  16. {
  17. SPI_Write(p[i], OLED_Data);
  18. }
  19. }

    注意1:在使用PCtoLCD2002完美版进行取模时,如果取模的字高大于8时一定要注意;

      如果字高16;取模的顺序是:从第一列开始,前8个点为第一个字节,后8个点为第二个字节

     然后第二列取模,前8个点为第三个字节,后8个点为第四个字节,以此类推,而OLED屏的内存

     寻址方式为0x10: 表示页寻址方式(默认方式)时,那么显示时将会乱码;因为是按页来显示的,

     那么第一个字节显示在第一列,而第二个字节本应该显示在第二页的第一列,而被错误的显示在第一页的第二列,以此类推,导致显示乱码;

      (这就是为什么OLED_ShowChar()函数和OLED_ShowChinese()函数中, 前面先显示数组下标为偶数的数组, 后面显示数组下标为奇数的数组)

    

    OLED显示的main函数代码:

  1. int main(void)
  2. {
  3. SysTick_Init();
  4. OLED_Init();
  5.  
  6. OLED_ShowChinese(, , xing);//‘姓’
  7. OLED_ShowChinese(, , ming);//‘名’
  8. OLED_ShowChar(, , ASCII_Colon);//‘:’
  9. OLED_ShowChinese(, , xue);//‘学’
  10. OLED_ShowChinese(, , hao);//‘号’
  11. OLED_ShowChar(, , ASCII_Colon);//‘:’
  12. // SPI_Write(0x2F, OLED_Order); //0x2F:激活滚动 0x2E:关闭滚动
  13. // //设置滚动方式:
  14. // // 0x26/0x27 :水平滚动(右向/左向)
  15. // // 0x29/0x2A :水平和垂直滚动(右向/左向)
  16. // // 0xA3 :垂直滚动
  17. // SPI_Write(0x27, OLED_Order);
  18. // SPI_Write(0x00, OLED_Order);
  19. // SPI_Write(0x00, OLED_Order);
  20. // SPI_Write(0x00, OLED_Order);
  21. // SPI_Write(0x03, OLED_Order);
  22. // SPI_Write(0x30, OLED_Order);
  23. while();

    注意:在使用滚动命令时,一定要先写入0x2F, 激活滚动

    取模数组:

  1. const unsigned char xing[]=
  2. { 0x10,0x40,0x10,0x22,0xF0,0x15,0x1F,0x08,
  3. 0x10,0x16,0xF0,0x21,0x40,0x40,0x3C,0x42,
  4. 0x10,0x42,0x10,0x42,0xFF,0x7F,0x10,0x42,
  5. 0x10,0x42,0x10,0x42,0x00,0x40,0x00,0x00};/*"姓",0*/
  6. const unsigned char A[]=
  7. { 0x00,0x20,0x00,0x3C,0xC0,0x23,0x38,0x02,
  8. 0xE0,0x02,0x00,0x27,0x00,0x38,0x00,0x20};/*"A",0*/
  9. const unsigned char ming[]=
  10. { 0x00,0x04,0x20,0x04,0x20,0x04,0x10,0x02,
  11. 0x08,0xFE,0x14,0x43,0x67,0x43,0x84,0x42,
  12. 0x44,0x42,0x24,0x42,0x14,0x42,0x0C,0x42,
  13. 0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00};/*"名",0*/
  14. const unsigned char ASCII_Colon[]=
  15. { 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,
  16. 0xC0,0x30,0x00,0x00,0x00,0x00,0x00,0x00};/*":",0*/
  17. const unsigned char xue[]=
  18. { 0x40,0x04,0x30,0x04,0x11,0x04,0x96,0x04,
  19. 0x90,0x04,0x90,0x44,0x91,0x84,0x96,0x7E,
  20. 0x90,0x06,0x90,0x05,0x98,0x04,0x14,0x04,
  21. 0x13,0x04,0x50,0x04,0x30,0x04,0x00,0x00};/*"学",0*/
  22. const unsigned char hao[]=
  23. { 0x80,0x00,0x80,0x00,0x80,0x00,0xBE,0x06,
  24. 0xA2,0x05,0xA2,0x04,0xA2,0x04,0xA2,0x04,
  25. 0xA2,0x44,0xA2,0x84,0xA2,0x44,0xBE,0x3C,
  26. 0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00};/*"号",0*/

      OLED的命令基本上已经在上面介绍,还有一些屏幕显示滚动的命令;本人没有进行一一实验;

   实验现象:

STM32学习笔记——OLED屏的更多相关文章

  1. STM32学习笔记——点亮LED

    STM32学习笔记——点亮LED 本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本: 先简单的介绍一下stm32的GPIO: stm32的GPIO有多种模式: 1 ...

  2. stm32学习笔记----双串口同时打开时的printf()问题

    stm32学习笔记----双串口同时打开时的printf()问题 最近因为要使用串口2外接PN532芯片实现通信,另一方面,要使用串口1来将一些提示信息输出到上位机,于是重定义了printf(),使其 ...

  3. stm32学习笔记——外部中断的使用

    stm32学习笔记——外部中断的使用 基本概念 stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个.比如说,PA0,PB0 ...

  4. STM32学习笔记(四)——串口控制LED(中断方式)

    目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...

  5. STM32学习笔记-NVIC中断知识点

    STM32学习笔记-NVIC中断知识点总结 中断优先级设置步骤 1. 系统运行后先设置中断优先级分组 函数:void NVIC_PriorityGroupConfig(uint32_tNVIC_Pri ...

  6. STM32学习笔记之一(初窥STM32)

    怎么做好学习笔记? 答:自我感知-->学习知识-->归纳总结-->自我升华(真正属于自己的知识是,抛开书本,运用时,你还能记得的思想) 自我感知--看到知识概念,先自我感觉那应该是个 ...

  7. STM32学习笔记(一)——点亮一个LED

    引言 最近报名了2017全国大学生电子设计竞赛,我们学校是第一次参加这个比赛,由于8/9月份就要比赛了,所以现在准备是比较晚的了,指导老师说只能做控制类的题目了,让我们学习一下STM32单片机,51到 ...

  8. STM32学习笔记——序言

    写AVR已经两年了.如果初中时候玩Arduino也算的话,就是6年. 两年以来,我用AVR单片机完成了两个大项目: AVR单片机教程,一时兴起写的,效果不好: MEDS,参赛用的课题,半完成,比赛都结 ...

  9. STM32学习笔记(二) 基于STM32-GPIO的流水灯实现

    学会了如何新建一个工程模板,下面就要开始动手实践了.像c/c++中经典的入门代码"hello world"一样,流水灯作为最简单的硬件设备在单片机领域也是入门首推.如果你已经有了一 ...

随机推荐

  1. asp.net文件下载文件另存为

    这是一个困惑已久的问题…… 首先,用<a>标签的href打开浏览器能解读的文件(如txt,jpg,pdf等),会自动打开,无法做到弹出另存为的效果. 其次,网上搜索了各种JS解决办法,包括 ...

  2. How to address this problem?

    root# cmake .. No problem. root# make [ 63%] Linking CXX shared module collisionperceptor.so/usr/bin ...

  3. 【python】闭包、@修饰符(装饰器)、

    闭包:(返回函数的行为叫闭包??) #函数也是对象,所以可以被传递 def line_conf(a,b): def line(x): return a*x+b return line line1=li ...

  4. 探索javascript----浅析js模块化

    引言: 鸭子类型: 面向对象的编程思想里,有一个有趣的概念,叫鸭子类型:“一只鸟走起来像鸭子.游起泳来像鸭子.叫起来也像鸭子,那它就可以被当做鸭子.也就是说,它不关注对象的类型,而是关注对象具有的行为 ...

  5. Git进行代码管理的心得

    git从网上下载安装后 直接可在开始菜单中找到 打开可以看到一个类似命令窗口的东西 用代码进行用户名和邮箱的设置 虽然不知道为什么但是教程叫我这么做 (ˇˍˇ) 然后似乎就可以用了 进入文件夹 输入对 ...

  6. 曲线参数化的Javascript实现(理论篇)

    在关键帧动画的制作过程中,动画师在k物体运动的过程中,一般要确定2个参数: 1)运动轨迹(表示物体运动的路径): 2)速度曲线(表示物体随时间的速度变化). 对于运动轨迹通常选用一定的样条曲线,通过动 ...

  7. mybatis配置log4j显示sql语句

    log4j.properties文件下: log4j.rootLogger=DEBUG, Console #Console log4j.appender.Console=org.apache.log4 ...

  8. java开发环境

    java开发环境搭建   文中主要内容来自:http://blog.csdn.net/cxwen78/article/details/6400798 .文章对原文有所改动. 1. 开发工具获取 开发工 ...

  9. ListView——android菜鸟成长之路

    ListView的基本用法 建博客这么久了,一直没能写点什么,其实一直想写来着,却又无从下手,今天终于下定决心写点什么,好吧,就ListView吧,这个控件是个搞基控件,所以初学者都会觉得很难,于是乎 ...

  10. Centeros7 环境相关问题

    服务处理命令 systemctl start mariadb #启动MariaDB systemctl stop mariadb #停止MariaDB systemctl restart mariad ...