ESP32驱动0.96寸OLED(自制画图库)


使用软件和硬件:
ESPidf 版本4.4
ESP32采用 ESP32_WROOM32
OLED采用的I IC接口的OLED,如下图所示
在这里插入图片描述

相关函数

esp_err_t iic_init(void);
void iic_sendData(uint8_t HWaddress,uint8_t RGaddress,uint8_t data);


void oled_init(oled_init_params_t * oled_params);
void oled_sendCom(uint8_t Com);
void oled_sendData(uint8_t *Dat,uint16_t size);
void oled_fill(uint8_t data);

void oled_point(uint8_t x, uint8_t y,bool cover);
void oled_line(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,bool cover);
void oled_rectangle(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,bool cover);
void oled_circle(uint8_t x1,uint8_t y1,uint8_t r,bool cover);
void oled_printf(uint8_t x1,uint8_t y1,char *string,bool cover);

void oled_rectangle_inverse(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2);
void oled_line_figure(char *title,uint8_t title_size,uint8_t *figure_data,uint8_t size);
void oled_point_figure_f(char *title,float *figure_data,uint8_t data_min,uint8_t data_range);
void oled_line_figure_f(char *title,uint8_t title_size,float *figure_data,uint8_t size,uint8_t y_range);
void oled_display_off(void);
void oled_display_on(void);
void oled_rom_printf(void);
void oled_show_err(const char* s1,const char* s2,const char* s3);

软件讲解

在这里插入图片描述

OLED显示采用的寻址模式为按页寻址,也就是先要发送从哪个PAGE开始的命令和从那一列开始的命令,由于一个PAGE代表8行,所以一个byte就代表了一个PAGE和一列数码管,其中高位在沿着低PAGE方向。在初始化之后就能开始画点画线再进行刷新就能够显示了。
在OLED的绘画操作都是由最基本的画点函数完成的。由于上述已经将OLED的整个显示屏显存GGDRRAM都由一个固定的数组ROM定义出来了,提高刷新率最快的办法就是把整个屏幕的RAM都定义出来:

uint8_t ROM[8][128];

所以在画点时只需要对这个数组进行操作就行了。用x,y作为函数的参数来设定位置,用cover来表示这个点是否需要覆盖,然后用y/8来表示对应的PAGE,再在这个基础上,如果不需要覆盖,就将数组与操作(1<<(y%8)),如果需要赋值,就直接将数组赋值为(1<<(y%8)),这样就能精确到显示屏的一个点了。

void oled_point(uint8_t x, uint8_t y,bool cover) 
{
    if (x > 127 || y > 63) 
	{
		printf("Error:x %d,y %d,range error 0<x<128 0<y<64\n",x,y);
        return;
    }
	if(cover) ROM[y/8][x]=(1<<(y%8));
	else ROM[y/8][x] |=(1<<(y%8));
}

完整代码

my_codetab.h

#ifndef __my_codetab_h_
#define __my_codetab_h_

/*  (0) !(1) "(2) #(3) $(4) %(5) &(6) '(7) ((8) )(9)
 *(10) +(11) ,(12) -(13) .(14) /(15) 0(16) 1(17) 2(18) 3(19)
 4(20) 5(21) 6(22) 7(23) 8(24) 9(25) :(26) ;(27) <(28) =(29)
 >(30) ?(31) @(32) A(33) B(34) C(35) D(36) E(37) F(38) G(39)
 H(40) I(41) J(42) K(43) L(44) M(45) N(46) O(47) P(48) Q(49)
 R(50) S(51) T(52) U(53) V(54) W(55) X(56) Y(57) Z(58) [(59)
 \(60) ](61) ^(62) _(63) `(64) a(65) b(66) c(67) d(68) e(69)
 f(70) g(71) h(72) i(73) j(74) k(75) l(76) m(77) n(78) o(79)
 p(80) q(81) r(82) s(83) t(84) u(85) v(86) w(87) x(88) y(89)
 z(90) {(91) |(92) }(93) ~(94)*/

const unsigned char str_code12_24[95][16]=
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/

{0x00,0x00,0x00,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x31,0x00,0x00,0x00},/*"!",1*/

