一 、OLED屏

1.OLED屏(七针)

2.OLED电路图

3.0.96'OLED简介

该模块特点:

1、三色可选,模块有两种单色和黄蓝双色两种颜色可选,单色为纯白色和纯蓝色,双

色为黄蓝双色;

2、超小尺寸,显示尺寸为 0.96 寸,模块尺寸为 27mm(长)*26mm(宽)*4mm(高);

3、高分辨率,分辨率为 128*64;

4、接口模式,4 线串行 SPI 接口模式;

5、带字库,可显示标准的国标简体(GB2312)汉字、8*16 点 ASCII 粗体字库、7*8

点 ASCII 字库、5*7 点 ASCII 字库。

6、兼容 3.3V~5V 电压。

二、GPIO模拟SPI

1.引脚定义

GND                      地

VCC                       电源,3.3V~5V

D0                         4 线 ISP 接口模式:时钟线(CLK) PA4

D1                         4 线 ISP 接口模式:串行数据线(MOSI)PA3

RES                        4 线 ISP 接口模式:命令/数据标志位(RET复位)PA2

DC                        命令/数据标志位 A1

CS                        OLED 片选

2.时序图

模块只支持向模块写数据不能读数据

所以只需要写SPI发送即可

3.程序

"SPI.h"


  1. #define OLED_CMD 0 //命令声明
  2. #define OLED_DATA 1 //数据声明
  3. #define OLED_CLK PAout(4) // CLK时钟 d0
  4. #define OLED_MOSI PAout(3) // MOSI d1
  5. #define OLED_RST PAout(2) // RET复位 ret
  6. #define OLED_DC PAout(1) // 命令|数据 dc (0表传输命令1表传输数据)
  7. void OLED_SPI_Init(void); //配置MCU的SPI
  8. void SPI_WriteByte(uint8_t addr,uint8_t data); //向寄存器地址写一个byte的数据
  9. void WriteCmd(unsigned char cmd); //写命令
  10. void WriteDat(unsigned char data); //写数据

"SPI.c"

  1. /*************************************************************************/
  2. /*函数功能: GPIO模拟SPI端口初始化 */
  3. /*************************************************************************/
  4. void OLED_SPI_Init(void)
  5. {
  6. GPIO_InitTypeDef GPIO_InitStructure;
  7. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);//使能PA端口时钟
  8. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //端口配置
  9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
  10. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度为50MHz
  11. GPIO_Init(GPIOA,&GPIO_InitStructure);//根据设定参数初始化GPIOA
  12. }
  13. /*************************************************************************/
  14. /*函数功能: 通过SPIO软件模拟SPI通信协议,向模块(SSD1306)写入一个字节 */
  15. /*入口参数: */
  16. /* data:要写入的数据/命令 */
  17. /* cmd :数据/命令标志 0,表示命令;1,表示数据; */
  18. /*************************************************************************/
  19. void SPI_WriteByte(unsigned char data,unsigned char cmd)
  20. {
  21. unsigned char i=0;
  22. OLED_DC =cmd;
  23. OLED_CLK=0;
  24. for(i=0;i<8;i++)
  25. {
  26. OLED_CLK=0;
  27. if(data&0x80)OLED_MOSI=1; //从高位到低位
  28. else OLED_MOSI=0;
  29. OLED_CLK=1;
  30. data<<=1;
  31. }
  32. OLED_CLK=1;
  33. OLED_DC=1;
  34. }
  35. /*************************************************************************/
  36. /*函数功能: 写命令 */
  37. /*************************************************************************/
  38. void WriteCmd(unsigned char cmd)
  39. {
  40. SPI_WriteByte(cmd,OLED_CMD);
  41. }
  42. /*************************************************************************/
  43. /*函数功能: 写数据 */
  44. /*************************************************************************/
  45. void WriteData(unsigned char data)
  46. {
  47. SPI_WriteByte(data,OLED_DATA);
  48. }

