oled的一套stm32实验1
详细的oled介绍:http://blog.sina.com.cn/s/blog_57ad1bd20102wtq8.html
整理自:https://www.cnblogs.com/wp2312139418/p/5988713.html
应该可以直接运行了。
stm32与OLED屏接口的引脚介绍:
CS————GPIOD3;
RST————GPIOD4;
DC—————GPIOD5;
D0——————GPIOD6;
D1——————GPIOD7;
OLED引脚介绍:
CS:OLED片选信号
RST:OLED复位端口
DC: 命令/数据选择端口(0:读写命令, 1: 读写数据)
SCLK(D0):串口时钟线
SDIN(D1): 串口数据线
估计电荷泵的作用是为了得到更好的显示效果。
相关宏定义:
#define OLED_CS(X) X?GPIO_SetBits(GPIOD, GPIO_Pin_3):GPIO_ResetBits(GPIOD, GPIO_Pin_3) //X为1时对应GPIO端口输出高电平,X为0时对应GPIO端口输出低电平
#define OLED_RST(X) X?GPIO_SetBits(GPIOD, GPIO_Pin_4):GPIO_ResetBits(GPIOD, GPIO_Pin_4)
#define OLED_DC(X) X?GPIO_SetBits(GPIOD, GPIO_Pin_5):GPIO_ResetBits(GPIOD, GPIO_Pin_5)
#define OLED_D0(X) X?GPIO_SetBits(GPIOD, GPIO_Pin_6):GPIO_ResetBits(GPIOD, GPIO_Pin_6)
#define OLED_D1(X) X?GPIO_SetBits(GPIOD, GPIO_Pin_7):GPIO_ResetBits(GPIOD, GPIO_Pin_7)
#define OLED_Order 0 //定义写命令
#define OLED_Data 1 //定义写数据
gpio的初始化:
void OLED_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//开启GPIOD的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
//设置GPIO的基本参数
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; //这里就是连接oled的几个引脚
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //输出速度50MHz
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_SetBits(GPIOD, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7);
}
spi的构造
/* SPI写数据/命令
* Mode :O:写命令 1:写数据
* data :数据/命令
*
*/
void SPI_Write(char data, int Mode)
{
int i = 0;
if(Mode)
{
OLED_DC(1); //DC引脚输入高,表示写数据
}
else
{
OLED_DC(0); //DC引脚输入低,表示写命令
}
OLED_CS(0); //CS引脚输入低,片选使能
for(i = 0; i < 8; i++)
{
OLED_D0(0); //D0引脚输入低
if(data & 0x80) //判断传输的数据最高位为1还是0
{
OLED_D1(1); //D1引脚输入高
}
else
{
OLED_D1(0); //D1引脚输入低
}
OLED_D0(1); //D1引脚输入高
data <<= 1; //将数据左移一位
}
OLED_DC(0); //DC引脚输入低
OLED_CS(1); //CS引脚输入高,片选失能
}
/* 设置OLED屏的显示坐标
* X : 表示OLED的水平坐标(0—127) ,横着走
* Y : 表示OLED的页(0—7) ,竖着走
*
*/
void OLED_Coord(unsigned char x, unsigned char y)
{
SPI_Write((0xb0+(y & 0x0f)), OLED_Order); //设置OLED显示的页
SPI_Write((((x & 0xf0)>>4) | 0x10), OLED_Order);//设置OLED水平坐标的高4位 根据上面那张图分析,这是取x的高四位,
SPI_Write((x & 0x0f)|0x01, OLED_Order); //设置OLED水平坐标的低4位 至于为什么要|0x01,可能是为了防止太靠边。
}
/*
* 清除OLED的显示
* //从代码上来看,似乎是给每一个像素点都写一个0,,,一共写了 128*8次。,显然,y的值是8但是,应该是8*8=64个像素
* //也就是在写0x00 的时候是给纵向的8个像素点写了0,即上图中天蓝色的8个格子
*
*/
void OLED_Clear(void)
{
int i = 0, j = 0;
for(i = 0; i < 8; i++)
{
OLED_Coord(0, i);
for(j = 0; j < 128; j++)
{
SPI_Write(0x00, OLED_Data);
}
}
}
/* 关闭OLED显示
*
*
*/
void OLED_Display_Off(void)
{
//电荷泵设置(初始化时必须打开,否则看不到显示)
SPI_Write(0x8D, OLED_Order);
SPI_Write(0x10, OLED_Order);//bit2 0:关闭 1:打开
SPI_Write(0xAE, OLED_Order);//0xAE:关闭显示
}
/*
* 开启OLED显示
*
*/
void OLED_Display_On(void)
{
//电荷泵设置(初始化时必须打开,否则看不到显示)
SPI_Write(0x8D, OLED_Order);
SPI_Write(0x14, OLED_Order);//bit2 0:关闭 1:打开
SPI_Write(0xAF, OLED_Order);//0xAF:开显示
}
OLED显示的参数的初始化:
1. 在设置OLED的参数时,并不需要把所有的参数都设置一次;有些参数是默认的(可以不进行设置),只是需要设置一写必要的参数;
(如:0xAF: 开显示, 0x8D:电荷泵设置(初始化是必须打开,否则看不到显示))
2.代码(初始化代码中,介绍了大部分命令):
屏幕的大部分初始化厂家都会提供的。
/* OLED显示参数的初始化
*
*
*
*/
void OLED_Init(void)
{
OLED_GPIO_Init();
OLED_RST(1);
delay_ms(100);
OLED_RST(0);
delay_ms(100);
OLED_RST(1);
SPI_Write(0xAE, OLED_Order);//0xAE:关显示
SPI_Write(0x00, OLED_Order);//设置低列地址
SPI_Write(0x10, OLED_Order);//设置高列地址
//设置行显示的开始地址(0-63)
//40-47: (01xxxxx)
SPI_Write(0x40, OLED_Order);
//设置对比度
SPI_Write(0x81, OLED_Order);
SPI_Write(0xff, OLED_Order);//这个值越大,屏幕越亮(和上条指令一起使用)(0x00-0xff)
SPI_Write(0xA1, OLED_Order);//0xA1: 左右反置, 0xA0: 正常显示(默认0xA0)
SPI_Write(0xC8, OLED_Order);//0xC8: 上下反置, 0xC0: 正常显示(默认0xC0)
//0xA6: 表示正常显示(在面板上1表示点亮,0表示不亮)
//0xA7: 表示逆显示(在面板上0表示点亮,1表示不亮)
SPI_Write(0xA6, OLED_Order);
SPI_Write(0xA8, OLED_Order);//设置多路复用率(1-64)
SPI_Write(0x3F, OLED_Order);//(0x01-0x3f)(默认为3f)
//设置显示抵消移位映射内存计数器
SPI_Write(0xD3, OLED_Order);
SPI_Write(0x00, OLED_Order);//(0x00-0x3f)(默认为0x00)
//设置显示时钟分频因子/振荡器频率
SPI_Write(0xD5, OLED_Order);
//低4位定义显示时钟(屏幕的刷新时间)(默认:0000)分频因子= [3:0]+1
//高4位定义振荡器频率(默认:1000)
SPI_Write(0x80, OLED_Order);//
//时钟预充电周期
SPI_Write(0xD9, OLED_Order);
SPI_Write(0xF1, OLED_Order);//[3:0],PHASE 1; [7:4] PHASE 2
//设置COM硬件应脚配置
SPI_Write(0xDA, OLED_Order);
SPI_Write(0x12, OLED_Order);//[5:4] 默认:01
SPI_Write(0xDB, OLED_Order);//
SPI_Write(0x40, OLED_Order);//
//设置内存寻址方式
SPI_Write(0x20, OLED_Order);
//00: 表示水平寻址方式
//01: 表示垂直寻址方式
//10: 表示页寻址方式(默认方式)
SPI_Write(0x02, OLED_Order);//
//电荷泵设置(初始化时必须打开,否则看不到显示)
SPI_Write(0x8D, OLED_Order);
SPI_Write(0x14, OLED_Order);//bit2 0:关闭 1:打开
//设置是否全部显示 0xA4: 禁止全部显示
SPI_Write(0xA4, OLED_Order);
//0xA6: 表示正常显示(在面板上1表示点亮,0表示不亮)
//0xA7: 表示逆显示(在面板上0表示点亮,1表示不亮)
SPI_Write(0xA6, OLED_Order);//
SPI_Write(0xAF, OLED_Order);//0xAF:开显示
SPI_Write(0xAF, OLED_Order);//0xAF:开显示
OLED_Clear();
}
下面的显示汉字和显示ascii都需要结合取模方式的。
/* 显示汉字
* x:表示显示的水平坐标
* y: 表示显示的垂直坐标
* *p: 表示要显示汉字模组的首地址
*/
void OLED_ShowChinese(int x, int y, const unsigned char *p)
{
int i = 0;
OLED_Coord(x, y);
for(i = 0; i < 32; i+=2)
{
SPI_Write(p[i], OLED_Data);
}
OLED_Coord(x, y+1);
for(i = 1; i < 32; i+=2)
{
SPI_Write(p[i], OLED_Data);
}
}
/* 显示ASCII
* x:表示显示的水平坐标
* y: 表示显示的垂直坐标
* *p: 表示要显示汉字模组的首地址
*/
void OLED_ShowChar(int x, int y, const unsigned char *p)
{
int i = 0;
OLED_Coord(x, y);
for(i = 0; i < 16; i+=2)
{
SPI_Write(p[i], OLED_Data);
}
OLED_Coord(x, y+1);
for(i = 1; i < 16; i+=2)
{
SPI_Write(p[i], OLED_Data);
}
}
int main(void)
{
SysTick_Init();
OLED_Init();
OLED_ShowChinese(0, 0, xing);//‘姓’
OLED_ShowChinese(18, 0, ming);//‘名’
OLED_ShowChar(36, 0, ASCII_Colon);//‘:’
OLED_ShowChinese(0, 2, xue);//‘学’
OLED_ShowChinese(18, 2, hao);//‘号’
OLED_ShowChar(36, 2, ASCII_Colon);//‘:’
// SPI_Write(0x2F, OLED_Order); //0x2F:激活滚动(一定要有) 0x2E:关闭滚动
// //设置滚动方式:
// // 0x26/0x27 :水平滚动(右向/左向)
// // 0x29/0x2A :水平和垂直滚动(右向/左向)
// // 0xA3 :垂直滚动
// SPI_Write(0x27, OLED_Order);
// SPI_Write(0x00, OLED_Order);
// SPI_Write(0x00, OLED_Order);
// SPI_Write(0x00, OLED_Order);
// SPI_Write(0x03, OLED_Order);
// SPI_Write(0x30, OLED_Order);
while(1);
}
const unsigned char xing[]=
{ 0x10,0x40,0x10,0x22,0xF0,0x15,0x1F,0x08,
0x10,0x16,0xF0,0x21,0x40,0x40,0x3C,0x42,
0x10,0x42,0x10,0x42,0xFF,0x7F,0x10,0x42,
0x10,0x42,0x10,0x42,0x00,0x40,0x00,0x00};/*"姓",0*/
const unsigned char A[]=
{ 0x00,0x20,0x00,0x3C,0xC0,0x23,0x38,0x02,
0xE0,0x02,0x00,0x27,0x00,0x38,0x00,0x20};/*"A",0*/
const unsigned char ming[]=
{ 0x00,0x04,0x20,0x04,0x20,0x04,0x10,0x02,
0x08,0xFE,0x14,0x43,0x67,0x43,0x84,0x42,
0x44,0x42,0x24,0x42,0x14,0x42,0x0C,0x42,
0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00};/*"名",0*/
const unsigned char ASCII_Colon[]=
{ 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,
0xC0,0x30,0x00,0x00,0x00,0x00,0x00,0x00};/*":",0*/
const unsigned char xue[]=
{ 0x40,0x04,0x30,0x04,0x11,0x04,0x96,0x04,
0x90,0x04,0x90,0x44,0x91,0x84,0x96,0x7E,
0x90,0x06,0x90,0x05,0x98,0x04,0x14,0x04,
0x13,0x04,0x50,0x04,0x30,0x04,0x00,0x00};/*"学",0*/
const unsigned char hao[]=
{ 0x80,0x00,0x80,0x00,0x80,0x00,0xBE,0x06,
0xA2,0x05,0xA2,0x04,0xA2,0x04,0xA2,0x04,
0xA2,0x44,0xA2,0x84,0xA2,0x44,0xBE,0x3C,
0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00};/*"号",0*/
注意1:在使用PCtoLCD2002完美版进行取模时,如果取模的字高大于8时一定要注意;
如果字高16;取模的顺序是:从第一列开始,前8个点为第一个字节,后8个点为第二个字节
然后第二列取模,前8个点为第三个字节,后8个点为第四个字节,以此类推,而OLED屏的内存
寻址方式为0x10: 表示页寻址方式(默认方式)时,那么显示时将会乱码;因为是按页来显示的,
那么第一个字节显示在第一列,而第二个字节本应该显示在第二页的第一列,而被错误的显示在第一页的第二列,以此类推,导致显示乱码;
(这就是为什么OLED_ShowChar()函数和OLED_ShowChinese()函数中, 前面先显示数组下标为偶数的数组, 后面显示数组下标为奇数的数组)
oled的一套stm32实验1的更多相关文章
- oled的一套stm32实验2(自己的实验)
stm32与OLED屏接口的引脚介绍: CS————GPIOD3: RST————GPIOD4: DC—————GPIOD5: D0——————GPIOD6: D1——————GPIOD7; 上是我参 ...
- STM32实验非正式报告之DMA
前言 DMA即直接内存存取.我理解它就是一个“交通部长”抑或是一个“搬运工”,协助CPU存储或读取数据.既然它的主要工作就是“搬运”数据,服务对象自然就是内存(不太严格的说法吧,STM32中Flash ...
- 嵌入式02 STM32 实验01 端口复用和重映射
内设与外设: 端口复用和端口重映射都需要了解内设和外设,那么什么是内设?什么是外设? 内设:单片机内部集成的功能一般包括:串口模块.SPI模块(Serial Peripheral Interface ...
- 嵌入式02 STM32 实验04跑马灯
开学STM32 跑马灯的实验主要就是了解GPIO口的配置及使用,我这里是使用库函数进行编程,主要需要设置以下两方面: 1.使能需要使用的IO口的时钟,一共有A.B.C.D.E.F.G七组IO口 2.初 ...
- 嵌入式02 STM32 实验11 NVIC和中断总结
一.基础知识 1.cortex-m3支持256个中断,其中包含了16个内核中断,240个外部中断 2.STM32只有84个中断,包括16个内核中断和68个可屏蔽中断 3.STM32F103上只有60个 ...
- 嵌入式02 STM32 实验10 定时器中断
优秀文章 https://blog.csdn.net/qq_38351824/article/details/82619734 一.STM32通用定时器(TIM2.TIM3.TIM4和TIM5共四个通 ...
- 嵌入式02 STM32 实验08 外部中断
一.中断 由于某个事件的发生,CPU暂停当前正在执行的程序,转而执行处理事件的一个程序.该程序执行完成后,CPU接着执行被暂停的程序.这个过程称为中断.(我正在捉泥鳅,但是我妈喊我回家吃饭,我必须回家 ...
- 嵌入式02 STM32 实验07 串口通信
STM32串口通信(F1系列包含3个USART和2个UART) 一.单片机与PC机串行通信研究目的和意义: 单片机自诞生以来以其性能稳定,价格低廉.功能强大.在智能仪器.工业装备以及日用电子消费产品中 ...
- 嵌入式02 STM32 实验06 按键
按键实验和前面的跑马灯.蜂鸣器主要的区别就是这个是读取外部的输入信号,之前的实验都是对外部输出信号. 一.硬件设计 本实验的硬件为三个按键.两个lED(LED0.LED1).一个蜂鸣器(BEEP). ...
随机推荐
- 实际运用中DataSet、DataTable、DataRow点滴
DataSet.DataTable都自带有序列化标记,但是DataRow没有, 所以如果是在CS程序中,Release版本程序DataTable才是最小的数据传输单元,如果使用DataRow则会报[未 ...
- Ubuntu安装php
http://jingyan.baidu.com/article/dca1fa6fadc61ff1a5405244.html
- Android.mk脚本推断文件是否存在
Android.mk 推断文件是否存在,若存在则复制该文件到某个文件夹 $(shell test -f [文件] && echo yes)的值假设是yes, 则文件存在,然后进行she ...
- Bag标签之中的一个行代码实行中文分词实例3
例3: 分词(返回一个书包.以_0._1._2 ...取出分好的词) <bag id=words act=2words>我喜欢黄色高领T恤衫</bag> 注意没有name属性 ...
- Android设计模式(七)--原型模式
1.定义: 用原型实例指定创建对象种类,并通过拷贝这些原型创建新的对象. 2.目的: 从一个对象创建另外一个可定制的对象,而不须要知道不论什么创建细节. 3.作用: 3.1.简化对象的创建. 3.2 ...
- Linux经常使用命令(十六) - whereis
whereis命令仅仅能用于程序名的搜索(程序安装在哪?).并且仅仅搜索二进制文件(參数-b).man说明文件(參数-m)和源码文件(參数-s). 假设省略參数,则返回全部信息. 和find相比.wh ...
- [欧拉回路] poj 1386 Play on Words
题目链接: http://poj.org/problem?id=1386 Play on Words Time Limit: 1000MS Memory Limit: 10000K Total S ...
- 通过Debug-->Attach to Process的方式来调试网站
找到网站所对应的应用程序池
- API集合开发文档
百度翻译api https://www.cnblogs.com/DevilX5/p/7079470.html 实现QQ第三方登录.网站接入 http://blog.csdn.net/u01067894 ...
- js简易留言板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...