{0x00,0x00,0x38,0x08,0x08,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/

{0x40,0x40,0xF8,0x40,0x40,0xF0,0x48,0x40,0x04,0x3C,0x07,0x04,0x34,0x0F,0x04,0x04},/*"#",3*/

{0x00,0x70,0xD8,0xFC,0x08,0x38,0x20,0x00,0x00,0x1C,0x30,0x7F,0x21,0x1F,0x0E,0x00},/*"$",4*/

{0x70,0x88,0xF8,0x40,0xE0,0x18,0x00,0x00,0x00,0x30,0x0C,0x03,0x1E,0x21,0x3F,0x00},/*"%",5*/

{0x00,0x00,0xF8,0x88,0x78,0x30,0x00,0x00,0x0C,0x1F,0x31,0x23,0x34,0x18,0x1E,0x10},/*"&",6*/

{0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/

{0x00,0x00,0x00,0x00,0xF0,0x18,0x04,0x00,0x00,0x00,0x00,0x00,0x0F,0x30,0x40,0x00},/*"(",8*/

{0x00,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x60,0x30,0x0F,0x00,0x00,0x00,0x00},/*")",9*/

{0x00,0x20,0xA0,0xF8,0xF8,0xA0,0x20,0x00,0x00,0x01,0x00,0x07,0x07,0x00,0x01,0x00},/*"*",10*/

{0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0F,0x01,0x01,0x01,0x01},/*"+",11*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB0,0x70,0x00,0x00,0x00,0x00,0x00},/*",",12*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00},/*"-",13*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00},/*".",14*/

{0x00,0x00,0x00,0x00,0xC0,0x30,0x08,0x00,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x00},/*"/",15*/

{0x00,0xF0,0x18,0x08,0x08,0x18,0xE0,0x00,0x00,0x0F,0x10,0x20,0x30,0x18,0x0F,0x00},/*"0",16*/

{0x00,0x60,0x20,0xF0,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00},/*"1",17*/

{0x00,0x30,0x18,0x08,0x08,0xD8,0x70,0x00,0x00,0x30,0x38,0x34,0x33,0x31,0x30,0x00},/*"2",18*/

{0x00,0x30,0x18,0x08,0x88,0xD8,0x70,0x00,0x00,0x18,0x10,0x20,0x21,0x13,0x0E,0x00},/*"3",19*/

{0x00,0x00,0x80,0x60,0x30,0xF8,0x00,0x00,0x04,0x07,0x05,0x04,0x04,0x3F,0x04,0x04},/*"4",20*/

{0x00,0xF0,0x98,0xC8,0x88,0x88,0x08,0x00,0x08,0x19,0x30,0x20,0x30,0x19,0x0F,0x00},/*"5",21*/

{0x00,0x80,0xC0,0xF0,0x98,0x80,0x00,0x00,0x00,0x1F,0x31,0x20,0x20,0x30,0x1F,0x06},/*"6",22*/

{0x00,0x08,0x08,0x08,0x88,0xE8,0x38,0x00,0x00,0x00,0x30,0x3E,0x03,0x00,0x00,0x00},/*"7",23*/

{0x00,0xF0,0x88,0x88,0x88,0xD8,0x70,0x00,0x04,0x1F,0x31,0x21,0x21,0x31,0x1E,0x00},/*"8",24*/

{0xE0,0xF0,0x08,0x08,0x08,0x98,0xF0,0x00,0x00,0x01,0x23,0x3A,0x0F,0x03,0x00,0x00},/*"9",25*/

{0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x11,0x00,0x00,0x00},/*":",26*/

{0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF1,0x31,0x00,0x00,0x00},/*";",27*/

{0x00,0x80,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00},/*"<",28*/

{0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00},/*"=",29*/

{0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x30,0x10,0x08,0x04,0x02,0x01,0x00},/*">",30*/

{0x00,0x30,0x18,0x08,0x88,0xF8,0x70,0x00,0x00,0x00,0x00,0x32,0x11,0x00,0x00,0x00},/*"?",31*/

{0xE0,0x10,0x88,0x68,0x28,0xE8,0xF0,0x00,0x0F,0x10,0x27,0x28,0x27,0x28,0x07,0x00},/*"@",32*/

{0x00,0x00,0xC0,0x78,0x78,0xC0,0x00,0x00,0x20,0x3E,0x07,0x02,0x02,0x07,0x3C,0x20},/*"A",33*/

{0x00,0xF8,0x88,0x88,0x88,0x98,0x70,0x00,0x00,0x3F,0x31,0x31,0x31,0x11,0x1E,0x00},/*"B",34*/

{0x00,0xF0,0x18,0x08,0x08,0x18,0x70,0x00,0x00,0x0F,0x18,0x30,0x20,0x30,0x1E,0x00},/*"C",35*/

{0x00,0xF8,0x08,0x08,0x18,0x30,0xE0,0x00,0x00,0x3F,0x30,0x30,0x10,0x18,0x0F,0x00},/*"D",36*/

{0x00,0xF8,0x88,0x88,0x88,0x88,0x88,0x00,0x00,0x3F,0x31,0x31,0x31,0x31,0x31,0x00},/*"E",37*/

{0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x3F,0x01,0x01,0x01,0x01,0x00,0x00},/*"F",38*/

{0x00,0xF0,0x18,0x08,0x08,0x18,0x70,0x00,0x00,0x0F,0x18,0x30,0x23,0x13,0x3F,0x00},/*"G",39*/

{0x00,0xF8,0x80,0x80,0x80,0x80,0xF8,0x00,0x00,0x3F,0x01,0x01,0x01,0x01,0x3F,0x00},/*"H",40*/

{0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00},/*"I",41*/

{0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x1C,0x30,0x30,0x30,0x18,0x0F,0x00},/*"J",42*/

{0x00,0xF8,0x80,0xC0,0x60,0x18,0x08,0x00,0x00,0x3F,0x01,0x01,0x07,0x1C,0x30,0x20},/*"K",43*/

{0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x30,0x30,0x30,0x30,0x00},/*"L",44*/

{0x00,0xF8,0xF8,0x00,0x80,0xF8,0xF8,0x00,0x00,0x3F,0x01,0x3F,0x1F,0x00,0x3F,0x00},/*"M",45*/

{0x00,0xF8,0x70,0xC0,0x00,0x00,0xF8,0x00,0x00,0x3F,0x00,0x01,0x07,0x3C,0x3F,0x00},/*"N",46*/

{0x80,0xF0,0x18,0x08,0x08,0x18,0xF0,0x00,0x03,0x1F,0x10,0x20,0x20,0x18,0x0F,0x00},/*"O",47*/

{0x00,0xF8,0x08,0x08,0x08,0x18,0xF0,0x00,0x00,0x3F,0x03,0x03,0x01,0x01,0x01,0x00},/*"P",48*/

{0x80,0xF0,0x18,0x08,0x08,0x18,0xF0,0x00,0x03,0x1F,0x10,0x20,0x2C,0x38,0x2F,0x00},/*"Q",49*/

{0x00,0xF8,0x08,0x08,0x08,0x98,0xF0,0x00,0x00,0x3F,0x01,0x01,0x07,0x1D,0x30,0x00},/*"R",50*/

{0x00,0x70,0xD8,0x88,0x08,0x38,0x30,0x00,0x00,0x1C,0x30,0x21,0x21,0x33,0x1E,0x00},/*"S",51*/

{0x00,0x08,0x08,0xF8,0xF8,0x08,0x08,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00},/*"T",52*/

{0x00,0xF8,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x1F,0x30,0x20,0x20,0x30,0x1F,0x00},/*"U",53*/

{0x08,0xF8,0xC0,0x00,0x00,0xE0,0x78,0x00,0x00,0x00,0x07,0x3C,0x3E,0x03,0x00,0x00},/*"V",54*/

{0x38,0xF0,0x00,0xF8,0xF8,0x00,0xF8,0x08,0x00,0x3F,0x3F,0x00,0x03,0x3C,0x0F,0x00},/*"W",55*/

{0x00,0x18,0x70,0xC0,0xC0,0x38,0x08,0x00,0x20,0x38,0x0E,0x03,0x07,0x1C,0x30,0x00},/*"X",56*/

{0x08,0x38,0xE0,0x80,0xC0,0x70,0x18,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00},/*"Y",57*/

{0x00,0x08,0x08,0x08,0xC8,0x78,0x18,0x00,0x00,0x38,0x3E,0x33,0x30,0x30,0x30,0x00},/*"Z",58*/

{0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00},/*"[",59*/

{0x00,0x08,0x70,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x30,0xC0,0x00},/*"\",60*/

{0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00},/*"]",61*/

{0x00,0x08,0x04,0x02,0x06,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},/*"_",63*/

{0x00,0x00,0x02,0x06,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/

{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1D,0x24,0x24,0x32,0x1F,0x3F,0x00},/*"a",65*/

{0x00,0xF8,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x3F,0x10,0x20,0x20,0x19,0x1F,0x00},/*"b",66*/

{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x30,0x20,0x20,0x11,0x19,0x00},/*"c",67*/

{0x00,0x80,0x80,0x80,0x80,0x80,0xF8,0x00,0x00,0x1F,0x30,0x20,0x20,0x19,0x3F,0x00},/*"d",68*/

{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x12,0x22,0x22,0x33,0x1B,0x00},/*"e",69*/

{0x00,0x80,0x80,0xF8,0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00},/*"f",70*/

{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0xFB,0x94,0x94,0x94,0xB7,0x60,0x00},/*"g",71*/

{0x00,0xF8,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x3F,0x01,0x00,0x00,0x00,0x3F,0x00},/*"h",72*/

{0x00,0x00,0x00,0x98,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00},/*"i",73*/

{0x00,0x00,0x00,0x00,0x88,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0xFF,0x7F,0x00,0x00},/*"j",74*/

{0x00,0xF8,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x3F,0x06,0x03,0x07,0x18,0x30,0x00},/*"k",75*/

{0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00},/*"l",76*/

{0x80,0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x3F,0x3F,0x00,0x3F,0x3F,0x00,0x3F,0x3F},/*"m",77*/

{0x00,0x80,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x3F,0x01,0x00,0x00,0x00,0x3F,0x00},/*"n",78*/

{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x10,0x20,0x20,0x11,0x1F,0x00},/*"o",79*/

{0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0xFF,0x10,0x20,0x20,0x19,0x1F,0x00},/*"p",80*/

{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x1F,0x30,0x20,0x20,0x19,0xFF,0x00},/*"q",81*/

{0x00,0x00,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x01,0x00,0x00,0x00,0x00},/*"r",82*/

{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1B,0x33,0x24,0x24,0x35,0x19,0x00},/*"s",83*/

{0x80,0x80,0x80,0xF0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x30,0x00},/*"t",84*/

{0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x1F,0x30,0x20,0x30,0x18,0x3F,0x00},/*"u",85*/

{0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x01,0x0F,0x38,0x38,0x07,0x01,0x00},/*"v",86*/

{0x80,0x80,0x00,0x80,0x80,0x00,0x80,0x80,0x01,0x1F,0x3C,0x03,0x07,0x38,0x0F,0x00},/*"w",87*/

{0x00,0x80,0x80,0x00,0x00,0x80,0x00,0x00,0x00,0x30,0x19,0x0E,0x0F,0x19,0x20,0x00},/*"x",88*/

{0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x81,0x8F,0xF8,0x38,0x07,0x01,0x00},/*"y",89*/

{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x30,0x38,0x24,0x23,0x21,0x20,0x00},/*"z",90*/

{0x00,0x00,0x00,0x00,0xFC,0xFE,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x7E,0x00,0x00},/*"{",91*/

{0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00},/*"|",92*/

{0x00,0x02,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x01,0x00,0x00,0x00,0x00},/*"}",93*/

{0x00,0x06,0x03,0x02,0x04,0x04,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}};/*"~",94*/
#endif

my_oled.h

#ifndef __my_oled_h_
#define __my_oled_h_

#include "driver/gpio.h"
#include "driver/i2c.h"
#include "freertos/task.h"
#include "string.h"

#define OLED_I2C_SDA_IO 18          //I2C SDA GPIO Number   
#define OLED_I2C_SCL_IO 19          //I2C SCL GPIO Number    
#define I2C_MASTER_NUM 0         //OLED ʹ�õ� I2C ������
#define OLED_I2C_FREQ 400000        //OLED ��Ӧ I2C ʱ��  
#define OLED_ADDR 0x78              //OLED I2C ������ַ    

#define I2C_MASTER_RX_BUF_DISABLE 0
#define I2C_MASTER_TX_BUF_DISABLE 0

typedef enum{
    OLED_MODE1_BLE_SELECT,
    OLED_MODE1_BREATH_F_SELECT,
    OLED_MODE1_HEART_F_SELECT,
    OLED_MODE1_SET_W_SELECT,

    OLED_MODE2_BREATH_F,
    OLED_MODE2_HEART_F,    
    OLED_MODE2_BREATH_W_SELECT,
    OLED_MODE2_HEART_W_SELECT,
    OLED_MODE2_QUIT_W_SELECT,

    OLED_MODE3_BREATH_HW_SELECT,
    OLED_MODE3_BREATH_LW_SELECT,
    OLED_MODE3_QUIT_BW_SELECT,
    OLED_MODE3_HEART_HW_SELECT,
    OLED_MODE3_HEART_LW_SELECT,
    OLED_MODE3_QUIT_HW_SELECT,

    OLED_MODE_VALUE_C_BREATHH,
    OLED_MODE_VALUE_C_BREATHL,   
    OLED_MODE_VALUE_C_HEARTH,
    OLED_MODE_VALUE_C_HEARTL,

    OLED_MODE_WARNING_BREATH_H,
    OLED_MODE_WARNING_BREATH_L,
    OLED_MODE_WARNING_HEART_H,
    OLED_MODE_WARNING_HEART_L,
}oled_mode_enum;

typedef struct {
    uint8_t contrast;     
    bool lateral_flip;   
    bool longitudinal_flip;
    bool inverse;  
} oled_init_params_t;

uint8_t ROM[8][128];

void oled_refresh(void);

esp_err_t iic_init(void);
void iic_sendData(uint8_t HWaddress,uint8_t RGaddress,uint8_t data);


void oled_init(oled_init_params_t * oled_params);
void oled_sendCom(uint8_t Com);
void oled_sendData(uint8_t *Dat,uint16_t size);
void oled_fill(uint8_t data);

void oled_point(uint8_t x, uint8_t y,bool cover);
void oled_line(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,bool cover);
void oled_rectangle(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,bool cover);
void oled_circle(uint8_t x1,uint8_t y1,uint8_t r,bool cover);
void oled_printf(uint8_t x1,uint8_t y1,char *string,bool cover);

void oled_rectangle_inverse(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2);
void oled_line_figure(char *title,uint8_t title_size,uint8_t *figure_data,uint8_t size);
void oled_point_figure_f(char *title,float *figure_data,uint8_t data_min,uint8_t data_range);
void oled_line_figure_f(char *title,uint8_t title_size,float *figure_data,uint8_t size,uint8_t y_range);
void oled_display_off(void);
void oled_display_on(void);
void oled_rom_printf(void);
void oled_show_err(const char* s1,const char* s2,const char* s3);

#endif


my_oled.c

#include "my_oled.h"
#include "my_codetab.h"

void oled_show_err(const char* s1,const char* s2,const char* s3)
{
	oled_fill(0x11);
	oled_printf(0,0,s1,1);
	oled_printf(0,24,s2,1);
	oled_printf(0,48,s3,1);
	oled_rectangle_inverse(0,0,127,63);
}

void oled_rectangle_inverse(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2)
{
	uint8_t max_x;
	uint8_t max_y;
	uint8_t min_x;
	uint8_t min_y;
	uint8_t value;

	if(x1>x2){max_x=x1;min_x=x2;}
	else {max_x=x2;min_x=x1;}
	if(y1>y2){max_y=y1;min_y=y2;}
	else {max_y=y2;min_y=y1;}

    if (x1 > 127 || y1 > 63) 
	{
		printf("Error:x,y range error 0<x<128 0<y<64");
        return;
    }
	uint8_t low_column=(min_y+1)/8;
	uint8_t high_column=(max_y+1)/8;
	for (int i = low_column; i < high_column; i++)
	{
		for (int j = min_x; j < max_x; j++)
		{	
			ROM[i][j]=~ROM[i][j];
		}
	}
}



void oled_point_figure_f(char *title,float *figure_data,uint8_t data_min,uint8_t data_range)
{	
	oled_printf(0,0,title,1);
	oled_line(0,15,0,63,0); //����
	oled_line(0,63,127,63,0); //����

	float y_range=63.0-16.0;
	float y_reflection=y_range/data_range;
	for (int i = 0; i <128; i++)
	{
		if (figure_data[i]<data_min) oled_point(i,63,0);
		else if (figure_data[i]>(data_min+data_range)) oled_point(i,16,0);
		else 
		{
			oled_point(i,(63-(uint8_t)(figure_data[i]-data_min)*y_reflection),0);
			if(i!=127)
			{
				if(figure_data[i+1]<data_min)
					oled_line(i,(63-(uint8_t)(figure_data[i]-data_min)*y_reflection),i,63,0);
				else if (figure_data[i+1]>(data_min+data_range))
					oled_line(i,(63-(uint8_t)(figure_data[i]-data_min)*y_reflection),i,16,0);
				else
					oled_line(i,(63-(uint8_t)(figure_data[i]-data_min)*y_reflection),i,(63-(uint8_t)(figure_data[i+1]-data_min)*y_reflection),0);
			}
		}
	}
		
}

void oled_line_figure_f(char *title,uint8_t title_size,float *figure_data,uint8_t size,uint8_t y_range)
{
	uint8_t x_range=127/(size-1);
	float y_reflection=47.0/y_range;
	uint8_t title_x=(128-(title_size*8))/2;
	oled_printf(title_x,0,title,1);
	oled_line(0,15,0,63,0); //����
	oled_line(0,63,127,63,0); //����
	for (int i = 0; i < size-1; i++)
	{
		oled_line(i*x_range,(uint8_t)(63-(uint8_t)(figure_data[i]*y_reflection)),
		(i+1)*x_range,(uint8_t)(63-(uint8_t)(figure_data[i+1]*y_reflection)),0);
	}	
}

void oled_line_figure(char *title,uint8_t title_size,uint8_t *figure_data,uint8_t size)
{
	uint8_t x_range=127/(size-1);
	float y_reflection=47.0/255;
	uint8_t title_x=(128-(title_size*8))/2;
	oled_printf(title_x,0,title,1);
	oled_line(0,15,0,63,0); //����
	oled_line(0,63,127,63,0); //����
	for (int i = 0; i < size-1; i++)
	{
		oled_line(i*x_range,(63-(uint8_t)(figure_data[i]*y_reflection)),
		(i+1)*x_range,(63-(uint8_t)(figure_data[i+1]*y_reflection)),0);
	}	
}

void oled_rom_printf(void)
{
	printf("-----------------------------------------------------------------------------------------------------------------------\n");
	for (int i = 0; i < 8; i++)
	{
		printf("|NO%d |: ",i);
		for (int j = 0; j < 128; j++)
		{
			printf("0x%x ",ROM[i][j]);
		}
		printf("\n");
	}
	printf("---------------------------------------------------------------------------------------------------------------------\n");
}

esp_err_t iic_init(void)
{
    int i2c_master_port = I2C_MASTER_NUM;

    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = OLED_I2C_SDA_IO,
        .scl_io_num = OLED_I2C_SCL_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = OLED_I2C_FREQ,
    };

    i2c_param_config(i2c_master_port, &conf);

    return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}


void iic_sendData(uint8_t HWaddress,uint8_t RGaddress,uint8_t data)
{
    uint8_t data_buf[2]={RGaddress,data};
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, HWaddress&0xFE, 1);
    i2c_master_write(cmd, data_buf, sizeof(data_buf), 1);
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);    
}



