使用软件和硬件:
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)的矩形。
在上述程序成功运行之后。接下来就可以开始测试画折线图函数。首先定义了一系列的点,点的值分别为77、43、199、47、169、143、200,然后最后调用绘图函数。