Files
stm32-iot-sensor-node/mylib/oled.c
T
2026-10-19 15:47:18 +08:00

330 lines
8.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 作者:魏明择
#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);
}