void oled_printf(uint8_t x1,uint8_t y1,char *string,bool cover)
{
    if (x1 > 127 || y1 > 63) 
	{
		printf("Error:x,y range error 0<x<128 0<y<64");
        return;
    }
	uint8_t lower_column=(y1/8);
	uint8_t len=0;
	while(*string != '\0')
	{
		for(uint8_t i=lower_column;i <= lower_column+2;i++)
		{	
			if(i==lower_column)
			{ 
				for (uint8_t j = 0; j <8; j++)
				{
					if(cover) ROM[i][x1+8*len+j] =(str_code12_24[(uint8_t)(*string)-32][j]<<(y1%8));
					else ROM[i][x1+8*len+j] |=(str_code12_24[(uint8_t)(*string)-32][j]<<(y1%8));
				}
			}
			else if(i==(lower_column+1))
			{ 
				for (uint8_t j =0; j <8; j++)
				{
					if(cover) ROM[i][x1+8*len+j] =((str_code12_24[(uint8_t)(*string)-32][j]>>(8-(y1%8)))|
					(str_code12_24[(uint8_t)(*string)-32][j+8]<<((y1+8)%8)));
					else ROM[i][x1+8*len+j] |=((str_code12_24[(uint8_t)(*string)-32][j]>>(8-(y1%8)))|
					(str_code12_24[(uint8_t)(*string)-32][j+8]<<((y1+8)%8)));
				}
			}
			else
			{
				for (uint8_t j =0; j <8; j++)
				{
					if(cover) ROM[i][x1+8*len+j] =(str_code12_24[(uint8_t)(*string)-32][j+8]>>(8-(y1+16)%8));
					else ROM[i][x1+8*len+j] |=(str_code12_24[(uint8_t)(*string)-32][j+8]>>(8-(y1+16)%8));
				}				
			}
		}
		len++;
		string++;	
	}	
}

