训练题——OLED部分
训练题OLED部分
实现目标
通过IIC通信控制OLED屏幕显示出一串字符串
名词介绍
OLED屏:
OLED(Organic Light-Emitting Diode),又称为有机电激光显示、有机发光半导体(Organic Electroluminescence Display,OLED)。OLED属于一种电流型的有机发光器件,是通过载流子的注入和复合而致发光的现象,发光强度与注入的电流成正比。OLED在电场的作用下,阳极产生的空穴和阴极产生的电子就会发生移动,分别向空穴传输层和电子传输层注入,迁移到发光层。当二者在发光层相遇时,产生能量激子,从而激发发光分子最终产生可见光。
百度百科上布拉布拉一堆,我也看不懂,不关键,原理不重要,会用就行。
我们这里使用的是OLED12864,12864就是指它有128*64个像素点,而每个像素点都有亮和暗两种状态,我们可以通过程序控制哪些像素点的亮来在我们的屏幕上显示我们想显示的内容
IIC通信
IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。I²C的正确读法为“I平方C”("I-squared-C"),而“I二C”("I-two-C")则是另一种错误但被广泛使用的读法。自2006年10月1日起,使用I²C协议已经不需要支付专利费,但制造商仍然需要付费以获取I²C从属设备地址。
我平常一般叫I方C,不过叫啥都行==
简单来说IIC就是一种设备间的通信方式,我们可以理解为一种加密方式,就类似于摩斯电码,发送和接收都要满足一定的规则才能把数据传输过去。IIC的一个主要的特点就是支持多主从结构,每个设备都有一个自己的地址,每次通信都要注明地址,这样数据就只会被该地址的设备接收,从而实现多个从机同时控制。本文中使用的OLED12864就是IIC通信
这里简单以IIC的数据传输来介绍一下IIC传输中两根线的作用
SCL,也就是clock,是控制IIC通信中时序的时钟信号,SDA,也就是DATA,是控制IIC通信中数据的信号,从这个图中我们可以看出,当SCL被拉高后,数据开始传输,传输的数据就是SDA线上的值,或者说是逻辑电平,当SCL拉低后,数据停止传输,SDA上的值可以发生变化,准备下一个数据的传输,然后周期往复。这样就通过两根线实现了数据的传输
这里附上一个更为详细的通信介绍,推荐大家仔细学习一下,通信协议还是很重要的。
OLED的实现
驱动
有关于OLED的驱动,因为写起来比较繁琐我这里就直接提供一个我之前用的驱动,有兴趣的同学可以查找OLED的数据手册学习
OLED.c
#include "OLED.h"
#include "asc.h"
#include "main.h"
#include <stdio.h>
#include <stdarg.h>
extern I2C_HandleTypeDef hi2c1;
static uint8_t OLED_GRAM[128][8];
void oled_write_byte(uint8_t dat, uint8_t cmd)
{
static uint8_t cmd_data[2];
if(cmd == OLED_CMD)
{
cmd_data[0] = 0x00;
}
else
{
cmd_data[0] = 0x40;
}
cmd_data[1] = dat;
HAL_I2C_Master_Transmit(&hi2c1, OLED_I2C_ADDRESS, cmd_data, 2, 10);
}
void OLED_init(void)
{
oled_write_byte(0xAE, OLED_CMD); //display off
oled_write_byte(0x20, OLED_CMD); //Set Memory Addressing Mode
oled_write_byte(0x10, OLED_CMD); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
oled_write_byte(0xb0, OLED_CMD); //Set Page Start Address for Page Addressing Mode,0-7
oled_write_byte(0xc8, OLED_CMD); //Set COM Output Scan Direction
oled_write_byte(0x00, OLED_CMD); //---set low column address
oled_write_byte(0x10, OLED_CMD); //---set high column address
oled_write_byte(0x40, OLED_CMD); //--set start line address
oled_write_byte(0x81, OLED_CMD); //--set contrast control register
oled_write_byte(0xff, OLED_CMD); //brightness 0x00~0xff
oled_write_byte(0xa1, OLED_CMD); //--set segment re-map 0 to 127
oled_write_byte(0xa6, OLED_CMD); //--set normal display
oled_write_byte(0xa8, OLED_CMD); //--set multiplex ratio(1 to 64)
oled_write_byte(0x3F, OLED_CMD); //
oled_write_byte(0xa4, OLED_CMD); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
oled_write_byte(0xd3, OLED_CMD); //-set display offset
oled_write_byte(0x00, OLED_CMD); //-not offset
oled_write_byte(0xd5, OLED_CMD); //--set display clock divide ratio/oscillator frequency
oled_write_byte(0xf0, OLED_CMD); //--set divide ratio
oled_write_byte(0xd9, OLED_CMD); //--set pre-charge period
oled_write_byte(0x22, OLED_CMD); //
oled_write_byte(0xda, OLED_CMD); //--set com pins hardware configuration
oled_write_byte(0x12, OLED_CMD);
oled_write_byte(0xdb, OLED_CMD); //--set vcomh
oled_write_byte(0x20, OLED_CMD); //0x20,0.77xVcc
oled_write_byte(0x8d, OLED_CMD); //--set DC-DC enable
oled_write_byte(0x14, OLED_CMD); //
oled_write_byte(0xaf, OLED_CMD); //--turn on oled panel
}
void OLED_display_on(void)
{
oled_write_byte(0x8d, OLED_CMD);
oled_write_byte(0x14, OLED_CMD);
oled_write_byte(0xaf, OLED_CMD);
}
void OLED_display_off(void)
{
oled_write_byte(0x8d, OLED_CMD);
oled_write_byte(0x10, OLED_CMD);
oled_write_byte(0xae, OLED_CMD);
}
void OLED_operate_gram(pen_typedef pen)
{
uint8_t i, n;
for (i = 0; i < 8; i++)
{
for (n = 0; n < 128; n++)
{
if (pen == PEN_WRITE)
{
OLED_GRAM[n][i] = 0xff;
}
else if (pen == PEN_CLEAR)
{
OLED_GRAM[n][i] = 0x00;
}
else
{
OLED_GRAM[n][i] = 0xff - OLED_GRAM[n][i];
}
}
}
}
void OLED_set_pos(uint8_t x, uint8_t y)
{
oled_write_byte((0xb0 + y), OLED_CMD); //set page address y
oled_write_byte(((x&0xf0)>>4)|0x10, OLED_CMD); //set column high address
oled_write_byte((x&0x0f), OLED_CMD); //set column low address
}
void OLED_draw_point(int8_t x, int8_t y, pen_typedef pen)
{
uint8_t page = 0, row = 0;
/* check the corrdinate */
if ((x < 0) || (x > (X_WIDTH - 1)) || (y < 0) || (y > (Y_WIDTH - 1)))
{
return;
}
page = y / 8;
row = y % 8;
if (pen == PEN_WRITE)
{
OLED_GRAM[x][page] |= 1 << row;
}
else if (pen == PEN_INVERSION)
{
OLED_GRAM[x][page] ^= 1 << row;
}
else
{
OLED_GRAM[x][page] &= ~(1 << row);
}
}
void OLED_draw_line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, pen_typedef pen)
{
uint8_t col = 0, row = 0;
uint8_t x_st = 0, x_ed = 0, y_st = 0, y_ed = 0;
float k = 0.0f, b = 0.0f;
if (y1 == y2)
{
(x1 <= x2) ? (x_st = x1):(x_st = x2);
(x1 <= x2) ? (x_ed = x2):(x_ed = x1);
for (col = x_st; col <= x_ed; col++)
{
OLED_draw_point(col, y1, pen);
}
}
else if (x1 == x2)
{
(y1 <= y2) ? (y_st = y1):(y_st = y2);
(y1 <= y2) ? (y_ed = y2):(y_ed = y1);
for (row = y_st; row <= y_ed; row++)
{
OLED_draw_point(x1, row, pen);
}
}
else
{
k = ((float)(y2 - y1)) / (x2 - x1);
b = (float)y1 - k * x1;
(x1 <= x2) ? (x_st = x1):(x_st = x2);
(x1 <= x2) ? (x_ed = x2):(x_ed = x2);
for (col = x_st; col <= x_ed; col++)
{
OLED_draw_point(col, (uint8_t)(col * k + b), pen);
}
}
}
void OLED_show_char(uint8_t row, uint8_t col, uint8_t chr)
{
uint8_t x = col * 6;
uint8_t y = row * 12;
uint8_t temp, t, t1;
uint8_t y0 = y;
chr = chr - ' ';
for (t = 0; t < 12; t++)
{
temp = asc2_1206[chr][t];
for (t1 = 0; t1 < 8; t1++)
{
if (temp&0x80)
OLED_draw_point(x, y, PEN_WRITE);
else
OLED_draw_point(x, y, PEN_CLEAR);
temp <<= 1;
y++;
if ((y - y0) == 12)
{
y = y0;
x++;
break;
}
}
}
}
void OLED_show_string(uint8_t row, uint8_t col, uint8_t *chr)
{
uint8_t n =0;
while (chr[n] != '\0')
{
OLED_show_char(row, col, chr[n]);
col++;
if (col > 20)
{
col = 0;
row += 1;
}
n++;
}
}
void OLED_printf(uint8_t row, uint8_t col, const char *fmt,...)
{
static uint8_t LCD_BUF[128] = {0};
static va_list ap;
uint8_t remain_size = 0;
if ((row > 4) || (col > 20) )
{
return;
}
va_start(ap, fmt);
vsprintf((char *)LCD_BUF, fmt, ap);
va_end(ap);
remain_size = 21 - col;
LCD_BUF[remain_size] = '\0';
OLED_show_string(row, col, LCD_BUF);
}
void OLED_refresh_gram(void)
{
uint8_t i, n;
for (i = 0; i < 8; i++)
{
OLED_set_pos(0, i);
for (n = 0; n < 128; n++)
{
oled_write_byte(OLED_GRAM[n][i], OLED_DATA);
}
}
}
OLED.h
#ifndef OLED_H
#define OLED_H
#include <stdint.h>
// the I2C address of oled
#define OLED_I2C_ADDRESS 0x78
//the resolution of oled 128*64
#define MAX_COLUMN 128
#define MAX_ROW 64
#define X_WIDTH MAX_COLUMN
#define Y_WIDTH MAX_ROW
#define OLED_CMD 0x00
#define OLED_DATA 0x01
typedef enum
{
PEN_CLEAR = 0x00,
PEN_WRITE = 0x01,
PEN_INVERSION= 0x02,
}pen_typedef;
extern void OLED_init(void);
extern void OLED_display_on(void);
extern void OLED_display_off(void);
extern void OLED_operate_gram(pen_typedef pen);
extern void OLED_set_pos(uint8_t x, uint8_t y);
extern void OLED_draw_point(int8_t x, int8_t y, pen_typedef pen);
extern void OLED_show_string(uint8_t row, uint8_t col, uint8_t *chr);
extern void OLED_printf(uint8_t row, uint8_t col, const char *fmt,...);
extern void OLED_refresh_gram(void);
extern void OLED_LOGO(void);
#endif
asc.h
#ifndef ASC__H
#define ASC__H
const unsigned char asc2_1206[95][12]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x3F,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x40,0x00,0x00,0x00},/*""",2*/
{0x09,0x00,0x0B,0xC0,0x3D,0x00,0x0B,0xC0,0x3D,0x00,0x09,0x00},/*"#",3*/
{0x18,0xC0,0x24,0x40,0x7F,0xE0,0x22,0x40,0x31,0x80,0x00,0x00},/*"$",4*/
{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/
{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/
{0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x40,0x20},/*"(",8*/
{0x00,0x00,0x40,0x20,0x20,0x40,0x1F,0x80,0x00,0x00,0x00,0x00},/*")",9*/
{0x09,0x00,0x06,0x00,0x1F,0x80,0x06,0x00,0x09,0x00,0x00,0x00},/*"*",10*/
{0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x00,0x00},/*"+",11*/
{0x00,0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/
{0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00},/*"-",13*/
{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/
{0x00,0x20,0x01,0xC0,0x06,0x00,0x38,0x00,0x40,0x00,0x00,0x00},/*"/",15*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"0",16*/
{0x00,0x00,0x10,0x40,0x3F,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"1",17*/
{0x18,0xC0,0x21,0x40,0x22,0x40,0x24,0x40,0x18,0x40,0x00,0x00},/*"2",18*/
{0x10,0x80,0x20,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"3",19*/
{0x02,0x00,0x0D,0x00,0x11,0x00,0x3F,0xC0,0x01,0x40,0x00,0x00},/*"4",20*/
{0x3C,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x23,0x80,0x00,0x00},/*"5",21*/
{0x1F,0x80,0x24,0x40,0x24,0x40,0x34,0x40,0x03,0x80,0x00,0x00},/*"6",22*/
{0x30,0x00,0x20,0x00,0x27,0xC0,0x38,0x00,0x20,0x00,0x00,0x00},/*"7",23*/
{0x1B,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"8",24*/
{0x1C,0x00,0x22,0xC0,0x22,0x40,0x22,0x40,0x1F,0x80,0x00,0x00},/*"9",25*/
{0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/
{0x00,0x00,0x00,0x00,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/
{0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40},/*"<",28*/
{0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00},/*"=",29*/
{0x00,0x00,0x40,0x40,0x20,0x80,0x11,0x00,0x0A,0x00,0x04,0x00},/*">",30*/
{0x18,0x00,0x20,0x00,0x23,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"?",31*/
{0x1F,0x80,0x20,0x40,0x27,0x40,0x29,0x40,0x1F,0x40,0x00,0x00},/*"@",32*/
{0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40},/*"A",33*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"B",34*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x30,0x80,0x00,0x00},/*"C",35*/
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"D",36*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x40,0x30,0xC0,0x00,0x00},/*"E",37*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x00,0x30,0x00,0x00,0x00},/*"F",38*/
{0x0F,0x00,0x10,0x80,0x20,0x40,0x22,0x40,0x33,0x80,0x02,0x00},/*"G",39*/
{0x20,0x40,0x3F,0xC0,0x04,0x00,0x04,0x00,0x3F,0xC0,0x20,0x40},/*"H",40*/
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x00,0x00},/*"I",41*/
{0x00,0x60,0x20,0x20,0x20,0x20,0x3F,0xC0,0x20,0x00,0x20,0x00},/*"J",42*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x0B,0x00,0x30,0xC0,0x20,0x40},/*"K",43*/
{0x20,0x40,0x3F,0xC0,0x20,0x40,0x00,0x40,0x00,0x40,0x00,0xC0},/*"L",44*/
{0x3F,0xC0,0x3C,0x00,0x03,0xC0,0x3C,0x00,0x3F,0xC0,0x00,0x00},/*"M",45*/
{0x20,0x40,0x3F,0xC0,0x0C,0x40,0x23,0x00,0x3F,0xC0,0x20,0x00},/*"N",46*/
{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"O",47*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"P",48*/
{0x1F,0x80,0x21,0x40,0x21,0x40,0x20,0xE0,0x1F,0xA0,0x00,0x00},/*"Q",49*/
{0x20,0x40,0x3F,0xC0,0x24,0x40,0x26,0x00,0x19,0xC0,0x00,0x40},/*"R",50*/
{0x18,0xC0,0x24,0x40,0x24,0x40,0x22,0x40,0x31,0x80,0x00,0x00},/*"S",51*/
{0x30,0x00,0x20,0x40,0x3F,0xC0,0x20,0x40,0x30,0x00,0x00,0x00},/*"T",52*/
{0x20,0x00,0x3F,0x80,0x00,0x40,0x00,0x40,0x3F,0x80,0x20,0x00},/*"U",53*/
{0x20,0x00,0x3E,0x00,0x01,0xC0,0x07,0x00,0x38,0x00,0x20,0x00},/*"V",54*/
{0x38,0x00,0x07,0xC0,0x3C,0x00,0x07,0xC0,0x38,0x00,0x00,0x00},/*"W",55*/
{0x20,0x40,0x39,0xC0,0x06,0x00,0x39,0xC0,0x20,0x40,0x00,0x00},/*"X",56*/
{0x20,0x00,0x38,0x40,0x07,0xC0,0x38,0x40,0x20,0x00,0x00,0x00},/*"Y",57*/
{0x30,0x40,0x21,0xC0,0x26,0x40,0x38,0x40,0x20,0xC0,0x00,0x00},/*"Z",58*/
{0x00,0x00,0x00,0x00,0x7F,0xE0,0x40,0x20,0x40,0x20,0x00,0x00},/*"[",59*/
{0x00,0x00,0x70,0x00,0x0C,0x00,0x03,0x80,0x00,0x40,0x00,0x00},/*"\",60*/
{0x00,0x00,0x40,0x20,0x40,0x20,0x7F,0xE0,0x00,0x00,0x00,0x00},/*"]",61*/
{0x00,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00},/*"^",62*/
{0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10},/*"_",63*/
{0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/
{0x00,0x00,0x02,0x80,0x05,0x40,0x05,0x40,0x03,0xC0,0x00,0x40},/*"a",65*/
{0x20,0x00,0x3F,0xC0,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"b",66*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/
{0x00,0x00,0x03,0x80,0x05,0x40,0x05,0x40,0x03,0x40,0x00,0x00},/*"e",69*/
{0x00,0x00,0x04,0x40,0x1F,0xC0,0x24,0x40,0x24,0x40,0x20,0x00},/*"f",70*/
{0x00,0x00,0x02,0xE0,0x05,0x50,0x05,0x50,0x06,0x50,0x04,0x20},/*"g",71*/
{0x20,0x40,0x3F,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"h",72*/
{0x00,0x00,0x04,0x40,0x27,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"i",73*/
{0x00,0x10,0x00,0x10,0x04,0x10,0x27,0xE0,0x00,0x00,0x00,0x00},/*"j",74*/
{0x20,0x40,0x3F,0xC0,0x01,0x40,0x07,0x00,0x04,0xC0,0x04,0x40},/*"k",75*/
{0x20,0x40,0x20,0x40,0x3F,0xC0,0x00,0x40,0x00,0x40,0x00,0x00},/*"l",76*/
{0x07,0xC0,0x04,0x00,0x07,0xC0,0x04,0x00,0x03,0xC0,0x00,0x00},/*"m",77*/
{0x04,0x40,0x07,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"n",78*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"o",79*/
{0x04,0x10,0x07,0xF0,0x04,0x50,0x04,0x40,0x03,0x80,0x00,0x00},/*"p",80*/
{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x50,0x07,0xF0,0x00,0x10},/*"q",81*/
{0x04,0x40,0x07,0xC0,0x02,0x40,0x04,0x00,0x04,0x00,0x00,0x00},/*"r",82*/
{0x00,0x00,0x06,0x40,0x05,0x40,0x05,0x40,0x04,0xC0,0x00,0x00},/*"s",83*/
{0x00,0x00,0x04,0x00,0x1F,0x80,0x04,0x40,0x00,0x40,0x00,0x00},/*"t",84*/
{0x04,0x00,0x07,0x80,0x00,0x40,0x04,0x40,0x07,0xC0,0x00,0x40},/*"u",85*/
{0x04,0x00,0x07,0x00,0x04,0xC0,0x01,0x80,0x06,0x00,0x04,0x00},/*"v",86*/
{0x06,0x00,0x01,0xC0,0x07,0x00,0x01,0xC0,0x06,0x00,0x00,0x00},/*"w",87*/
{0x04,0x40,0x06,0xC0,0x01,0x00,0x06,0xC0,0x04,0x40,0x00,0x00},/*"x",88*/
{0x04,0x10,0x07,0x10,0x04,0xE0,0x01,0x80,0x06,0x00,0x04,0x00},/*"y",89*/
{0x00,0x00,0x04,0x40,0x05,0xC0,0x06,0x40,0x04,0x40,0x00,0x00},/*"z",90*/
{0x00,0x00,0x00,0x00,0x04,0x00,0x7B,0xE0,0x40,0x20,0x00,0x00},/*"{",91*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x00},/*"|",92*/
{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/
{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/
};
#endif
与之前招新题一样,新建一个文本文档然后改成对应的名字,然后把代码复制进去,然后.c放在src,.h放在inc
代码解释
- oled.h
这个就是我们之前提到的IIC的设备地址,我们可以看到本博客开始时的OLED示例中的
这个就是生产厂家给出的地址选择,一共有两个可选项,想使用哪个就把电阻焊在哪一端,在这里我们可以看出地址是用的0x78 - asc.h
这个里面主要存的是字库,就是每种字符对应的都是哪些像素点亮,如果想要修改字符的字体就需要修改这个文件。 - oled.c
在本博客的配置中,我们选择的是单片机的硬件IIC,是片内集成的IIC,配置起来较为方便,缺点是不太自由,需要使用固定的引脚。也可以通过GPIO模拟IIC通信时序,这个就比较自由,只要有GPIO功能的引脚就可以,缺点就是需要自己写通信驱动。由于c6t6上只有一个硬件IIC,即i2c1,于是这里写i2c1,如果你使用的是其他单片机,就要注意这里的i2c要与你配置的i2c一致。
这个函数就是向OLED通信的函数,最下面的HAL_I2C_Master_Transmit便是HAL库封装的IIC通信函数,可以看到是需要指明从机地址的
- 其余常用函数的简单介绍
OLED_init(void) 初始化函数,在主程序的前面要加上来初始化OLED
OLED_display_on(void),OLED_display_off(void) OLED屏幕显示与关闭
OLED_operate_gram(pen_typedef pen) 将整个屏幕点亮或点灭,可以用来清屏
OLED_draw_point(int8_t x, int8_t y, pen_typedef pen) 画点
OLED_draw_line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, pen_typedef pen) 画线
OLED_show_char(uint8_t row, uint8_t col, uint8_t chr) 绘出一个字符
OLED_show_string(uint8_t row, uint8_t col, uint8_t *chr) 绘出一个字符串
OLED_refresh_gram(void)
这个就比较重要了,是更新函数,在前面的很多个OLED的控制函数,都是对一个数组OLED_GRAM的修改,这个二维数组控制的就是屏幕上每个像素点的亮灭与否,而数组的修改是不会让屏幕更改的,如果想让屏幕修改就必须要在后面加上这个函数,将数组的值更新到屏幕上。这样做的好处就是可以处理完好几个函数后再更新,让显示更流畅。
PS:注意pen_typedef pen这个参数填的是0与1,控制的就是亮和灭,另外字符的显示是8x128,即行的位置是固定的8个地方,而列则可以从128中任意地方开始显示,所以row的范围是0-7,col是0-127.
代码配置与生成
有关于工程的生成不再赘述,直接开始配置IIC
如图所示,选择硬件IIC,可以看到右边出现了IIC的引脚,与OLED上对应引脚相连即可。
然后更新代码
将头文件include进去
在主程序中添加如图代码,分别进行初始化,打开显示,将整个屏幕点灭也就是清屏(OLED上电后会花屏,所以先清一下)。
然后用show_string函数在第二行第二列显示一串字符串。此时只是对数组进行了修改,还需要再加上refresh函数将数组更新到屏幕上。
效果如下
总结
本文简单介绍了OLED的使用,希望同学们可以理解原理并实现显示,另外,有关于OLED还有个更为强大的库——U8G2,这个库有很多优化与更多绘制的函数,也有很多预制好的字体样式,推荐想要用OLED做的更加美观的同学自行学习,这里提供一个讲解的博客
训练题——OLED部分的更多相关文章
- X-NUCA 2017 web专题赛训练题 阳光总在风雨后和default wp
0X0.前言 X-NUCA 2017来了,想起2016 web专题赛,题目都打不开,希望这次主办方能够搞好点吧!还没开赛,依照惯例会有赛前指导,放一些训练题让CTFer们好感受一下题目. 题目有一大 ...
- PAT乙级真题及训练题 1025. 反转链表 (25)
PAT乙级真题及训练题 1025. 反转链表 (25) 感觉几个世纪没打代码了,真是坏习惯,调了两小时把反转链表调出来了,心情舒畅. 这道题的步骤 数据输入,数组纪录下一结点及储存值 创建链表并储存上 ...
- 日常 java+雅思+训练题1
今天主要学了一些类似c中的一些语句,java也是一样类似的,只有一些点需要稍微注意一下,一些语句是新增的需要知道. 完完全全新学的知识就是class和instance的区别.如何创建实例.数据的封装. ...
- java基础集合经典训练题
第一题:要求产生10个随机的字符串,每一个字符串互相不重复,每一个字符串中组成的字符(a-zA-Z0-9)也不相同,每个字符串长度为10; 分析:*1.看到这个题目,或许你脑海中会想到很多方法,比如判 ...
- 2016huas暑假集训训练题 G-Who's in the Middle
题目链接:http://acm.hust.edu.cn/vjudge/contest/121192#problem/G 此题大意是给定一个数n 然后有n个数 要求求出其中位数 刚开始以为是按数学中的 ...
- 2016HUAS暑假集训训练题 G - Oil Deposits
Description The GeoSurvComp geologic survey company is responsible for detecting underground oil dep ...
- c语言训练题:关于张三李四王五说谎的问题(此处用javascript实现)
(第一篇博文) 今天在一个交流群里见他们无聊,然后找到之前收藏的一些c语言题目放出去想让他们做,结果反倒是自己不会做,于是花了很多时间去想. 原题:张三说李四在说谎,李四说王五在说谎,王五说张三和李四 ...
- 中南大学2018年ACM暑期集训前期训练题集(入门题) X: 又一道简单题
简直智障,上一题V题,样例输出里面的“Case:”不要输出,到了这题又是要输出的了 #include<iostream> using namespace std; int num[1000 ...
- 中南大学2018年ACM暑期集训前期训练题集(入门题) J : A Simple Problem
毒瘤哇!为什么要用long long 啊!!!这个题没有加法操作啊,为什么会爆int啊!!!! 思路: http://www.cnblogs.com/buerdepepeqi/p/9048130.ht ...
- 树状数组训练题1:弱弱的战壕(vijos1066)
题目链接:弱弱的战壕 这道题似乎是vijos上能找到的最简单的树状数组题了. 原来,我有一个错误的思想,我的设计是维护两个树状数组,一个是横坐标,一个是纵坐标,然后读入每个点的坐标,扔进对应的树状数组 ...
随机推荐
- centos7下的防火墙部署
iptables以及firewalld其实都是防火墙管理工具,说白一点,就是一个服务,用来保障公网与内网 iptables 由于centos7没有自带,需要自己安装 安装 yum install ip ...
- 18.SQLite应用案例-课程表
一.程序界面 1.课程表首页 一周有7天,一天有10节课. 课程表首页的布局activity_main.xml框架设计大致如此: 最外层使用线性布局设置屏幕水平方向android:orientatio ...
- ES-增删改查
写作目的 供想了解ES数据操作的伙伴学习ES的CRUD操作. 测试环境 ES7.8.1 postman 创建索引库 // PUT请求 localhost:9200/test_alert { " ...
- hex 函数
python的内置函数. 一.作用: 用于将十进制数改为十六进制数,并以字符串的形式表示. 二.语法: hex(number) # 其中number为十进制的整数. 三.返回值: 以字符串形式表示的 ...
- 查看linux 用户
sudo cat /etc/passwd|grep -v nologin|grep -v halt|grep -v shutdown|awk -F":" '{ print $1}' ...
- Oracle一次插入多条数据
Oracle一次插入多条数据(批量插入)语法:INSERT ALL INTO tableName (column1, column2, column_n) VALUES (expr1, expr2, ...
- 日志参数 %n 引起的coredump
今天测试发现一段代码 coredump,居然是一行日志输出.看参数都乱了,以为是内存溢出造成的.查了半天,也没发现问题 最后把前边的函数调用都注释掉,只运行这一段日志输出,依然挂掉 仔细一看: TRA ...
- windos下激活python虚拟环境
1.从终端中找到解释器的目录 2.cd到Scripts,输入激活命令activate 这样就表示激活成功了
- CUDA kernel使用printf调试,一定要加cudaDeviceSynchronize
#include <stdio.h> __global__ void print() { printf("Hello from (%d, %d)\n", blockId ...
- Mac聚焦搜索无法搜索应用问题处理
问题描述 打开聚焦搜索(快捷键:command + space)后,发现安装的应用搜索不到. 参考文章 https://blog.csdn.net/fox_lori/article/details/1 ...