doubao_chat/apps/common/ui/oled/oled.c

415 lines
11 KiB
C
Raw Permalink 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 "oledfont.h"
#include "bmp.h"
//#define USE_SDK_IIC
/**********************************************
//软件 IIC IO 配置
**********************************************/
void oled_gpio_init(void)
{
gpio_direction_output(OLED_CLK_IO, 1);
gpio_direction_output(OLED_SDA_IO, 1);
}
void oled_sclk_init(void)
{
gpio_direction_output(OLED_CLK_IO, 1);
}
void oled_sdi_init(void)
{
gpio_direction_output(OLED_SDA_IO, 1);
}
void oled_sclk_set(char val)//输出设置
{
if (val) {
gpio_direction_output(OLED_CLK_IO, 1);
} else {
gpio_direction_output(OLED_CLK_IO, 0);
}
}
void oled_sdi_set(char val)//输出设置
{
if (val) {
gpio_direction_output(OLED_SDA_IO, 1);
} else {
gpio_direction_output(OLED_SDA_IO, 0);
}
}
/**********************************************
//IIC IO Init
**********************************************/
void IIC_IO_Init(void)
{
// OLED_SCLK_INIT();
// OLED_SDIN_INIT();
OLED_GPIO_INIT();
}
/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
OLED_SCLK_Set() ;
OLED_SDIN_Set();
OLED_SDIN_Clr();
OLED_SCLK_Clr();
}
/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
OLED_SCLK_Set() ;
OLED_SDIN_Clr();
OLED_SDIN_Set();
}
void IIC_Wait_Ack()
{
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
/**********************************************
// IIC Write byte
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m, da;
da = IIC_Byte;
OLED_SCLK_Clr();
for (i = 0; i < 8; i++) {
m = da;
m = m & 0x80;
if (m == 0x80) {
OLED_SDIN_Set();
} else {
OLED_SDIN_Clr();
}
da = da << 1;
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
IIC_Wait_Ack();
Write_IIC_Byte(0x00); //write command
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Command);
IIC_Wait_Ack();
IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
IIC_Start();
Write_IIC_Byte(0x78); //D/C#=0; R/W#=0
IIC_Wait_Ack();
Write_IIC_Byte(0x40); //write data
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Data);
IIC_Wait_Ack();
IIC_Stop();
}
void OLED_WR_Byte(unsigned char dat, unsigned char cmd)
{
if (cmd) {
Write_IIC_Data(dat);
} else {
Write_IIC_Command(dat);
}
}
/********************************************
// fill_Picture
********************************************/
void fill_picture(unsigned char fill_Data)
{
unsigned char m, n;
for (m = 0; m < 8; m++) {
OLED_WR_Byte(0xb0 + m, OLED_CMD); //page0-page1
OLED_WR_Byte(0x00, OLED_CMD); //low column start address
OLED_WR_Byte(0x10, OLED_CMD); //high column start address
for (n = 0; n < 128; n++) {
OLED_WR_Byte(fill_Data, 1);
}
}
}
//坐标设置
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
OLED_WR_Byte(0xb0 + y, OLED_CMD);
OLED_WR_Byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD);
OLED_WR_Byte((x & 0x0f), OLED_CMD);
}
//开启OLED显示
void OLED_Display_On(void)
{
OLED_WR_Byte(0X8D, OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X14, OLED_CMD); //DCDC ON
OLED_WR_Byte(0XAF, OLED_CMD); //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{
OLED_WR_Byte(0X8D, OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X10, OLED_CMD); //DCDC OFF
OLED_WR_Byte(0XAE, OLED_CMD); //DISPLAY OFF
}
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
u8 i, n;
for (i = 0; i < 8; i++) {
OLED_WR_Byte(0xb0 + i, OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte(0x00, OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte(0x10, OLED_CMD); //设置显示位置—列高地址
for (n = 0; n < 128; n++) {
OLED_WR_Byte(0, OLED_DATA);
}
} //鏇存柊鏄剧ず
}
void OLED_On(void)
{
u8 i, n;
for (i = 0; i < 8; i++) {
OLED_WR_Byte(0xb0 + i, OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte(0x00, OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte(0x10, OLED_CMD); //设置显示位置—列高地址
for (n = 0; n < 128; n++) {
OLED_WR_Byte(1, OLED_DATA);
}
} //更新显示
}
//{0x00,0x00,0xF0,0x10,0x10,0x10,0xFE,0x12,0x10,0x10,0x10,0xF0,0x00,0x00},
//{0x00,0x00,0x03,0x02,0x02,0x02,0xFF,0x02,0x02,0x02,0x02,0x03,0x00,0x00},/*"中",0*/
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 16/12
void OLED_ShowChar(u8 x, u8 y, u8 chr, u8 Char_Size)
{
unsigned char c = 0, i = 0;
c = chr - ' '; //得到偏移后的值
if (x > Max_Column - 1) {
x = 0;
y = y + 2;
}
if (Char_Size == 16) {
OLED_Set_Pos(x, y);
for (i = 0; i < 8; i++) {
OLED_WR_Byte(F8X16[c * 16 + i], OLED_DATA);
}
OLED_Set_Pos(x, y + 1);
for (i = 0; i < 8; i++) {
OLED_WR_Byte(F8X16[c * 16 + i + 8], OLED_DATA);
}
} else {
OLED_Set_Pos(x, y);
for (i = 0; i < 6; i++) {
OLED_WR_Byte(F6x8[c][i], OLED_DATA);
}
}
}
//m^n函数
u32 oled_pow(u8 m, u8 n)
{
u32 result = 1;
while (n--) {
result *= m;
}
return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式 0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_ShowNum(u8 x, u8 y, u32 num, u8 len, u8 size2)
{
u8 t, temp;
u8 enshow = 0;
for (t = 0; t < len; t++) {
temp = (num / oled_pow(10, len - t - 1)) % 10;
if (enshow == 0 && t < (len - 1)) {
if (temp == 0) {
OLED_ShowChar(x + (size2 / 2)*t, y, ' ', size2);
continue;
} else {
enshow = 1;
}
}
OLED_ShowChar(x + (size2 / 2)*t, y, temp + '0', size2);
}
}
void OLED_ShowNumKB(u8 x, u8 y, u32 num, u8 Char_Size)
{
u8 t = 0, temp;
u8 len = 0;
static u8 last_max_cnt = 0;
u32 p = num;
while (p) {
p = p / 10;
len++;
}
if (len == 0) {
OLED_ShowChar(x + (Char_Size / 2)*t, y, '0', Char_Size);
t++;
} else {
for (t = 0; t < len; t++) {
temp = num / oled_pow(10, len - 1 - t) % 10;
OLED_ShowChar(x + (Char_Size / 2)*t, y, '0' + temp, Char_Size);
}
}
OLED_ShowChar(x + (Char_Size / 2)*t, y, ' ', Char_Size);
t++;
OLED_ShowChar(x + (Char_Size / 2)*t, y, 'K', Char_Size);
t++;
OLED_ShowChar(x + (Char_Size / 2)*t, y, 'B', Char_Size);
if (t > last_max_cnt) {
last_max_cnt = t;
}
while (t < last_max_cnt) {
t++;
OLED_ShowChar(x + (Char_Size / 2)*t, y, ' ', Char_Size);
}
}
//显示一个字符号串
void OLED_ShowString(u8 x, u8 y, u8 *chr, u8 Char_Size)
{
unsigned char j = 0;
while (chr[j] != '\0') {
OLED_ShowChar(x, y, chr[j], Char_Size);
x += 8;
if (x > 120) {
x = 0;
y += 2;
}
j++;
}
}
//显示汉字
void OLED_ShowCHinese(u8 x, u8 y, u8 num)
{
u8 t, adder = 0;
OLED_Set_Pos(x, y);
for (t = 0; t < 16; t++) {
OLED_WR_Byte(Hzk[2 * num][t], OLED_DATA);
adder += 1;
}
OLED_Set_Pos(x, y + 1);
for (t = 0; t < 16; t++) {
OLED_WR_Byte(Hzk[2 * num + 1][t], OLED_DATA);
adder += 1;
}
}
//显示汉字
void OLED_ShowCHineseString(u8 x, u8 y, u8 start_num, u8 num)
{
u8 t, adder = 0, no;
for (no = start_num; no < num; no++) {
OLED_Set_Pos(x, y);
for (t = 0; t < 16; t++) {
OLED_WR_Byte(Hzk[2 * no][t], OLED_DATA);
adder += 1;
}
OLED_Set_Pos(x, y + 1);
for (t = 0; t < 16; t++) {
OLED_WR_Byte(Hzk[2 * no + 1][t], OLED_DATA);
adder += 1;
}
x += 16;
}
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
void OLED_DrawBMP(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, unsigned char BMP[])
{
unsigned int j = 0;
unsigned char x, y;
if (y1 % 8 == 0) {
y = y1 / 8;
} else {
y = y1 / 8 + 1;
}
for (y = y0; y < y1; y++) {
OLED_Set_Pos(x0, y);
for (x = x0; x < x1; x++) {
OLED_WR_Byte(BMP[j++], OLED_DATA);
}
}
}
void OLED_KBPS_SHOWN_FONT(void)
{
OLED_ShowCHineseString(0, 0, 0, 5);
OLED_ShowCHineseString(0, 4, 5, 5 + 5);
}
void OLED_KBPS_SHOWN(int send_kb, int recv_kb)
{
OLED_ShowNumKB(5 * 16, 0, send_kb, 16);
OLED_ShowNumKB(5 * 16, 4, recv_kb, 16);
}
//初始化SSD1306
void OLED_Init(void)
{
IIC_IO_Init();
Delay_50ms();
OLED_WR_Byte(0xAE, OLED_CMD); //--display off
OLED_WR_Byte(0x00, OLED_CMD); //---set low column address
OLED_WR_Byte(0x10, OLED_CMD); //---set high column address
OLED_WR_Byte(0x40, OLED_CMD); //--set start line address
OLED_WR_Byte(0xB0, OLED_CMD); //--set page address
OLED_WR_Byte(0x81, OLED_CMD); // contract control
OLED_WR_Byte(0xFF, OLED_CMD); //--128
OLED_WR_Byte(0xA1, OLED_CMD); //set segment remap
OLED_WR_Byte(0xA6, OLED_CMD); //--normal / reverse
OLED_WR_Byte(0xA8, OLED_CMD); //--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3F, OLED_CMD); //--1/32 duty
OLED_WR_Byte(0xC8, OLED_CMD); //Com scan direction
OLED_WR_Byte(0xD3, OLED_CMD); //-set display offset
OLED_WR_Byte(0x00, OLED_CMD); //
OLED_WR_Byte(0xD5, OLED_CMD); //set osc division
OLED_WR_Byte(0x80, OLED_CMD); //
OLED_WR_Byte(0xD8, OLED_CMD); //set area color mode off
OLED_WR_Byte(0x05, OLED_CMD); //
OLED_WR_Byte(0xD9, OLED_CMD); //Set Pre-Charge Period
OLED_WR_Byte(0xF1, OLED_CMD); //
OLED_WR_Byte(0xDA, OLED_CMD); //set com pin configuartion
OLED_WR_Byte(0x12, OLED_CMD); //
OLED_WR_Byte(0xDB, OLED_CMD); //set Vcomh
OLED_WR_Byte(0x30, OLED_CMD); //
OLED_WR_Byte(0x8D, OLED_CMD); //set charge pump enable
OLED_WR_Byte(0x14, OLED_CMD); //
OLED_WR_Byte(0xAF, OLED_CMD); //--turn on oled panel
OLED_Clear();
//显示测试
OLED_KBPS_SHOWN_FONT();
OLED_KBPS_SHOWN(0, 0);
}