void oled_circle(uint8_t x1,uint8_t y1,uint8_t r,bool cover)
{
	
}

/*
(x1,y1)----------(x2,y1)
	-              -
	-              -
	-              -
(x1,y2)--------(x2,y2)

*/
void oled_rectangle(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,bool cover)
{
	oled_line(x1,y1,x2,y1,cover);
	oled_line(x1,y2,x2,y2,cover);
	oled_line(x1,y1,x1,y2,cover);
	oled_line(x2,y1,x2,y2,cover);
}


void oled_line(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,bool cover)
{
	uint8_t max_x;
	uint8_t max_y;
	uint8_t min_x;
	uint8_t min_y;
	
	if(x1>x2){max_x=x1;min_x=x2;}
	else {max_x=x2;min_x=x1;}
	if(y1>y2){max_y=y1;min_y=y2;}
	else {max_y=y2;min_y=y1;}
	
    if (max_x > 127 || max_y > 63) 
	{
		printf("Error:x %d,y %d,range error 0<x<128 0<y<64\n",max_x,max_y);
        return;
    }
	

	if((x1==x2))
	{
		for (uint8_t i = min_y; i < max_y; i++)
		{
			oled_point(x1,i,cover);
		}	
	}
	else if(y1==y2)
	{
		for (uint8_t i = min_x; i < max_x; i++)
		{
			oled_point(i,y1,cover);
		}	
	}
	else
	{
		float tan;
		tan=((float)(y2-y1))/((float)(x2-x1));
		if (tan>0)
		{
			for (uint8_t i = min_x; i < max_x; i++)
			{
				oled_point(i,min_y+(int)(tan*(i-min_x)),cover);
			}
		}
		else
		{
			for (uint8_t i = min_x; i < max_x; i++)
			{
				oled_point(i,max_y+(int)(tan*(i-min_x)),cover);
			}
		}
	}
}