4.SSD1306的命令

1.SSD1306显存为128*64bit大小, SSD1306将全部显存分为8页,每页128字节

2.ssd1306命令

  1. 0:OLED设置对比度
  2. 发送两个字节
  3. 第一个字节为命令-0x81
  4. 第二个字节为设置对比度值,值越大屏幕越亮(0X00-0XFF)
  5. 1:关闭/开启OLED显示
  6. 发送一个命令字节,高七位固定,最低位X0=0关闭显示,X0=1开启显示
  7. 0xAE:关闭显示
  8. 0xAF:开启显示
  9. 2:关闭/开启电荷泵
  10. 发送两个字节
  11. 第一个字节为命令-0x8D
  12. 第二个字节为设置电荷泵开关
  13. 0,1,4,5,6固定,位67随意,位2控制电荷泵开关
  14. A2=0关闭电荷泵
  15. A2=1开启电荷泵
  16. 注意:在模块初始化时,必须开启,否则看不到屏幕显示
  17. 3:0xB0-0xB7 设置页地址
  18. 发送一个字节,高5位固定
  19. 0-位2 , X[2:0]共3位, 值范围0-7对应页0-7地址(共8页)
  20. 4:0x00-0x0F设置列地址起始低四位
  21. 高四位固定
  22. 低四位设置列地址起始低四位
  23. 5:0x10-0x1F设置列地址起始高四位
  24. 高四位固定
  25. 低四位设置列地址起始高四

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

"OLED.h"

  1. void OLED_Init(void);//初始化OLED
  2. void OLED_ON(void);//唤醒OLED
  3. void OLED_OFF(void);//OLED休眠
  4. void OLED_Refresh_Gram(void);//更新显存到OLED
  5. void OLED_Clear(void);//清屏
  6. void OLED_DrawPoint(u8 x,u8 y,u8 t);//画点
  7. void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);//填充
  8. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode);//显示字符
  9. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);//显示2个数字
  10. void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size);//显示字符串

