赞
踩
OLED,即有机发光二极管
OLED引脚说明
引脚说明:
1、CS:OLED片选信号(低电平有效)
2、WR:向OLED写入数据
3、RD:向OLED读取数据
4、D[7:0]:8位双向数据线,有8个引脚,每个引脚传一位数据
5、RST(RES):硬复位OLED(低电平有效)
6、DC:数据/命令标志(0,命令;1,数据)
驱动IC:驱动IC是指驱动集成电路(Integrated Circuit),它是一种用于控制和驱动液晶显示器的电子元件。负责将输入的信号转换为液晶显示器可以理解和显示的信号,从而实现对液晶显示器的控制和驱动,驱动IC的功能包括控制液晶显示器的像素点亮和灭,调节亮度和对比度,以及实现图像的显示和刷新等。
1、选择驱动芯片时序 8080时序 根据时序实现数据写入/读取
2、初始化序列 由厂家提供,用于初始化屏幕
3、实现画点函数、读点函数(可选) 基于这两个函数可以实现各种绘图功能
1、设置DC为高(数据)/低(命令) 根据写入/读取的数据类型
2、拉低片选 选中SSD1306
3、设置RD/WR为低 根据是读数据还是写数据
4、拉高RD/WR,出现上升沿
在RD的上升沿,使数据锁存到数据线D[7:0]上
在WR的上升沿,使数据写入到SSD1306里
注意:SSD1306是一款单片CMOS OLED/PLED驱动器,用于OLED点阵图形显示系统
void oled_data_out(uint8_t data)
{
GPIOC->ODR = (GPIOC->ODR & 0XFF00) | (data & 0X00FF);
}
void oled_wr_byte(uint8_t data, uint8_t cmd)
{
OLED_RS (cmd); /* 数据类型,由传参决定 /
OLED_CS ( 0 ); / 拉低片选线,选中SSD1306 /
OLED_WR ( 0 ); / 拉低WR线,准备数据 /
oled_data_out(data); / WR低电平期间,准备数据 /
OLED_WR ( 1 ); / 在WR上升沿,数据发出 /
OLED_CS ( 1 ); / 取消片选 /
OLED_RS ( 1 ); / 释放RS线,恢复默认 */
}
三种设置内存地址模式:页地址模式,水平地址模式和垂直地址模式
图形显示数据RAM是一个位映射静态RAM,保存要显示的位模式。内存大小为128 * 64位,可分为8页,从页0到页7,用于黑白128 * 64点阵显示
static uint8_t g_oled_gram[128][8]; /* OLED的显存 */
void oled_refresh_gram(void)
{
uint8_t i,n;
for (i = 0; i < 8; i++)
{
oled_wr_byte(0xb0 + i, OLED_CMD) ; /* 设置页地址(0~7)/
oled_wr_byte(0x00, OLED_CMD) ; / 设置显示位置-列低地址 /
oled_wr_byte(0x10, OLED_CMD) ; / 设置显示位置-列高地址 */
for (n = 0; n < 128; n++)
{
oled_wr_byte( g_oled_gram[ n ][ i ], OLED_DATA) ;
}
}
}
OLED_GRAM[x][y / 8] |= 1 << y % 8;
void oled_draw_point(uint8_t x, uint8_t y, uint8_t dot)
{
uint8_t pos, bx, temp = 0;
if (x > 127 || y > 63) return; /* 超出范围了 /
pos = y / 8; / 页地址 /
bx = y % 8; / 计算y在对应字节里面的位置 /
temp = 1 << bx; / 转换后y对应的bit位置 */
if ( dot ) /* 画实心点 */
g_oled_gram[ x ][ pos ] |= temp;
else
g_oled_gram[ x ][ pos ] &= ~temp;
1,显示字符,必须先有其点阵数据,点阵数据的集合,叫做字库
2,单片机根据点阵数据按取模方向进行描点还原,就能显示字符
3,ASCII字符宽度 = 汉字宽度的一半
16*16大小,字符A的点阵数据数组:
uint8_t oled_ascii_1608[]=
{
0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,
0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04
} ;
字符显示代码:
字符显示规则:从上到下、从左到右、高位在前
uint8_t temp, t1, t; uint8_t y0 = y; /* 保存y的初值 */ for(t = 0; t < 16; t++) /* 总共16个字节,要遍历一遍 */ { temp = oled_ascii_1608[t]; /* 依次获取点阵数据 */ for(t1 = 0; t1 < 8; t1++) { if(temp & 0X80) /* 这个点有效,需要画出来 */ oled_draw_point(x, y, mode); else /* 这个点无效,不需要画出来 */ oled_draw_point(x, y, !mode); temp <<= 1; /* 低位数据往高位移位,最高位数据直接丢弃 */ y++; /* y坐标自增 */ if((y - y0) == 16) /* 显示完一列了 */ { y = y0; /* y坐标复位 */ x++; /* x坐标递增 */ break; /* 跳出 for循环 */ } } }
目标:用最简单代码,点亮OLED屏,实现任意位置画点
1,确定IO连接关系 开发板OLED接口原理图
2,初始化IO口 初始化连接OLED的各个IO口
3,编写8080接口函数 oled_wr_byte
4,编写OLED初始化函数 编写oled_init函数,完成初始化序列配置
5,编写OLED画点函数 编写oled_draw_point函数,实现OLED任意位置画点
1,在OLED屏幕上画一个点(不建立OLED_GRAM)
2,在OLED屏幕上显示一个字符‘A’(建立OLED_GRAM)
#include "stdlib.h" #include "./BSP/OLED/oled.h" #include "./BSP/OLED/oledfont.h" #include "./SYSTEM/delay/delay.h" /* * OLED的显存 * 每个字节表示8个像素, 128,表示有128列, 8表示有64行, 高位表示第行数. * 比如:g_oled_gram[0][0],包含了第一列,第1~8行的数据. g_oled_gram[0][0].7,即表示坐标(0,0) * 类似的: g_oled_gram[1][0].6,表示坐标(1,1), g_oled_gram[10][1].5,表示坐标(10,10), * * 存放格式如下(高位表示低行数). * [0]0 1 2 3 ... 127 * [1]0 1 2 3 ... 127 * [2]0 1 2 3 ... 127 * [3]0 1 2 3 ... 127 * [4]0 1 2 3 ... 127 * [5]0 1 2 3 ... 127 * [6]0 1 2 3 ... 127 * [7]0 1 2 3 ... 127 */ static uint8_t g_oled_gram[128][8]; /** * @brief 更新显存到OLED * @param 无 * @retval 无 */ void oled_refresh_gram(void) { //1.定义变量 uint8_t i, n; for(i = 0;i<8;i++) { //2 将页地址、列低地址、列高地址写入到OLED中 oled_wr_byte(0xb0 + i,OLED_CMD); //设置页地址(0~7) oled_wr_byte(0x00,OLED_CMD); //设置显示位置一列低地址 oled_wr_byte(0x10,OLED_CMD); //设置显示位置一列高地址 for(n = 0; n<128; n++) { //3 写入到OLED的GRAM中 oled_wr_byte(g_oled_gram[n][i], OLED_DATA); } } } #if OLED_MODE ==1 //使用8080并口驱动OLED /** * @brief 通过拼凑的方法向OLED输出一个8位数据 * @param data: 要输出的数据 * @retval 无 */ static void oled_data_out(uint8_t data) { uint16_t dat = data & 0X0F; //只保留D[3:0]位值,其他位清零 GPIOC->ODR &= ~(0XF<<6); //6~9位清零,其他位保留 GPIOC->ODR |= dat << 6; //将D[3:0]->PC[9:6]位,其他位保留 GPIOC->ODR &= ~(0X1<<11); //清空第十一位,其他位保留 GPIOC->ODR |= ((dat>>4)& 0x01)<<11; //将D4->PC11位 其他位保留 GPIOB->ODR &= ~(0X1<<6); //清空6 GPIOB->ODR |= ((dat>>5)&0x01)<<6; //将D5->PB6位 其他位保留 GPIOE->ODR &= ~(0X3<<5); //清空5,6 GPIOE->ODR |= ((dat>>6)&0x3)<<5; //将D[7:6]->PE[6:5]位 其他位保留 } /** * @brief 向OLED写入一个字节 * @param data: 要输出的数据 * @param cmd: 数据/命令标志 0,表示命令;1,表示数据; * @retval 无 */ //写一个字节到OLED static void oled_wr_byte(uint8_t data, uint8_t cmd) { //输出一个8位数据,数据准备 oled_data_out(data); //1.数据类型 设置DC引脚电频 命令 OLED_RS(cmd); //2.选中SSD1306显示芯片 CS引脚拉低 OLED_CS(0); //3.选择写数据 WR引脚拉低 OLED_WR(0); //4.将数据写入SSD1306芯片 WR引脚拉高 OLED_WR(1); //5.释放CS引脚 OLED_CS(1); //6.释放DC引脚 OLED_RS(1); } #else /*使用SPI驱动OLED*/ /** * @brief 向OLED写入一个字节 * @param data: 要输出的数据 * @param cmd: 数据/命令标志 0,表示命令;1,表示数据; * @retval 无 */ static void oled_wr_byte(uint8_t data, uint8_t cmd) { uint8_t i; //1.设置数据类型为写命令 OLED_RS(cmd); //2.选中SSD1306显示芯片 CS引脚拉低 OLED_CS(0); //3.写数据 for(i=0;i<8;i++) { OLED_SCLK(0); if(data &0x80) { OLED_SDIN(1); } else { OLED_SCLK(0); } OLED_SCLK(1); data<<=1; } //4 释放CS引脚 OLED_CS(1); //5 释放DS引脚 OLED_RS(0); } #endif /** * @brief 开启OLED显示 * @param 无 * @retval 无 */ void oled_display_on(void) { oled_wr_byte(0X8D, OLED_CMD); /* SET DCDC命令 */ oled_wr_byte(0X14, OLED_CMD); /* DCDC ON */ oled_wr_byte(0XAF, OLED_CMD); /* DISPLAY ON */ } /** * @brief 关闭OLED显示 * @param 无 * @retval 无 */ void oled_display_off(void) { oled_wr_byte(0X8D, OLED_CMD); /* SET DCDC命令 */ oled_wr_byte(0X10, OLED_CMD); /* DCDC ON */ oled_wr_byte(0XAE, OLED_CMD); /* DISPLAY ON */ } /** * @brief 清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!! * @param 无 * @retval 无 */ void oled_clear(void) { uint8_t i,n; for(i =0;i<8;i++) { for(n = 0;n<128;n++) g_oled_gram[n][i] = 0x00; } oled_refresh_gram(); //更新显示 } /** * @brief OLED画点 * @param x : 0~127 * @param y : 0~63 * @param dot: 1 填充 0,清空 * @retval 无 */ void oled_draw_point(uint8_t x, uint8_t y, uint8_t dot) { //定义变量 uint8_t pos,bx,temp =0; if(x > 127 || y > 63) return; //超出范围 pos = y/8; //y坐标所在的字节,每个字节存储8个行坐标 bx = y % 8; //方便获取y所在字节里面的位置 temp = 1 << bx; //高位存储的是低行号,将对应bit位置1 if(dot) { g_oled_gram[x][pos] |= temp; //话实心点 } else { g_oled_gram[x][pos] |= temp; //话空点 } } /** * @brief OLED填充区域填充 * @note: 注意:需要确保: x1<=x2; y1<=y2 0<=x1<=127 0<=y1<=63 * @param x1,y1: 起点坐标 * @param x2,y2: 终点坐标 * @param dot: 1 填充 0,清空 * @retval 无 */ void oled_fill(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t dot) { uint8_t x, y; for(x = x1;x<=x2;x++) { for(y = y1;y<=y2; y++) { oled_draw_point(x,y,dot); } } oled_refresh_gram(); //更新显示 } /** * @brief 在指定位置显示一个字符,包括部分字符 * @param x : 0~127 * @param y : 0~63 * @param size: 选择字体 12/16/24 * @param mode: 0,反白显示;1,正常显示 * @retval 无 */ void oled_show_char(uint8_t x, uint8_t y, uint8_t chr, uint8_t size, uint8_t mode) { //定义变量 uint8_t temp, t, t1; uint8_t y0 = y; uint8_t *pfont = 0; uint8_t csize =(size/8+(size%8)? 1:0)*(size/2); //得到字体一个字符对应点阵集所占字节数 chr = chr - ' '; /* 得到偏移后的值,因为字库是从空格开始存储的,第一个字符是空格 */ if(size == 12) { pfont = (uint8_t *)oled_asc2_1206[chr]; } else if(size == 16) { pfont = (uint8_t *)oled_asc2_1608[chr]; } else if(size == 24) { pfont = (uint8_t *)oled_asc2_2412[chr]; } else { return; } for (t = 0; t < csize; t++) { temp = pfont[t]; for (t1 = 0; t1 < 8; t1++) { if (temp & 0x80)oled_draw_point(x, y, mode); else oled_draw_point(x, y, !mode); temp <<= 1; y++; if ((y - y0) == size) { y = y0; x++; break; } } } } /** * @brief 平方函数, m^n * @param m: 底数 * @param n: 指数 * @retval 无 */ static uint32_t oled_pow(uint8_t m, uint8_t n) { uint32_t result = 1; while(n--) { result *= m; } return result; } /** * @brief 显示len个数字 * @param x,y : 起始坐标 * @param num : 数值(0 ~ 2^32) * @param len : 显示数字的位数 * @param size: 选择字体 12/16/24 * @retval 无 */ void oled_show_num(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size) { uint8_t t, temp; uint8_t enshow = 0; for(t = 0; t < len; t++) { temp = (num/oled_pow(10, len - t - 1))%10; //获取对应位的值 if(enshow == 0 && t < (len-1)) { if(temp == 0) { oled_show_char(x + (size/2)*t, y, ' ',size, 1); //显示空格站位 continue; //继续下一个位 } else { enshow =1; } } oled_show_char(x + (size/2)*t, y, ' ',size, 1); //显示空格站位 } } /** * @brief 显示字符串 * @param x,y : 起始坐标 * @param size: 选择字体 12/16/24 * @param *p : 字符串指针,指向字符串首地址 * @retval 无 */ void oled_show_string(uint8_t x, uint8_t y, const char *p, uint8_t size) { while((*p <= '~') && (*p <= ' ')) //判断是否为非法字符 { if(x>(128 -(size/2))) //宽度越界 { x = 0; y += size; } if(y>(64-size)) //高度越界 { y = x =0; oled_clear(); } oled_show_char(x, y, *p,size, 1); //显示一个字符 x +=size/2; //ASXII字符宽度仅为汉字宽度的一半 p++; } } /** * @brief 初始化OLED(SSD1306) * @param 无 * @retval 无 */ // void oled_init(void) { GPIO_InitTypeDef gpio_init_struct; #if OLED_MODE==1 /* 使用8080并口模式 */ __HAL_RCC_GPIOA_CLK_ENABLE(); /* 使能PORTA时钟 */ __HAL_RCC_GPIOB_CLK_ENABLE(); /* 使能PORTB时钟 */ __HAL_RCC_GPIOC_CLK_ENABLE(); /* 使能PORTC时钟 */ __HAL_RCC_GPIOD_CLK_ENABLE(); /* 使能PORTD时钟 */ __HAL_RCC_GPIOE_CLK_ENABLE(); /* 使能PORTE时钟 */ __HAL_RCC_GPIOG_CLK_ENABLE(); /* 使能PORTG时钟 */ /* PA4 设置 */ gpio_init_struct.Pin = GPIO_PIN_4; gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */ gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */ gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */ HAL_GPIO_Init(GPIOA, &gpio_init_struct); /* PB6, PB7 设置 */ gpio_init_struct.Pin = GPIO_PIN_6 | GPIO_PIN_7; HAL_GPIO_Init(GPIOB, &gpio_init_struct); /* PC6~9, PC11 设置*/ gpio_init_struct.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_11; HAL_GPIO_Init(GPIOC, &gpio_init_struct); /* PD6, PD7 设置 */ gpio_init_struct.Pin = GPIO_PIN_6 | GPIO_PIN_7; HAL_GPIO_Init(GPIOD, &gpio_init_struct); /* PE5, PE6 设置 */ gpio_init_struct.Pin = GPIO_PIN_5 | GPIO_PIN_6; HAL_GPIO_Init(GPIOE, &gpio_init_struct); /* PG15 设置 */ gpio_init_struct.Pin = GPIO_PIN_15; HAL_GPIO_Init(GPIOG, &gpio_init_struct); OLED_WR(1); OLED_RD(1); #else /* 使用4线SPI 串口模式 */ OLED_SPI_RST_CLK_ENABLE(); OLED_SPI_CS_CLK_ENABLE(); OLED_SPI_RS_CLK_ENABLE(); OLED_SPI_SCLK_CLK_ENABLE(); OLED_SPI_SDIN_CLK_ENABLE(); gpio_init_struct.Pin = OLED_SPI_RST_PIN; /* RST引脚 */ gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */ gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */ gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; /* 中速 */ HAL_GPIO_Init(OLED_SPI_RST_PORT, &gpio_init_struct); /* RST引脚模式设置 */ gpio_init_struct.Pin = OLED_SPI_CS_PIN; /* CS引脚 */ gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */ gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */ gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; /* 中速 */ HAL_GPIO_Init(OLED_SPI_CS_PORT, &gpio_init_struct); /* CS引脚模式设置 */ gpio_init_struct.Pin = OLED_SPI_RS_PIN; /* RS引脚 */ gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */ gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */ gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; /* 中速 */ HAL_GPIO_Init(OLED_SPI_RS_PORT, &gpio_init_struct); /* RS引脚模式设置 */ gpio_init_struct.Pin = OLED_SPI_SCLK_PIN; /* SCLK引脚 */ gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */ gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */ gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; /* 中速 */ HAL_GPIO_Init(OLED_SPI_SCLK_PORT, &gpio_init_struct); /* SCLK引脚模式设置 */ gpio_init_struct.Pin = OLED_SPI_SDIN_PIN; /* SDIN引脚模式设置 */ gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */ gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */ gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; /* 中速 */ HAL_GPIO_Init(OLED_SPI_SDIN_PORT, &gpio_init_struct); /* SDIN引脚模式设置 */ OLED_SDIN(1); OLED_SCLK(1); #endif OLED_CS(1); OLED_RS(1); OLED_RST(0); delay_ms(100); OLED_RST(1); oled_wr_byte(0xAE,OLED_CMD); //关闭显示 oled_wr_byte(0xD5, OLED_CMD); /* 设置时钟分频因子,震荡频率 */ oled_wr_byte(80, OLED_CMD); /* [3:0],分频因子;[7:4],震荡频率 */ oled_wr_byte(0xA8, OLED_CMD); /* 设置驱动路数 */ oled_wr_byte(0X3F, OLED_CMD); /* 默认0X3F(1/64) */ oled_wr_byte(0xD3, OLED_CMD); /* 设置显示偏移 */ oled_wr_byte(0X00, OLED_CMD); /* 默认为0 */ oled_wr_byte(0x40, OLED_CMD); /* 设置显示开始行 [5:0],行数. */ oled_wr_byte(0x8D, OLED_CMD); /* 电荷泵设置 */ oled_wr_byte(0x14, OLED_CMD); /* bit2,开启/关闭 */ oled_wr_byte(0x20, OLED_CMD); /* 设置内存地址模式 */ oled_wr_byte(0x02, OLED_CMD); /* [1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10; */ oled_wr_byte(0xA1, OLED_CMD); /* 段重定义设置,bit0:0,0->0;1,0->127; */ oled_wr_byte(0xC8, OLED_CMD); /* 设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 */ oled_wr_byte(0xDA, OLED_CMD); /* 设置COM硬件引脚配置 */ oled_wr_byte(0x12, OLED_CMD); /* [5:4]配置 */ oled_wr_byte(0x81, OLED_CMD); /* 对比度设置 */ oled_wr_byte(0xEF, OLED_CMD); /* 1~255;默认0X7F (亮度设置,越大越亮) */ oled_wr_byte(0xD9, OLED_CMD); /* 设置预充电周期 */ oled_wr_byte(0xf1, OLED_CMD); /* [3:0],PHASE 1;[7:4],PHASE 2; */ oled_wr_byte(0xDB, OLED_CMD); /* 设置VCOMH 电压倍率 */ oled_wr_byte(0x30, OLED_CMD); /* [6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc; */ oled_wr_byte(0xA4, OLED_CMD); /* 全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) */ oled_wr_byte(0xA6, OLED_CMD); /* 设置显示方式;bit0:1,反相显示;0,正常显示 */ oled_wr_byte(0xAF, OLED_CMD); /* 开启显示 */ oled_clear(); }
#ifndef __OLED_H #define __OLED_H #include "stdlib.h" #include "./SYSTEM/sys/sys.h" /* OLED模式设置 * 0: 4线串行模式 (模块的BS1,BS2均接GND) * 1: 并行8080模式 (模块的BS1,BS2均接VCC) */ #define OLED_MODE 1 //默认使用8080并口模式 /******************************************************************************************/ /* OLED SPI模式引脚 定义 */ /* 注意:这里仅定义了 OLED 4线SPI模式驱动时的 引脚定义. 8位并口访问, 由于引脚太多,就不单独定义了. */ #define OLED_SPI_RST_PORT GPIOG #define OLED_SPI_RST_PIN GPIO_PIN_15 #define OLED_SPI_RST_CLK_ENABLE() do{ __HAL_RCC_GPIOG_CLK_ENABLE(); }while(0) /* PG15口时钟使能 */ #define OLED_SPI_CS_PORT GPIOB #define OLED_SPI_CS_PIN GPIO_PIN_7 #define OLED_SPI_CS_CLK_ENABLE() do{ __HAL_RCC_GPIB_CLK_ENABLE(); }while(0) /* PB7口时钟使能 */ #define OLED_SPI_RS_PORT GPIOD #define OLED_SPI_RS_PIN GPIO_PIN_6 #define OLED_SPI_RS_CLK_ENABLE() do{ __HAL_RCC_GPIOD_CLK_ENABLE(); }while(0) /* PD6口时钟使能 */ #define OLED_SPI_SCLK_PORT GPIOC #define OLED_SPI_SCLK_PIN GPIO_PIN_6 #define OLED_SPI_SCLJ_CLK_ENABLE() do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0) /* PC6口时钟使能 */ #define OLED_SPI_SDIN_PORT GPIOC #define OLED_SPI_SDIN_PIN GPIO_PIN_7 #define OLED_SPI_SDIN_CLK_ENABLE() do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0) /* PC7口时钟使能 */ //OLED SPI模式相关端口控制函数 定义 //注意:OLED_RST/OLED_CS/OLED_RS,这三个是和80并口模式共用的,即80模式也必须实现这3个模式 #define OLED_RST(x) do{ x?\ HAL_GPIO_WritePin(OLED_SPI_RST_PORT,OLED_SPI_RST_PIN,GPIO_PIN_RESET):\ HAL_GPIO_WritePin(OLED_SPI_RST_PORT,OLED_SPI_RST_PIN,GPIO_PIN_SET);\ }while(0) //设置RST引脚 #define OLED_CS(x) do{ x?\ HAL_GPIO_WritePin(OLED_SPI_CS_PORT, OLED_SPI_CS_PIN, GPIO_PIN_RESET):\ HAL_GPIO_WritePin(OLED_SPI_RST_PORT, OLED_SPI_CS_PIN, GPIO_PIN_SET);\ }while(0) //设置CS引脚 #define OLED_RS(x) do{ x?\ HAL_GPIO_WritePin(OLED_SPI_CS_PORT, OLED_SPI_SCLK_PIN, GPIO_PIN_RESET):\ HAL_GPIO_WritePin(OLED_SPI_RST_PORT, OLED_SPI_SCLK_PIN, GPIO_PIN_SET);\ }while(0) //设置RS引脚 #define OLED_SCLK(x) do{ x?\ HAL_GPIO_WritePin(OLED_SPI_CS_PORT, OLED_SPI_RS_PIN, GPIO_PIN_RESET):\ HAL_GPIO_WritePin(OLED_SPI_RST_PORT, OLED_SPI_RS_PIN, GPIO_PIN_SET);\ }while(0) //设置SCLK引脚 #define OLED_SCLK(x) do{ x?\ HAL_GPIO_WritePin(OLED_SPI_CS_PORT, OLED_SPI_RS_PIN, GPIO_PIN_RESET):\ HAL_GPIO_WritePin(OLED_SPI_RST_PORT, OLED_SPI_RS_PIN, GPIO_PIN_SET);\ }while(0) //设置SCLK引脚 #define OLED_SDIN(x) do{ x?\ HAL_GPIO_WritePin(OLED_SPI_CS_PORT, OLED_SPI_SDIN_PIN, GPIO_PIN_RESET):\ HAL_GPIO_WritePin(OLED_SPI_RST_PORT, OLED_SPI_SDIN_PIN, GPIO_PIN_SET);\ }while(0) //设置SCLK引脚 //OLED 80并口模式WR、 RD端口控制函数 定义 #define OLED_WR(x) do{ x?\ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET):\ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);\ }while(0) //设置WR引脚 #define OLED_RD(x) do{ x?\ HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_RESET):\ HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET);\ }while(0) //设置RD引脚 //命令、数据 定义 #define OLED_CMD 0 //命令 #define OLED_DATA 1 //写数据 /*************************************************************************************/ static void oled_wr_byte(uint8_t data, uint8_t cmd); //写一个字节到OLED static uint32_t oled_pow(uint8_t m, uint8_t n); //OLED求平方函数 void oled_init(void); //OLED初始化 void oled_clear(void); //OLED清屏 void oled_display_on(void); //开启OLED显示 void oled_display_off(void); //关闭OLED显示 void oled_refresh_gram(void); //更新显存到OLED void oled_draw_point(uint8_t x, uint8_t y,uint8_t dot); //OLED画点 void oled_fill(uint8_t xl, uint8_t yl,uint8_t x2, uint8_t y2,uint8_t dot); //OLED区域填充 void oled_show_char(uint8_t x, uint8_t y, uint8_t chr, uint8_t size, uint8_t mode);//OLED显示字符 void oled_show_num(uint8_t x, uint8_t y, uint8_t num, uint8_t len, uint8_t size); //OLED显示数字 void oled_show_string(uint8_t x, uint8_t y, const char*p, uint8_t len, uint8_t size); //OLED显示数字 #endif
#include "./SYSTEM/sys/sys.h" #include "./SYSTEM/usart/usart.h" #include "./SYSTEM/delay/delay.h" #include "./BSP/LED/led.h" #include "./BSP/OLED/oled.h" int main(void) { uint8_t t = 0; HAL_Init(); /* 初始化HAL库 */ sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */ delay_init(168); /* 延时初始化 */ usart_init(115200); /* 串口初始化为115200 */ led_init(); /* 初始化LED */ oled_init(); /* 初始化OLED */ oled_show_string(0, 0, "ALIENTEK", 24); oled_show_string(0, 24, "0.96' OLED TEST", 16); oled_show_string(0, 52, "ASCII:", 12); oled_show_string(64, 52, "CODE:", 12); oled_refresh_gram(); /* 更新显示到OLED */ t = ' '; while(1) { oled_show_char(36, 52, t, 12, 1); /* 显示ASCII字符 */ oled_show_num(94, 52, t, 3, 12); /* 显示ASCII字符的码值 */ oled_refresh_gram(); /* 更新显示到OLED */ t++; if (t > '~') { t = ' '; } delay_ms(500); LED0_TOGGLE(); /* LED0闪烁 */ } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。