void oled_point(uint8_t x, uint8_t y,bool cover) 
{
    if (x > 127 || y > 63) 
	{
		printf("Error:x %d,y %d,range error 0<x<128 0<y<64\n",x,y);
        return;
    }
	if(cover) ROM[y/8][x]=(1<<(y%8));
	else ROM[y/8][x] |=(1<<(y%8));
}


void oled_init(oled_init_params_t * oled_params)
{
    iic_init();
	vTaskDelay(200 / portTICK_PERIOD_MS);
	oled_sendCom(0xAE); //display off
	oled_sendCom(0x20);	//Set Memory Addressing Mode	
	oled_sendCom(0x10);	//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
	oled_sendCom(0xb0);	//Set Page Start Address for Page Addressing Mode,0-7
	oled_sendCom(0x00); //---set low column address
	oled_sendCom(0x10); //---set high column address

	oled_sendCom(0x40); //--set start line address
	oled_sendCom(0x81); //--set contrast control register
	oled_sendCom(oled_params->contrast); //���ȵ��� 0x00~0xff
	if(oled_params->longitudinal_flip) oled_sendCom(0xc0);	//-���·�ת c0 c8
	else oled_sendCom(0xc8);
	if(oled_params->lateral_flip) oled_sendCom(0xa0); //--���ҷ�ת a0 a1
	else oled_sendCom(0xa1);
	if(oled_params->inverse) oled_sendCom(0xa7);
	else oled_sendCom(0xa6); //--set normal display
	oled_sendCom(0xa8); //--set multiplex ratio(1 to 64)
	oled_sendCom(0x3F); //
	oled_sendCom(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content

	oled_sendCom(0xd3); //-set display offset
	oled_sendCom(0x00); //-not offset

	oled_sendCom(0xd5); //--set display clock divide ratio/oscillator frequency
	oled_sendCom(0xf0); //--set divide ratio
	oled_sendCom(0xd9); //--set pre-charge period
	oled_sendCom(0x22); //
	oled_sendCom(0xda); //--set com pins hardware configuration
	oled_sendCom(0x12);
	oled_sendCom(0xdb); //--set vcomh
	oled_sendCom(0x20); //0x20,0.77xVcc
	oled_sendCom(0x8d); //--set DC-DC enable
	oled_sendCom(0x14); //
	oled_sendCom(0xaf); //--turn on oled panel

	oled_fill(0x00);
	oled_refresh();
}

void oled_display_off(void)
{
	oled_sendCom(0xae);
}


void oled_display_on(void)
{
	oled_sendCom(0xaf);
}

void oled_sendCom(uint8_t Com)
{
    iic_sendData(OLED_ADDR,0x00,Com);
}

void oled_refresh(void)
{
	uint8_t buffer[129]={0x40};
	for (uint8_t i = 0; i < 8; i++)
	{
		memcpy(buffer + 1, ROM[i], 128);
		oled_sendCom(0xb0+i);	//Set Page Start Address for Page Addressing Mode,0-7
		oled_sendCom(0x00); //---set low column address
		oled_sendCom(0x10); //---set high column address
		oled_sendData(&buffer,sizeof(buffer));
	}
	
}


void oled_sendData(uint8_t *Dat,uint16_t size)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, OLED_ADDR&0xFE, 1);
	i2c_master_write(cmd, Dat, size, 1);
    i2c_master_stop(cmd);
    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1500 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);   
}

