STM32学习笔记——OLED屏

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
12 #define OLED_Order 0     //定义写命令
13 #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 = 0;
 9     if(Mode)
10     {
11         OLED_DC(1);        //DC引脚输入高,表示写数据
12     }
13     else
14     {
15         OLED_DC(0);        //DC引脚输入低,表示写命令
16     }
17     OLED_CS(0);            //CS引脚输入低,片选使能
18     for(i = 0; i < 8; i++)
19     {
20         OLED_D0(0);        //D0引脚输入低
21         if(data & 0x80)    //判断传输的数据最高位为1还是0
22         {
23             OLED_D1(1);    //D1引脚输入高
24         }
25         else
26         {
27             OLED_D1(0);    //D1引脚输入低
28         }
29         OLED_D0(1);        //D1引脚输入高
30         data <<= 1;        //将数据左移一位
31     }
32     OLED_DC(0);            //DC引脚输入高
33     OLED_CS(1);            //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)>>4) | 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 = 0, j = 0;
 9     for(i = 0; i < 8; i++)
10     {
11         OLED_Coord(0, i);
12         for(j = 0; j < 128; 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(1);
11     delay_ms(100);
12     OLED_RST(0);
13     delay_ms(100);
14     OLED_RST(1);
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     //设置显示抵消移位映射内存计数器
41     SPI_Write(0xD3, OLED_Order);
42     SPI_Write(0x00, OLED_Order);//(0x00-0x3f)(默认为0x00)
43
44     //设置显示时钟分频因子/振荡器频率
45     SPI_Write(0xD5, OLED_Order);
46     //低4位定义显示时钟(屏幕的刷新时间)(默认:0000)分频因子= [3:0]+1
47     //高4位定义振荡器频率(默认:1000)
48     SPI_Write(0x80, OLED_Order);//
49
50     //时钟预充电周期
51     SPI_Write(0xD9, OLED_Order);
52     SPI_Write(0xF1, OLED_Order);//[3:0],PHASE 1;   [7:4] PHASE 2
53
54     //设置COM硬件应脚配置
55     SPI_Write(0xDA, OLED_Order);
56     SPI_Write(0x12, OLED_Order);//[5:4]  默认:01
57
58     SPI_Write(0xDB, OLED_Order);//
59     SPI_Write(0x40, OLED_Order);//
60
61     //设置内存寻址方式
62     SPI_Write(0x20, OLED_Order);
63     //0x00: 表示水平寻址方式
64     //0x01: 表示垂直寻址方式
65     //0x10: 表示页寻址方式(默认方式)
66     SPI_Write(0x02, OLED_Order);//
67
68     //电荷泵设置(初始化时必须打开,否则看不到显示)
69     SPI_Write(0x8D, OLED_Order);
70     SPI_Write(0x14, OLED_Order);//bit2   0:关闭        1:打开
71
72     //设置是否全部显示 0xA4: 禁止全部显示
73     SPI_Write(0xA4, OLED_Order);
74
75     //0xA6: 表示正常显示(在面板上1表示点亮,0表示不亮)
76     //0xA7: 表示逆显示(在面板上0表示点亮,1表示不亮)
77     SPI_Write(0xA6, OLED_Order);//
78
79     SPI_Write(0xAF, OLED_Order);//0xAF:开显示
80
81     SPI_Write(0xAF, OLED_Order);//0xAF:开显示
82
83     OLED_Clear();
84 }

      显示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 = 0;
 9     OLED_Coord(x, y);
10     for(i = 0; i < 32; i+=2)
11     {
12         SPI_Write(p[i], OLED_Data);
13     }
14     OLED_Coord(x, y+1);
15     for(i = 1; i < 32; i+=2)
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 = 0;
 9     OLED_Coord(x, y);
10     for(i = 0; i < 16; i+=2)
11     {
12         SPI_Write(p[i], OLED_Data);
13     }
14     OLED_Coord(x, y+1);
15     for(i = 1; i < 16; i+=2)
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(0, 0, xing);//‘姓’
 7     OLED_ShowChinese(18, 0, ming);//‘名’
 8     OLED_ShowChar(36, 0, ASCII_Colon);//‘:’
 9     OLED_ShowChinese(0, 2, xue);//‘学’
10     OLED_ShowChinese(18, 2, hao);//‘号’
11     OLED_ShowChar(36, 2, 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(1);

    注意:在使用滚动命令时,一定要先写入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的命令基本上已经在上面介绍,还有一些屏幕显示滚动的命令;本人没有进行一一实验;

时间: 2024-08-02 19:22:55

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

STM32学习笔记——USART串口(向原子哥和火哥学习)

一.USART简介 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换.USART利用分数波特率发生器提供宽范围的波特率选择. STM32 的串口资源相当丰富的,功能也相当强劲.STM32F103ZET6 最多可提供 5 路串口,有分数波特率发生器,支持同步单向通信和半双工单线通信,支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作.它还允许多处理器通信.

STM32学习笔记6(TIM通用模块生成PWM)

1.     TIMER输出PWM基本概念   脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术.简单一点,就是对脉冲宽度的控制.一般用来控制步进电机的速度等等. STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出. 1.1   PWM输出模式 S

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

目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类型并使能串口中断 七.编写中断服务函数函数名格式为函数名格式为 USARTxIRQHandler(x 对应串口号). 八.主函数的实现. 一.时钟使能,包括GPIO的时钟和串口的时钟使能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //

STM32学习笔记4(TIM32位定时器的实现)

关于STM32的CPU为32位,定时器却为16位的探讨 STM32的通用定时器可以实现很多功能,例如:定时计数.测量外部信号脉冲宽度.产生PWM波形.测量输入的PWM波形等.在所有这些操作中,定时器的位数主要影响两个参数,一个是定时或测量的精度,另一个是定时的时间长度.下面我们以一个列表看一下定时的精度和定时的长度有多少: 关于各个预分频器的作用请参考下图的右半部分: 从表中可以看出,在最高精度下(14ns)定时长度只有0.91ms,在精度为250ns(即4MHz)时定时长度可达16.38ms.

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

怎么做好学习笔记? 答:自我感知-->学习知识-->归纳总结-->自我升华(真正属于自己的知识是,抛开书本,运用时,你还能记得的思想) 自我感知--看到知识概念,先自我感觉那应该是个什么东西(如:寄存器---寄存东西(数据)的地方嘛) 学习知识--有了自我感知后,就需要验证自己的感知是否正确,请记住,带着自己思想的学习是最高效的学习(如:寄存器---存什么东西呢?) 归纳总结--学习了大量知识后,就该汇总汇总了(如:寄存器---存数据(通用寄存器),存命令(PC),存地址(LR)) 自我

stm32学习笔记之win8系统下,keil4出现黑块的解决方法

前不久,笔者安装keil4启动会出现黑块,如图所示 当时询问了不少技术群都没有找到解决办法,并且还在百度贴吧发贴,最终都无果而终 这是当时发贴地址 http://tieba.baidu.com/p/3176578044 后来重做了个系统,才勉强能使用.直至今天又出现了同样的状况.在此之间笔者发现当keil4出现黑块,win8自带的记事本也会出现未响应状况,于是上网找解决方法,最终网友 oafaq给了我思路 这是他的原文地址 http://blog.sina.com.cn/key9928 .原来我

STM32学习笔记——点亮LED

STM32学习笔记——点亮LED 本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本: 先简单的介绍一下stm32的GPIO: stm32的GPIO有多种模式: 1.输入浮空 2.输入上拉 3.输入下拉 4.模拟输入 5.开漏输出 6.推挽式输出 7.推挽式复用功能 8.开漏复用功能 stm32GPIO模式设置相关寄存器设置的介绍 stm32中文参考手册中对GPIO模式设置对应寄存器的详细介绍: 下图为开发板LED的接线图: 根据上面的电路图可知,将GPIOB

STM32学习笔记2——RC522

RC522的学习算下来也有四五天了,今天终于勉强知道大概是怎么一回事了,实现效果如图,大概总结如下: 一.RC522操作流程: 二.M1卡简单介绍: 1.16个扇区,每个扇区分四块 2.每个扇区的块0,1,2为数据块,块3为控制块 3.第0扇区块0为厂家固化,不能更改 三.M1卡的读写: 读和写都是一样的,先定义好读和写的存放数组,读是把块里的数据写入到空数组中,读是把事先赋值的数组的值写入到块中 unsigned char RFID[16];//读 Unsigned charRFID1[16]

STM32学习笔记1-软件安装

收到自己买的STM32F103ZE为主芯片的开发板,标志着我正式进入实践阶段,之前看了不少ARM的资料,都是零零散散的,也没有什么系统的总结,总觉得找到真正的感觉,就下决心买开发板,至于为什么选择STM32,很简单,适合自己.好了,废话少说,以下是我今天收到开发板后的学习总结. 由于还不清楚什么如何运作,就按照提供的资料的视频一步一步做: 第1步:上电检测开发板是否正常. 第2步:安装驱动和软件. 驱动:JLINK驱动---用于仿真调试用. CH340驱动(USB串口驱动)-----用于开发板与