"OLED.c"

  1. //OLED的显存
  2. //存放格式如下.
  3. //[0]0 1 2 3 ... 127
  4. //[1]0 1 2 3 ... 127
  5. //[2]0 1 2 3 ... 127
  6. //[3]0 1 2 3 ... 127
  7. //[4]0 1 2 3 ... 127
  8. //[5]0 1 2 3 ... 127
  9. //[6]0 1 2 3 ... 127
  10. //[7]0 1 2 3 ... 127
  11. u8 OLED_GRAM[128][8];
  12. /*************************************************************************/
  13. /*函数功能: 软延时 */
  14. /*************************************************************************/
  15. void OLED_DLY_ms(unsigned int ms)
  16. {
  17. unsigned int a;
  18. while(ms)
  19. {
  20. a=1335;
  21. while(a--);
  22. ms--;
  23. }
  24. }
  25. /*************************************************************************/
  26. /*函数功能: 初始化OLED模块 */
  27. /*************************************************************************/
  28. void OLED_Init(void)
  29. {
  30. OLED_SPI_Init();
  31. OLED_CLK = 1;
  32. OLED_RST = 0;
  33. OLED_DLY_ms(100);
  34. OLED_RST = 1;
  35. //从上电到下面开始初始化要有足够的时间,即等待RC复位完毕
  36. WriteCmd(0xAE); // Display Off (0x00)
  37. WriteCmd(0xD5);
  38. WriteCmd(0x80); // Set Clock as 100 Frames/Sec
  39. WriteCmd(0xA8);
  40. WriteCmd(0x3F); // 1/64 Duty (0x0F~0x3F)
  41. WriteCmd(0xD3);
  42. WriteCmd(0x00); // Shift Mapping RAM Counter (0x00~0x3F)
  43. WriteCmd(0x40 | 0x00); // Set Mapping RAM Display Start Line (0x00~0x3F)
  44. WriteCmd(0x8D);
  45. WriteCmd(0x10 | 0x04); // Enable Embedded DC/DC Converter (0x00/0x04)
  46. WriteCmd(0x20);
  47. WriteCmd(0x02); // Set Page Addressing Mode (0x00/0x01/0x02)
  48. WriteCmd(0xA0 | 0x01); // Set SEG/Column Mapping
  49. WriteCmd(0xC0); // Set COM/x Scan Direction
  50. WriteCmd(0xDA);
  51. WriteCmd(0x02 | 0x10); // Set Sequential Configuration (0x00/0x10)
  52. WriteCmd(0x81);
  53. WriteCmd(0xCF); // Set SEG Output Current
  54. WriteCmd(0xD9);
  55. WriteCmd(0xF1); // Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  56. WriteCmd(0xDB);
  57. WriteCmd(0x40); // Set VCOM Deselect Level
  58. WriteCmd(0xA4 | 0x00); // Disable Entire Display On (0x00/0x01)
  59. WriteCmd(0xA6 | 0x00); // Disable Inverse Display On (0x00/0x01)
  60. WriteCmd(0xAE | 0x01); // Display On (0x01)
  61. OLED_Clear(); //初始清屏
  62. }
  63. /*************************************************************************/
  64. /*函数功能: 将OLED从休眠中唤醒 */
  65. /*************************************************************************/
  66. void OLED_ON(void)
  67. {
  68. WriteCmd(0X8D); //设置电荷泵
  69. WriteCmd(0X14); //开启电荷泵
  70. WriteCmd(0XAF); //OLED唤醒
  71. }
  72. /*************************************************************************/
  73. /*函数功能: 将OLED休眠 -- 休眠模式下,OLED功耗不到10uA */
  74. /*************************************************************************/
  75. void OLED_OFF(void)
  76. {
  77. WriteCmd(0X8D); //设置电荷泵
  78. WriteCmd(0X10); //关闭电荷泵
  79. WriteCmd(0XAE); //OLED休眠
  80. }
  81. /*************************************************************************/
  82. /*函数功能: 更新显存到OLED */
  83. /*************************************************************************/
  84. void OLED_Refresh_Gram(void)
  85. {
  86. u8 i,n;
  87. for(i=0;i<8;i++)
  88. {
  89. WriteCmd(0xb0+i); //设置页地址(0~7)
  90. WriteCmd(0x00); //设置显示位置—列低地址
  91. WriteCmd(0x10); //设置显示位置—列高地址
  92. for(n=0;n<128;n++)WriteData(OLED_GRAM[n][i]);
  93. }
  94. }
  95. /*************************************************************************/
  96. /*函数功能: 清屏 */
  97. /*************************************************************************/
  98. void OLED_Clear(void)
  99. {
  100. u8 i,n;
  101. for(i=0;i<8;i++)for(n=0;n<128;n++)OLED_GRAM[n][i]=0X00;
  102. OLED_Refresh_Gram();//更新显示
  103. }
  104. /*************************************************************************/
  105. /*函数功能: 画点 */
  106. /*入口参数: */
  107. /* x:横坐标 0~127 */
  108. /* y:纵坐标 0~63 */
  109. /* dot:0,清空;1,填充 */
  110. /*************************************************************************/
  111. void OLED_DrawPoint(u8 x,u8 y,u8 t)
  112. {
  113. u8 pos,bx,temp=0;
  114. if(x>127||y>63)return;//超出范围了.
  115. pos=7-y/8;
  116. bx=y%8;
  117. temp=1<<(7-bx);
  118. if(t)OLED_GRAM[x][pos]|=temp;
  119. else OLED_GRAM[x][pos]&=~temp;
  120. }
  121. /*************************************************************************/
  122. /*函数功能: 填充 */
  123. /*入口参数: */
  124. /* x1,y1,x2,y2 填充区域的对角坐标 */
  125. /* 确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63 */
  126. /* dot:0,清空;1,填充 */
  127. /*************************************************************************/
  128. void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot)
  129. {
  130. u8 x,y;
  131. for(x=x1;x<=x2;x++)
  132. {
  133. for(y=y1;y<=y2;y++)OLED_DrawPoint(x,y,dot);
  134. }
  135. OLED_Refresh_Gram();//更新显示
  136. }
  137. /*************************************************************************/
  138. /*函数功能: 在指定位置显示一个字符,包括部分字符 */
  139. /*入口参数: */
  140. /* x:0~12 */
  141. /* y:0~63 */
  142. /* mode:0,反白显示;1,正常显示 */
  143. /* size:选择字体 16/12 */
  144. /*************************************************************************/
  145. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
  146. {
  147. u8 temp,t,t1;
  148. u8 y0=y;
  149. u8 csize=(size/8+((size%8)?1:0))*(size/2); //得到字体一个字符对应点阵集所占的字节数
  150. chr=chr-' ';//得到偏移后的值
  151. for(t=0;t<csize;t++)
  152. {
  153. if(size==12)temp=asc2_1206[chr][t]; //调用1206字体
  154. else if(size==16)temp=asc2_1608[chr][t]; //调用1608字体
  155. else if(size==24)temp=asc2_2412[chr][t]; //调用2412字体
  156. else return; //没有的字库
  157. for(t1=0;t1<8;t1++)
  158. {
  159. if(temp&0x80)OLED_DrawPoint(x,y,mode);
  160. else OLED_DrawPoint(x,y,!mode);
  161. temp<<=1;
  162. y++;
  163. if((y-y0)==size)
  164. {
  165. y=y0;
  166. x++;
  167. break;
  168. }
  169. }
  170. }
  171. }
  172. //m^n函数
  173. u32 mypow(u8 m,u8 n)
  174. {
  175. u32 result=1;
  176. while(n--)result*=m;
  177. return result;
  178. }
  179. /*************************************************************************/
  180. /*函数功能: 显示2个数字 */
  181. /*入口参数: */
  182. /* x,y :起点坐标 */
  183. /* len :数字的位数 */
  184. /* size:字体大小 */
  185. /* mode:模式 0,填充模式;1,叠加模式 */
  186. /* num:数值(0~4294967295) */
  187. /*************************************************************************/
  188. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)
  189. {
  190. u8 t,temp;
  191. u8 enshow=0;
  192. for(t=0;t<len;t++)
  193. {
  194. temp=(num/mypow(10,len-t-1))%10;
  195. if(enshow==0&&t<(len-1))
  196. {
  197. if(temp==0)
  198. {
  199. OLED_ShowChar(x+(size/2)*t,y,' ',size,1);
  200. continue;
  201. }else enshow=1;
  202. }
  203. OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1);
  204. }
  205. }
  206. /*************************************************************************/
  207. /*函数功能: 显示字符串 */
  208. /*入口参数: */
  209. /* x,y:起点坐标 */
  210. /* size:字体大小 */
  211. /* *p:字符串起始地址 */
  212. /*************************************************************************/
  213. void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size)
  214. {
  215. while((*p<='~')&&(*p>=' '))//判断是不是非法字符!
  216. {
  217. if(x>(128-(size/2))){x=0;y+=size;}
  218. if(y>(64-size)){y=x=0;OLED_Clear();}
  219. OLED_ShowChar(x,y,*p,size,1);
  220. x+=size/2;
  221. p++;
  222. }
  223. }