void oled_fill(uint8_t data)
{
	memset(ROM,data,128*8);
}

使用方法

#include "my_oled.h" //添加头文件

void app_main(void)
{
    oled_init_params_t my_oled_params=
    {
        .contrast=0xff,
        .lateral_flip=1,
        .longitudinal_flip=1,
        .inverse=0,
    };
    oled_init(&my_oled_params); // 初始化OLED

	oled_Point(10,10,0); //画点
    oled_line(0,0,100,49,0); //画线
    oled_rectangle(30,30,50,50,0);   //画框
    oled_refresh();  //刷新  每次操作后必须刷新
    while(1){
	oled_fill(0x00); //清空 每次操作前必须使用
	oled_point_figure_f(s,&floatdata,0,60); //画折线,浮点型图
	//s是题图(字符串),floatdata是数据,0,60是floatdata最小值和最大值
	oled_refresh();  //刷新  每次操作后必须刷新
	};
}


调试效果

对于OLED显示屏的调试测试程序,首先对OLED初始化完成之后,在显示屏上进行绘制点,线,矩形等操作。绘制了一个坐标为(10,10)的点,和一个起始坐标为(0,0),结尾坐标为(100,49)的折线,还有一个起始坐标为(30,30),结尾坐标为(50,50)的矩形。

图5-2  OLED点线矩形图

在上述程序成功运行之后。接下来就可以开始测试画折线图函数。首先定义了一系列的点,点的值分别为77、43、199、47、169、143、200,然后最后调用绘图函数。

图5-3  OLED折线图

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月明Mo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值