// 作者:魏明择 #include "oled.h" #include "stdlib.h" #include "systick.h" #include "gpio_iic.h" #include "wfont.h" #include "string.h" uint8_t OLED_frame_buffer[128][8] = {0}; void iic_start_Oled(void) { iic_start(); } void iic_stop_Oled(void) { iic_stop(); } void iic_wait_ack_Oled(void) { iic_wait_ack(); } void OLED_write_command(u8 IIC_Command) { iic_start(); iic_send_byte(0x78); iic_wait_ack(); iic_send_byte(0x00); iic_wait_ack(); iic_send_byte(IIC_Command); iic_wait_ack(); iic_stop(); } void OLED_write_data(u8 IIC_Data) { iic_start(); iic_send_byte(0x78); iic_wait_ack(); iic_send_byte(0x40); iic_wait_ack(); iic_send_byte(IIC_Data); iic_wait_ack(); iic_stop(); } void oled_fill(u8 fill_Data) { u8 page; u8 n; for (page = 0; page < 8; page++) for (n = 0; n < 128; n++) OLED_frame_buffer[n][page] = fill_Data; } void oled_draw_picture(const u8 *buf) { const u8 *p = buf; int page; int x; for (page = 0; page < 8; page++) { for (x = 0; x < 128; x++) { OLED_frame_buffer[x][page] = *p; p++; } } } void oled_display_on(void) { OLED_write_command(0X8D); OLED_write_command(0X14); OLED_write_command(0XAF); } void oled_display_off(void) { OLED_write_command(0X8D); OLED_write_command(0X10); OLED_write_command(0XAE); } void oled_clear_frame_buffer(void) { memset(OLED_frame_buffer, 0, sizeof(OLED_frame_buffer)); } void oled_clear(void) { oled_clear_frame_buffer(); oled_refresh_framebuffer(); } void oled_init(void) { iic_init(); delay_ms(800); OLED_write_command(0xAE); // display off OLED_write_command(0x20); // Set Memory Addressing Mode OLED_write_command(0x10); // 00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid OLED_write_command(0xb0); // Set Page Start Address for Page Addressing Mode,0-7 OLED_write_command(0xc8); // Set COM Output Scan Direction OLED_write_command(0x02); //---set low column address OLED_write_command(0x10); //---set high column address OLED_write_command(0x40); //--set start line address OLED_write_command(0x81); //--set contrast control register OLED_write_command(0xCf); // 7f OLED_write_command(0xa1); //--set segment re-map 0 to 127 OLED_write_command(0xa6); //--set normal display OLED_write_command(0xa8); //--set multiplex ratio(1 to 64) OLED_write_command(0x3F); // OLED_write_command(0xa4); // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content OLED_write_command(0xd3); //-set display offset OLED_write_command(0x00); //-not offset OLED_write_command(0xd5); //--set display clock divide ratio/oscillator frequency OLED_write_command(0xf0); //--set divide ratio OLED_write_command(0xd9); //--set pre-charge period OLED_write_command(0x22); // OLED_write_command(0xda); //--set com pins hardware configuration OLED_write_command(0x12); OLED_write_command(0xdb); //--set vcomh OLED_write_command(0x40); // 0x20,0.77xVcc OLED_write_command(0x8d); //--set DC-DC enable OLED_write_command(0x14); // OLED_write_command(0xaf); //--turn on oled panel /* OLED_write_command(0xAE);//--display off OLED_write_command(0x00);//---set low column address OLED_write_command(0x10);//---set high column address OLED_write_command(0x40);//--set start line address OLED_write_command(0xB0);//--set page address OLED_write_command(0x81); // contract control OLED_write_command(0xFF);//--128 OLED_write_command(0xA1);//set segment remap OLED_write_command(0xA6);//--normal / reverse OLED_write_command(0xA8);//--set multiplex ratio(1 to 64) OLED_write_command(0x3F);//--1/32 duty OLED_write_command(0xC8);//Com scan direction OLED_write_command(0xD3);//-set display offset OLED_write_command(0x00);// OLED_write_command(0xD5);//set osc division OLED_write_command(0x80);// OLED_write_command(0xD8);//set area color mode off OLED_write_command(0x05);// OLED_write_command(0xD9);//Set Pre-Charge Period OLED_write_command(0xF1);// OLED_write_command(0xDA);//set com pin configuartion OLED_write_command(0x12);// OLED_write_command(0xDB);//set Vcomh OLED_write_command(0x30);// OLED_write_command(0x8D);//set charge pump enable OLED_write_command(0x14);// OLED_write_command(0xAF);//--turn on oled panel */ } void oled_draw_point(u8 x, u8 y, u8 val) { u8 page; u8 row; u8 point_pos = 0; if (x > 127 || y > 63) return; // 超出范围 page = y >> 3; row = y & 0x7; point_pos = 1 << row; // 计算点在页的相对位置 if (val) OLED_frame_buffer[x][page] |= point_pos; // 写1 else OLED_frame_buffer[x][page] &= ~point_pos; // 写0 } // 更新显示的点到OLED void oled_refresh_framebuffer(void) { u8 page; u8 x; for (page = 0; page < 8; page++) { OLED_write_command(0xB0 + page); // 设置页地址(0~7) OLED_write_command(0x00); // 设置显示位置—列低地址 OLED_write_command(0x10); // 设置显示位置—列高地址 for (x = 0; x < 128; x++) OLED_write_data(OLED_frame_buffer[x][page]); } // 更新显示 } void oled_draw_chinese_text16(u8 x, u8 y, int cn_index) { int i, j; int page = y >> 3; cn_index <<= 1; for (i = 0; i < 16; i++) { for (j = 0; j < 2; j++) { OLED_frame_buffer[x + i][page + j] = hanzi16x16[cn_index + j][i]; } } } void OLED_draw_english_text8(u8 x, u8 y, int en_index) { int i; int page = y >> 3; for (i = 0; i < 6; i++) { OLED_frame_buffer[x + i][page] = ascii6x8[en_index * 6 + i]; } } void oled_draw_text8(u8 x, u8 y, const char *text) { const char *p = text; while (*p && x < 128 && y < 64) { if ((*p) & 0x80) { // 中文跳过 p += 2; x += 12; } else { // 英文 OLED_draw_english_text8(x, y, *p - ' '); p++; x += 6; } } } void OLED_draw_english_text16(u8 x, u8 y, int en_index) { int i; int j; int page = y >> 3; for (i = 0; i < 8; i++) { for (j = 0; j < 2; j++) { OLED_frame_buffer[x + i][page + j] = ascii8x16[(en_index << 4) + (j << 3) + i]; } } } void oled_draw_text16(u8 x, u8 y, const char *text) { const char *p = text; while (*p && x < 128 && y < 64) { if ((*p) & 0x80) { // 中文 // 查找中文是第几个汉字 const char *p_cn = hanzi_utf8_index; int cn_index = 0; while (*p_cn) { if (strncmp(p_cn, p, 2) == 0) { oled_draw_chinese_text16(x, y, cn_index); break; } p_cn += 2; cn_index++; } p += 2; x += 16; } else { // 英文 OLED_draw_english_text16(x, y, *p - ' '); p++; x += 8; } } } void oled_draw_rect(u8 x0, u8 y0, u8 x1, u8 y1) { u8 x; u8 y; for (x = x0; x <= x1; x++) { oled_draw_point(x, y0, 1); oled_draw_point(x, y1, 1); } for (y = y0 + 1; y < y1; y++) { oled_draw_point(x0, y, 1); oled_draw_point(x1, y, 1); } } void oled_fill_rect(u8 x0, u8 y0, u8 x1, u8 y1) { u8 x; u8 y; for (x = x0; x <= x1; x++) for (y = y0; y <= y1; y++) oled_draw_point(x, y, 1); } void oled_fill_circle(u8 x, u8 y, u8 r) // 画一个点 { u8 i = 0; u8 j = 0; for (j = y - r; j <= y + r; j++) for (i = x - r; i <= x + r; i++) if ((x - i) * (x - i) + (y - j) * (y - j) <= r * r) oled_draw_point(i, j, 1); }