OLED的使用-4线SPI驱动的更多相关文章

  1. STM32—4线SPI驱动SSD1306 OLED

    文章目录 一.OLED简介 二.驱动SSD1306所需知识 1.引脚介绍 2.通信时序 3.显存GRAM 4.字库 5.SSD1306基本命令 三.代码讲解 1.相关引脚配置 2.模拟SPI通信 3. ...

  2. 联盛德 HLK-W806 (八): 4线SPI驱动SSD1306/SSD1315 128x64 OLED液晶屏

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  3. 联盛德 HLK-W806 (九): 软件SPI和硬件SPI驱动ST7789V液晶LCD

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  4. 联盛德 HLK-W806 (十一): 软件SPI和硬件SPI驱动ST7567液晶LCD

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  5. 基于TQ2440的SPI驱动学习(OLED)

    平台简介 开发板:TQ2440 (NandFlash:256M  内存:64M) u-boot版本:u-boot-2015.04 内核版本:Linux-3.14 作者:彭东林 邮箱:pengdongl ...

  6. spi驱动框架全面分析,从master驱动到设备驱动

    内核版本:linux2.6.32.2  硬件资源:s3c2440 参考:  韦东山SPI视频教程 内容概括:     1.I2C 驱动框架回顾     2.SPI 框架简单介绍     3.maste ...

  7. STC8H开发(十): SPI驱动Nokia5110 LCD(PCD8544)

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  8. linux驱动基础系列--linux spi驱动框架分析

    前言 主要是想对Linux 下spi驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型等也不进行详细说明原理.如果有任何错误地方,请指出,谢谢! spi ...

  9. [转载]Linux驱动-SPI驱动-概述

    转载地址http://blog.csdn.net/droidphone SPI是"Serial Peripheral Interface" 的缩写,是一种四线制的同步串行通信接口, ...

