#include "oled.h" #include "oled_font.h" #include "oled_font_chuc.h" #include "font.h" #define BUFPOINT(x, y) (*(dev->buf + x + (y * dev->width))) #define GET_BIT(x, bit) ((x & (1 << bit)) >> bit) const uint8_t initCmd[] = { 0xAE, // 关闭显示 0xD5, 0x80, // 设置显示时钟分频比/振荡器频率 0xA8, 0x3F, // 设置多路复用比率 0xD3, 0x00, // 设置显示偏移 0x40, 0x00, // 设置显示起始行 0x8D, 0x14, // 电荷泵设置 0x20, 0x00, // 设置内存寻址模式 0xA0, // 设置段重映射 0xC0, // 设置COM输出扫描方向 0xDA, 0x12, // 设置COM引脚硬件配置 0x81, 0xCF, // 设置对比度控制 0xD9, 0xF1, // 设置预充电周期 0xDB, 0x20, // 设置VCOMH取消电平 0xA4, 0xA6, // 整个显示打开 0xAF // 打开显示 }; void OLED_Init(OLED_T *dev) { uint8_t *cmdIndex = (uint8_t *) initCmd; // uint8_t count, temp; // while (*cmdIndex) { // temp = *cmdIndex++; // count = temp & 0x7F; // // dev->cmd(cmdIndex, count); // cmdIndex += count; // } dev->cmd(cmdIndex, sizeof(initCmd)); dev->state = IDLE; } void OLED_ON(OLED_T *dev) { uint8_t cmd[3] = {0x8D, 0x14, 0xAF}; if (dev->state == IDLE) { dev->state = WRITE; dev->cmd(cmd, 3); dev->state = IDLE; } } void OLED_OFF(OLED_T *dev) { uint8_t cmd[3] = {0x8D, 0x10, 0xAE}; if (dev->state == IDLE) { dev->state = WRITE; dev->cmd(cmd, 3); dev->state = IDLE; } } void OLED_Turn(OLED_T *dev, bool e) { uint8_t cmd = 0xA6 + e; if (dev->state == IDLE) { dev->state = WRITE; dev->cmd(&cmd, 1); dev->state = IDLE; } } void OLED_Refresh(OLED_T *dev) { #if REFRESH_CALL_ENABLE dev->call(dev); #else uint8_t i, cmd[3] = {0xb0, 0x00, 0x10}; if (dev->state == IDLE) { dev->state = REFRESH; for (i = 0; i < (dev->height >> 3); i++) { cmd[0] = 0xb0 + i; dev->cmd(cmd, 3); dev->data(dev->buf + (i * dev->width), dev->width); } dev->state = IDLE; } #endif } void OLED_DisplayTurn(OLED_T *dev, bool e) { uint8_t cmd[2]; if (e) { cmd[0] = 0xC8; cmd[1] = 0xA1; } else { cmd[0] = 0xC0; cmd[1] = 0xA0; } if (dev->state == IDLE) { dev->state = WRITE; dev->cmd(cmd, 1); dev->state = IDLE; } } void OLED_Set(OLED_T *dev, uint8_t x, uint8_t y) { uint8_t i, m, n; i = y / 8; m = y % 8; n = 1 << m; BUFPOINT(x, i) |= n; } void OLED_BSet(OLED_T *dev, uint8_t x, uint8_t y, uint8_t data) { uint8_t i, ys = y; for (i = 0; i < 8; i++) //写入数据 { if (GET_BIT(data, i))OLED_Set(dev, x, ys); else OLED_RSet(dev, x, ys); ys++; } } void OLED_RSet(OLED_T *dev, uint8_t x, uint8_t y) { uint8_t i, m, n; i = y / 8; m = y % 8; n = 1 << m; BUFPOINT(x, i) = ~BUFPOINT(x, i); BUFPOINT(x, i) |= n; BUFPOINT(x, i) = ~BUFPOINT(x, i); } void OLED_DrawLine(OLED_T *dev, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) { uint8_t i, k, k1, k2; if ((x1 < 0) || (x2 > dev->width) || (y1 < 0) || (y2 > dev->height) || (x1 > x2) || (y1 > y2))return; if (x1 == x2) //画竖线 { for (i = 0; i < (y2 - y1); i++) { OLED_Set(dev, x1, y1 + i); } } else if (y1 == y2) //画横线 { for (i = 0; i < (x2 - x1); i++) { OLED_Set(dev, x1 + i, y1); } } else //画斜线 { k1 = y2 - y1; k2 = x2 - x1; k = k1 * 10 / k2; for (i = 0; i < (x2 - x1); i++) { OLED_Set(dev, x1 + i, y1 + i * k / 10); } } } void OLED_DrawRect(OLED_T *dev, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) { OLED_DrawLine(dev, x1, y1, x2, y1); // Top side OLED_DrawLine(dev, x1, y1, x1, y2); // Left side OLED_DrawLine(dev, x2, y1, x2, y2); // Right side OLED_DrawLine(dev, x1, y2, x2, y2); // Bottom side } void OLED_DrawCircle(OLED_T *dev, uint8_t x, uint8_t y, uint8_t r) { int a, b, num; a = 0; b = r; while (2 * b * b >= r * r) { OLED_Set(dev, x + a, y - b); OLED_Set(dev, x - a, y - b); OLED_Set(dev, x - a, y + b); OLED_Set(dev, x + a, y + b); OLED_Set(dev, x + b, y + a); OLED_Set(dev, x + b, y - a); OLED_Set(dev, x - b, y - a); OLED_Set(dev, x - b, y + a); a++; num = (a * a + b * b) - r * r;//计算画的点离圆心的距离 if (num > 0) { b--; a--; } } } void OLED_ShowChar(OLED_T *dev, uint8_t x, uint8_t y, uint8_t chr, uint8_t size1) { uint8_t i, m, temp, size2, chr1; uint8_t ys = y; size2 = (size1 / 8 + ((size1 % 8) ? 1 : 0)) * (size1 / 2); //得到字体一个字符对应点阵集所占的字节数 chr1 = chr - ' '; //计算偏移后的值 for (i = 0; i < size2; i++) { if (size1 == 12) { temp = asc2_1206[chr1][i]; } //调用1206字体 else if (size1 == 16) { temp = asc2_1608[chr1][i]; } //调用1608字体 else if (size1 == 24) { temp = asc2_2412[chr1][i]; } //调用2412字体 else return; for (m = 0; m < 8; m++) //写入数据 { if (temp & 0x80)OLED_Set(dev, x, ys); else OLED_RSet(dev, x, ys); temp <<= 1; ys++; if ((ys - y) == size1) { ys = y; x++; break; } } } } void OLED_ShowString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *str, uint8_t size1) { while ((*str >= ' ') && (*str <= '~'))//判断是不是非法字符! { OLED_ShowChar(dev, x, y, *str, size1); x += size1 / 2; if (x > dev->width - size1) //换行 { x = 0; y += 2; } str++; } } #define GET_LOW_BYTE0(x) ((x >> 0) & 0x000000ff) /* 获取第0个字节 */ #define GET_LOW_BYTE1(x) ((x >> 8) & 0x000000ff) /* 获取第1个字节 */ #define GET_LOW_BYTE2(x) ((x >> 16) & 0x000000ff) /* 获取第2个字节 */ #define GET_LOW_BYTE3(x) ((x >> 24) & 0x000000ff) /* 获取第3个字节 */ void OLED_ShowCHString(OLED_T *dev, uint8_t x, uint8_t y, uint8_t *str) { uint8_t i, temp, size2, ys = y, xs = x, c = x; uint16_t index; // Hzk_size=12; // size2 = Hzk_size * Hzk_size / 8; //得到字体一个字符对应点阵集所占的字节数 size2 = Hzk_size * ((Hzk_size + 7) / 8 * 8) / 8; uint8_t test[24] = {0x00, 0x00, 0x2E, 0x18, 0xF7, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0xFC, 0x5F, 0x0D, 0xC6, 0x00, 0x00, 0x00}; while (*str != '\0') { for (index = 0; index < sizeof(Hzk) / sizeof(Chinese_t); index++) { if (Hzk[index].unicode[0] == str[0] && Hzk[index].unicode[1] == str[1])//对比汉字区码位码 { for (i = 0; i < size2; i++) { temp = Hzk[index].data[i]; // temp = test[i]; OLED_BSet(dev, xs, ys, temp); xs++; if (xs - c == Hzk_size) { ys += 8; xs = c; c += Hzk_size; } } ys = y; x += Hzk_size; str++; str++; } else { OLED_ShowChar(dev, x, y, *str, 16); x += 16 / 2; if (x > dev->width - 16) //换行 { x = 0; y += 2; } str++; break; } } } } void draw_rect(Font_f_t *fd, uint8_t *data, size_t len) { size_t index; uint16_t x = fd->x, y = fd->y; uint8_t bit; for (index = 0; index < len; index++) { bit = (data[index / 8] >> (index % 8)) & 1; if (bit)OLED_Set((OLED_T *) fd->dev, x, y); else OLED_RSet((OLED_T *) fd->dev, x, y); x++; if ((x - fd->x) == fd->w) { y++; x = fd->x; } } } // void OLED_DisplayString(OLED_T *dev, const lv_font_t *font, uint8_t *s, uint16_t x, uint16_t y) { uint32_t unicode_letter; Font_f_t fd = {.dev=dev, .dev_w=dev->width, .show=draw_rect}; while (*s) { if (font) { s += Font_utf8_to_unicode(s, &unicode_letter); x += Font_draw_letter(font, &fd, unicode_letter, x, y); x += 0; //字间距 } else { OLED_ShowChar(dev, x, y, *s, 12); x += 12; s++; } } } uint32_t OLED_Pow(uint8_t m, uint8_t n) { uint32_t result = 1; while (n--) { result *= m; } return result; } void OLED_ShowNum(OLED_T *dev, uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size1) { uint8_t t, temp; for (t = 0; t < len; t++) { temp = (num / OLED_Pow(10, len - t - 1)) % 10; if (temp == 0) { OLED_ShowChar(dev, x + (size1 / 2) * t, y, '0', size1); } else { OLED_ShowChar(dev, x + (size1 / 2) * t, y, temp + '0', size1); } } } void OLED_ShowPic(OLED_T *dev, uint8_t x0, uint8_t y0, uint8_t w, uint8_t h, uint8_t *bmp) { size_t index; uint16_t x = x0, y = y0; for (index = 0; index < (w * h) / 8; index++) { OLED_BSet(dev, x, y, bmp[index]); x++; if ((x - x0) == w) { y += 8; x = x0; } } } void OLED_Fill(OLED_T *dev, uint8_t data) { uint8_t x, y; for (y = 0; y < (dev->height >> 3); y++) { for (x = 0; x < dev->width; x++) { BUFPOINT(x, y) = data; } } } void OLED_CLS(OLED_T *dev) { OLED_Fill(dev, 0x00); } void OLED_SPos(OLED_T *dev, uint8_t x, uint8_t y) { uint8_t cmd[3]; cmd[0] = 0xb0 + y; cmd[1] = ((x & 0xf0) >> 4) | 0x10; cmd[2] = (x & 0x0f) | 0x01; if (dev->state == IDLE) { dev->state = WRITE; dev->cmd(cmd, 3); dev->state = IDLE; } }