随机推荐

  1. MySQL show命令的用法

    show tables或show tables from database_name; // 显示当前数据库中所有表的名称 show databases; // 显示mysql中所有数据库的名称 sh ...

  2. 牛奶别乱喝6种最好最差牛奶PK

    ​ 牛奶被认为是最健康的一种食材,而且牛奶柔滑的口感和味道让地球上的每一个人都爱不释口.随着现代工业的发展,牛奶也被加工成各种各样的制品,即便是牛奶本身也有着无数的选择,那么究竟什么样的牛奶好.什么样 ...

  3. SpringMVC 使用注解完成登录拦截

    目录 为了实现用户登录拦截你是否写过如下代码呢? 1. 基于Filter 2. 基于Struts 3. 基于SpringMVC 如何使用自定义注解完成自定义拦截呢? 登录注解 SpringMVC 拦截 ...

  4. Spark基础全解析

    我的个人博客:https://www.luozhiyun.com/ 为什么需要Spark? MapReduce的缺陷 第一,MapReduce模型的抽象层次低,大量的底层逻辑都需要开发者手工完成. 第 ...

  5. P1102 A-B 数对

    P1102题库链接:https://www.luogu.org/problem/P1102 难度:普及- 算法标签:模拟,数论,排序,HASH,概率论,二分查找 1.朴素 O(n^2) 得分76 将输 ...

  6. python列表解析补充:

    python列表解析补充: # 补充: f = [x + y for x in 'ABCDE' for y in '1234567'] print(f) test = [] for x in 'ABC ...

  7. node跨域方法

    第一种:jsonp 参看用nodejs实现json和jsonp服务 第二种:res.wirteHeadnode部分 var http = require('http') var url = requi ...

  8. Bootstrap4 正式发布

    历经三年开发,前端框架Bootstrap 4正式发布了.然而今天的Web世界已经和当初Mark Otto发布Bootstrap时的情况大为不同,一些开发者由此质疑它的更新是否还有意义 1.V4版本的主 ...

  9. spring boot actuator服务监控与管理

    1.引入actuator所需要的jar包 <dependency> <groupId>org.springframework.boot</groupId> < ...

  10. web前端问题整理

    1.常用那几种浏览器测试?有哪些内核(Layout Engine)? (Q1)浏览器:IE,Chrome,FireFox,Safari,Opera (Q2)内核:Trident,Gecko,Prest ...