型号:HS96L01W 4S03
分辨率:120*64
通讯方式:4线SPI 模式00
MCU:MSPM0G3507(只影响SPI的配置)
原本照着型号搜到了嘉立创的使用文档,但是实际上并不能正常使用,后来寻到了一篇博客教程【常用模块】OLED显示模块(原理讲解、STM32实例操作)_oled介绍-CSDN博客,博客里写的非常详细且通俗易懂。
借鉴了上面的初始化函数才能正常完成初始化,初始化代码如下:
void OLED_Init(void)
{SPI_Init(3,0);//4分频,模式为0,0DL_GPIO_initDigitalOutput(GPIO_OLED_RES_IOMUX);DL_GPIO_initDigitalOutput(GPIO_OLED_DC_IOMUX);DL_GPIO_clearPins(GPIO_OLED_PORT, GPIO_OLED_DC_PIN);DL_GPIO_setPins(GPIO_OLED_PORT, GPIO_OLED_RES_PIN);DL_GPIO_enableOutput(GPIO_OLED_PORT, GPIO_OLED_RES_PIN | GPIO_OLED_DC_PIN);//OLED复位OLED_RES_Ctrl();//RES 置0delay_ms(200);//延时 200msOLED_RES_Set();//RES 置1//OLED初始化OLED_WR_Byte(0xAE, OLED_CMD);//关闭显示OLED_WR_Byte(0xD5, OLED_CMD);//设置时钟分频因子,震荡频率OLED_WR_Byte(80, OLED_CMD); //[3:0],分频因子;[7:4],震荡频率OLED_WR_Byte(0xA8, OLED_CMD);//设置驱动路数OLED_WR_Byte(0X3F, OLED_CMD);//默认0X3F(1/64)OLED_WR_Byte(0xD3, OLED_CMD);//设置显示偏移OLED_WR_Byte(0X00, OLED_CMD);//默认为0OLED_WR_Byte(0x40, OLED_CMD);//设置显示开始行 [5:0],行数.OLED_WR_Byte(0x8D, OLED_CMD);//电荷泵设置OLED_WR_Byte(0x14, OLED_CMD);//bit2,开启/关闭OLED_WR_Byte(0x20, OLED_CMD);//设置内存地址模式OLED_WR_Byte(0x02, OLED_CMD);//[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;OLED_WR_Byte(0xA1, OLED_CMD);//段重定义设置,bit0:0,0->0;1,0->127;OLED_WR_Byte(0xC0, OLED_CMD);//设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数OLED_WR_Byte(0xDA, OLED_CMD);//设置COM硬件引脚配置OLED_WR_Byte(0x12, OLED_CMD);//[5:4]配置OLED_WR_Byte(0x81, OLED_CMD);//对比度设置OLED_WR_Byte(0xEF, OLED_CMD);//1~255;默认0X7F (亮度设置,越大越亮)OLED_WR_Byte(0xD9, OLED_CMD);//设置预充电周期OLED_WR_Byte(0xf1, OLED_CMD);//[3:0],PHASE 1;[7:4],PHASE 2;OLED_WR_Byte(0xDB, OLED_CMD);//设置VCOMH 电压倍率OLED_WR_Byte(0x30, OLED_CMD);//[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;OLED_WR_Byte(0xA4, OLED_CMD);//全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)OLED_WR_Byte(0xA6, OLED_CMD);//设置显示方式;bit0:1,反相显示;0,正常显示OLED_WR_Byte(0xAF, OLED_CMD);//开启显示//这里不能加延迟,否则什么都不显示!!!!!!!!OLED_Clear();/**下面代码为嘉立创源码,但不能用*/
#if 0//// OLED_WR_Byte(0xAE, OLED_CMD);//–turn off oled panel//// 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(0x81, OLED_CMD);//–set contrast control register//// OLED_WR_Byte(0xCF, OLED_CMD);//Set SEG Output Current Brightness//// OLED_WR_Byte(0xA1, OLED_CMD);//–Set SEG/Column Mapping 0xa0左右反置 0xa1正常//// OLED_WR_Byte(0xC8, OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常//// OLED_WR_Byte(0xA6, OLED_CMD);//–set normal display//// OLED_WR_Byte(0xAB, OLED_CMD);//–set multiplex ratio(1 to 64)//// OLED_WR_Byte(0x3f, OLED_CMD);//–1/64 duty//// OLED_WR_Byte(0xD3, OLED_CMD);//–set display offset Shift Mapping RAM Counter (0x00~0x3F)//// OLED_WR_Byte(0x00, OLED_CMD);//–not offset//// OLED_WR_Byte(0xd5, OLED_CMD);//–set display dock divide ratio/oscillator frequency//// OLED_WR_Byte(0x80, OLED_CMD);//–set divide ratio, Set Clock as 100 Frames/Sec//// OLED_WR_Byte(0xD9, OLED_CMD);//–set pre-charge period//// OLED_WR_Byte(0xf1, OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1Clock//// OLED_WR_Byte(0xDA, OLED_CMD);//–set com pins hardware configuration//// OLED_WR_Byte(0x12, OLED_CMD);//// OLED_WR_Byte(0xDB, OLED_CMD);//–set vcomh//// OLED_WR_Byte(0x30, OLED_CMD);//Set VCOM Deselect Level//// OLED_WR_Byte(0x20, OLED_CMD);//–Set Page Addressing Mode (0x00/0x01/0x02)//// OLED_WR_Byte(0x02, OLED_CMD);////// OLED_WR_Byte(0x8D, OLED_CMD);//–set Charge Pump enable/disable//// OLED_WR_Byte(0x14, OLED_CMD);//–set(0x10) disable//// OLED_Clear();//// OLED_WR_Byte(0xAF, OLED_CMD);
#endif
}
完整代码如下,为了提高刷新的性能,下面绘画函数没有选择直接更新屏幕,而是只有当所有绘画完成后,再统一调用更新函数。不过关于字体函数的命名有些紊乱
OLED.h
//
// Created by 34753 on 2024/7/22.
//#ifndef ISB_TI_OLED_H
#define ISB_TI_OLED_H
#include "ZQ_Conf.h"#include "ti_init.h"
#include "SPI.h"/* Port definition for Pin Group GPIO_LCD */
#define GPIO_OLED_PORT (GPIOA)/* Defines for RS: GPIOA.12 with pinCMx 34 on package pin 5 */
#define GPIO_OLED_RES_PIN (DL_GPIO_PIN_12)
#define GPIO_OLED_RES_IOMUX (IOMUX_PINCM34)
/* Defines for RST: GPIOA.13 with pinCMx 35 on package pin 6 */
#define GPIO_OLED_DC_PIN (DL_GPIO_PIN_13)
#define GPIO_OLED_DC_IOMUX (IOMUX_PINCM35)#define OLED_RES_Ctrl() DL_GPIO_clearPins(GPIO_OLED_PORT, GPIO_OLED_RES_PIN)
#define OLED_RES_Set() DL_GPIO_setPins(GPIO_OLED_PORT, GPIO_OLED_RES_PIN)
#define OLED_DC_Ctrl() DL_GPIO_clearPins(GPIO_OLED_PORT, GPIO_OLED_DC_PIN)
#define OLED_DC_Set() DL_GPIO_setPins(GPIO_OLED_PORT, GPIO_OLED_DC_PIN)void OLED_Init(void);
void OLED_Clear();void OLED_Fill(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t dot);
void OLED_Refresh_Gram(void);
void OLED_ShowChar_1608(uint16_t x, uint16_t y, uint8_t chr);
void OLED_ShowChar_1206(uint16_t x, uint16_t y, char chr);
void OLED_ShowString_1206(uint16_t x, uint16_t y, char *chr, uint16_t length);
void OLED_ShowCustomChar_1616_Fast(uint16_t x, uint16_t y, uint16_t chrNum);
void OLED_ShowCustomString_1616_Fast(uint16_t x, uint16_t y, uint16_t chrNum,uint16_t length);
void OLED_ShowCustomChar_1212_Fast(uint16_t x, uint16_t y, uint16_t chrNum);
void OLED_ShowCustomString_1212_Fast(uint16_t x, uint16_t y, uint16_t chrNum,uint16_t length);
void OLED_Point(uint16_t x, uint16_t y);//只用来画像素点,并不作为其他函数的子函数,若需则用OLED_DrawPointvoid OLED_Rectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t width);//显示矩形框
void OLED_Line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width);//显示线条
void OLED_Circle(uint16_t x, uint16_t y, uint16_t r, uint16_t width);//显示圆#endif//ISB_TI_OLED_H
OLED.c
//
// Created by 34753 on 2024/7/22.
//#include "OLED.h"
#include "DATA/FONT.h"
#include "Timer.h"
#include <stdlib.h>#define OLED_CMD 0 //write command
#define OLED_DATA 1//write datauint8_t OLED_GRAM[128][8];//缓冲区数组
static const uint8_t lut[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};//用于加速描点计算/**内联函数*///画点
//x:0~127
//y:0~63
//t:1 填充 0,清空
static inline void OLED_WR_Byte(uint8_t data, uint8_t cmd)
{if (cmd){OLED_DC_Set();}else{OLED_DC_Ctrl();}SPI_WriteByte(data);OLED_DC_Set();
}static inline void OLED_DrawPoint_Inline(uint16_t x, uint16_t y, uint8_t t)
{
#if 0uint8_t pos, bx, temp = 0;if (x > 127 || y > 63)return;//超出范围了.pos = 7 - y>>3;// 7-y/8bx = y % 8;temp = 1 << (7 - bx);if (t)OLED_GRAM[x][pos] |= temp;elseOLED_GRAM[x][pos] &= ~temp;
#endif/**优化后*/uint8_t pos = 7 - (y / 8);//计算页数if (t)OLED_GRAM[x][pos] |= lut[y % 8];elseOLED_GRAM[x][pos] &= ~lut[y % 8];
}static inline void OLED_DrawPointDefault_Inline(uint8_t x, uint8_t y)
{
#if 0uint8_t pos, bx, temp = 0;if (x > 127 || y > 63)return;//超出范围了.pos = 7 - y>>3;// 7-y/8bx = y % 8;temp = 1 << (7 - bx);if (t)OLED_GRAM[x][pos] |= temp;elseOLED_GRAM[x][pos] &= ~temp;
#endif/**优化后*/uint8_t pos = 7 - (y / 8);//计算页数OLED_GRAM[x][pos] |= lut[y % 8];
}//更新显存到LCD
static inline void OLED_Refresh_Gram_Inline(void)
{for (uint8_t 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 (uint8_t n = 0; n < 128; n++)OLED_WR_Byte(OLED_GRAM[n][i], OLED_DATA);}
}
static inline void OLED_FillRect_Inline(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
{// 遍历矩形的宽度和高度,逐行逐列调用OLED_Pointfor (uint16_t row = 0; row < h; row++){for (uint16_t col = 0; col < w; col++){// 调用OLED_Point在当前位置绘制一个点OLED_DrawPoint_Inline(x + col, y + row, 1);}}
}void OLED_Line_In(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width)
{int deltaX = x2 - x1;int deltaY = y2 - y1;uint16_t signX = (deltaX > 0) ? 1 : ((deltaX < 0) ? -1 : 0);uint16_t signY = (deltaY > 0) ? 1 : ((deltaY < 0) ? -1 : 0);deltaX = abs(deltaX);deltaY = abs(deltaY);if (deltaX > deltaY){int fraction = deltaY * 2 - deltaX;for (; x1 != x2; x1 += signX){OLED_FillRect_Inline(x1, y1, width, width);// Draw a square instead of a point.if (fraction >= 0){y1 += signY;fraction -= deltaX * 2;}fraction += deltaY * 2;}}else{int fraction = deltaX * 2 - deltaY;for (; y1 != y2; y1 += signY){OLED_FillRect_Inline(x1, y1, width, width);// Draw a square instead of a point.if (fraction >= 0){x1 += signX;fraction -= deltaY * 2;}fraction += deltaX * 2;}}// Draw the last point or adjust if necessaryOLED_FillRect_Inline(x1, y1, width, width);
}void drawCircleHelper_In(uint16_t x_center, uint16_t y_center, int x0, int y0, uint16_t width)
{for (uint16_t i = 0; i < width; i++){for (uint16_t j = 0; j < width; j++){if ((i * i + j * j) <= (width * width)){OLED_DrawPointDefault_Inline(x_center + x0 + i, y_center + y0 + j);OLED_DrawPointDefault_Inline(x_center + x0 + i, y_center - (y0 + j));OLED_DrawPointDefault_Inline(x_center - (x0 + i), y_center + y0 + j);OLED_DrawPointDefault_Inline(x_center - (x0 + i), y_center - (y0 + j));OLED_DrawPointDefault_Inline(x_center + (y0 + j), y_center + x0 + i);OLED_DrawPointDefault_Inline(x_center + (y0 + j), y_center - (x0 + i));OLED_DrawPointDefault_Inline(x_center - (y0 + j), y_center + x0 + i);OLED_DrawPointDefault_Inline(x_center - (y0 + j), y_center - (x0 + i));}}}
}void OLED_Init(void)
{SPI_Init(3,0);//模式为1,1DL_GPIO_initDigitalOutput(GPIO_OLED_RES_IOMUX);DL_GPIO_initDigitalOutput(GPIO_OLED_DC_IOMUX);DL_GPIO_clearPins(GPIO_OLED_PORT, GPIO_OLED_DC_PIN);DL_GPIO_setPins(GPIO_OLED_PORT, GPIO_OLED_RES_PIN);DL_GPIO_enableOutput(GPIO_OLED_PORT, GPIO_OLED_RES_PIN | GPIO_OLED_DC_PIN);//OLED复位OLED_RES_Ctrl();//RES 置0delay_ms(200);//延时 200msOLED_RES_Set();//RES 置1//OLED初始化OLED_WR_Byte(0xAE, OLED_CMD);//关闭显示OLED_WR_Byte(0xD5, OLED_CMD);//设置时钟分频因子,震荡频率OLED_WR_Byte(80, OLED_CMD); //[3:0],分频因子;[7:4],震荡频率OLED_WR_Byte(0xA8, OLED_CMD);//设置驱动路数OLED_WR_Byte(0X3F, OLED_CMD);//默认0X3F(1/64)OLED_WR_Byte(0xD3, OLED_CMD);//设置显示偏移OLED_WR_Byte(0X00, OLED_CMD);//默认为0OLED_WR_Byte(0x40, OLED_CMD);//设置显示开始行 [5:0],行数.OLED_WR_Byte(0x8D, OLED_CMD);//电荷泵设置OLED_WR_Byte(0x14, OLED_CMD);//bit2,开启/关闭OLED_WR_Byte(0x20, OLED_CMD);//设置内存地址模式OLED_WR_Byte(0x02, OLED_CMD);//[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;OLED_WR_Byte(0xA1, OLED_CMD);//段重定义设置,bit0:0,0->0;1,0->127;OLED_WR_Byte(0xC0, OLED_CMD);//设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数OLED_WR_Byte(0xDA, OLED_CMD);//设置COM硬件引脚配置OLED_WR_Byte(0x12, OLED_CMD);//[5:4]配置OLED_WR_Byte(0x81, OLED_CMD);//对比度设置OLED_WR_Byte(0xEF, OLED_CMD);//1~255;默认0X7F (亮度设置,越大越亮)OLED_WR_Byte(0xD9, OLED_CMD);//设置预充电周期OLED_WR_Byte(0xf1, OLED_CMD);//[3:0],PHASE 1;[7:4],PHASE 2;OLED_WR_Byte(0xDB, OLED_CMD);//设置VCOMH 电压倍率OLED_WR_Byte(0x30, OLED_CMD);//[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;OLED_WR_Byte(0xA4, OLED_CMD);//全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)OLED_WR_Byte(0xA6, OLED_CMD);//设置显示方式;bit0:1,反相显示;0,正常显示OLED_WR_Byte(0xAF, OLED_CMD);//开启显示//这里不能加延迟,否则什么都不显示!!!!!!!!OLED_Clear();/**下面代码为嘉立创源码,但不能用*/
#if 0//// OLED_WR_Byte(0xAE, OLED_CMD);//–turn off oled panel//// 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(0x81, OLED_CMD);//–set contrast control register//// OLED_WR_Byte(0xCF, OLED_CMD);//Set SEG Output Current Brightness//// OLED_WR_Byte(0xA1, OLED_CMD);//–Set SEG/Column Mapping 0xa0左右反置 0xa1正常//// OLED_WR_Byte(0xC8, OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常//// OLED_WR_Byte(0xA6, OLED_CMD);//–set normal display//// OLED_WR_Byte(0xAB, OLED_CMD);//–set multiplex ratio(1 to 64)//// OLED_WR_Byte(0x3f, OLED_CMD);//–1/64 duty//// OLED_WR_Byte(0xD3, OLED_CMD);//–set display offset Shift Mapping RAM Counter (0x00~0x3F)//// OLED_WR_Byte(0x00, OLED_CMD);//–not offset//// OLED_WR_Byte(0xd5, OLED_CMD);//–set display dock divide ratio/oscillator frequency//// OLED_WR_Byte(0x80, OLED_CMD);//–set divide ratio, Set Clock as 100 Frames/Sec//// OLED_WR_Byte(0xD9, OLED_CMD);//–set pre-charge period//// OLED_WR_Byte(0xf1, OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1Clock//// OLED_WR_Byte(0xDA, OLED_CMD);//–set com pins hardware configuration//// OLED_WR_Byte(0x12, OLED_CMD);//// OLED_WR_Byte(0xDB, OLED_CMD);//–set vcomh//// OLED_WR_Byte(0x30, OLED_CMD);//Set VCOM Deselect Level//// OLED_WR_Byte(0x20, OLED_CMD);//–Set Page Addressing Mode (0x00/0x01/0x02)//// OLED_WR_Byte(0x02, OLED_CMD);////// OLED_WR_Byte(0x8D, OLED_CMD);//–set Charge Pump enable/disable//// OLED_WR_Byte(0x14, OLED_CMD);//–set(0x10) disable//// OLED_Clear();//// OLED_WR_Byte(0xAF, OLED_CMD);
#endif
}void OLED_Clear()
{for (uint16_t 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 (uint16_t n = 0; n < 128; n++)OLED_WR_Byte(0x00, OLED_DATA);}
}void OLED_Refresh_Gram(void)
{OLED_Refresh_Gram_Inline();
}//开启OLED显示
void OLED_Display_On(void)
{OLED_WR_Byte(0X8D, OLED_CMD);//SET DCDC命令OLED_WR_Byte(0X14, OLED_CMD);//DCDC ONOLED_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 OFFOLED_WR_Byte(0XAE, OLED_CMD);//DISPLAY OFF
}//x1,y1,x2,y2 填充区域的对角坐标
//确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63
//dot:0,清空;1,填充
void OLED_Fill(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t dot)
{for (uint16_t x = x1; x <= x2; x++){for (uint16_t y = y1; y <= y2; y++)OLED_DrawPoint_Inline(x, y, dot);}
}void OLED_Point(uint16_t x, uint16_t y)
{OLED_DrawPoint_Inline(x, y, 1);
}/*** @brief 使用自定义字库16*16* @param x,y 横纵坐标* @param chrNum 字符在自定义字库里的位置* @note 默认亮显,取模方式为逐列式,低位在前* */
void OLED_ShowChineseChar_Fast_In(uint16_t x, uint16_t y, uint16_t chrNum, uint8_t size)
{uint8_t temp;uint16_t y0 = y;uint8_t pos;chrNum <<= 1;//由于1616字体数组是16为一行,而字体又是16*16,所以每个字体在字体数组中需要两行for (uint8_t i = 0; i < 2; ++i){for (uint8_t t = 0; t < size; t++){switch (size){case 12:temp = Character_Custom_1212[chrNum + i][t];break;case 16:temp = Character_Custom_1616[chrNum + i][t];break;default:return;//报错}//对一个字节开始解码for (uint8_t t1 = 0; t1 < 8; t1++){pos = 7 - (y / 8);//计算页数if (temp & 0x1){OLED_GRAM[x][pos] |= lut[y % 8];}else{OLED_GRAM[x][pos] &= ~lut[y % 8];}temp >>= 1;y++;//从上到下,如果满16字高则换一列if ((y - y0) == 16){y = y0;x++;break;}}}}
}/*** @brief 使用自定义字库16*16* @param x,y 横纵坐标* @param chrNum 字符在自定义字库里的位置* @note 默认亮显,取模方式为逐列式,低位在前* */
void OLED_ShowChar_Fast_In(uint16_t x, uint16_t y, char chr, uint8_t size)
{uint8_t temp;uint16_t y0 = y;uint8_t pos;chr = chr - ' ';for (uint8_t i = 0; i < 2; ++i){for (uint8_t t = 0; t < size; t++){switch (size){case 12:temp = asc_1206[chr + i][t];break;case 16:temp = asc_1608[chr + i][t];break;default:return;//报错}//对一个字节开始解码for (uint8_t t1 = 0; t1 < 8; t1++){pos = 7 - (y / 8);//计算页数if (temp & 0x1){OLED_GRAM[x][pos] |= lut[y % 8];}else{OLED_GRAM[x][pos] &= ~lut[y % 8];}temp >>= 1;y++;//从上到下,如果满16字高则换一列if ((y - y0) == 16){y = y0;x++;break;}}}}
}
void OLED_ShowCustomChar_1616_Fast(uint16_t x, uint16_t y, uint16_t chrNum)
{OLED_ShowChineseChar_Fast_In(x, y, chrNum, 16);
}void OLED_ShowCustomString_1616_Fast(uint16_t x, uint16_t y, uint16_t chrNum, uint16_t length)
{for (uint16_t i = 0; i < length; i++){OLED_ShowChineseChar_Fast_In(x + i * 16, y, chrNum + i, 16);}
}void OLED_ShowCustomChar_1212_Fast(uint16_t x, uint16_t y, uint16_t chrNum)
{OLED_ShowChineseChar_Fast_In(x, y, chrNum, 12);
}
void OLED_ShowChar_1206(uint16_t x, uint16_t y, char chr)
{OLED_ShowChar_Fast_In(x, y, chr, 12);
}void OLED_ShowString_1206(uint16_t x, uint16_t y, char *chr, uint16_t length)
{for (uint16_t i = 0; i != '\0'; ++i){chr[i] = chr[i] - ' ';OLED_ShowChar_Fast_In(x + i * 6, y, chr[i],12);}
}void OLED_ShowCustomString_1212_Fast(uint16_t x, uint16_t y, uint16_t chrNum, uint16_t length)
{for (uint16_t i = 0; i < length; i++){OLED_ShowChineseChar_Fast_In(x + i * 12, y, chrNum + i, 12);}
}//下面为原代码备份,不要做任何改动!!!
#if 0
//void OLED_ShowCustomChar_1616_Fast(uint8_t x, uint8_t y, uint8_t chrNum)
//{
// static const uint8_t lut[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
//
// uint8_t temp;
// uint8_t y0 = y;
// chrNum <<= 1;//由于字体数组是16为一行,而字体又是16*16,所以每个字体在字体数组中需要两行
// for (uint8_t i = 0; i < 2; ++i)
// {
// for (uint8_t t = 0; t < 16; t++)
// {
// temp = Character_Custom[chrNum + i][t];
//
// //对一个字节开始解码
// for (uint8_t t1 = 0; t1 < 8; t1++)
// {
// if (temp & 0x1)
// {
// uint8_t pos = 7 - (y / 8);//计算页数
// OLED_GRAM[x][pos] |= lut[y % 8];
// }
// else
// {
// uint8_t pos = 7 - (y / 8);//计算页数
// OLED_GRAM[x][pos] &= ~lut[y % 8];
// }
// temp >>= 1;
// y++;
// //从上到下,如果满16字高则换一列
// if ((y - y0) == 16)
// {
// y = y0;
// x++;
// break;
// }
// }
// }
// }
// OLED_Refresh_Gram();//更新显示
//}
#endif
void OLED_ShowChar_1608(uint16_t x, uint16_t y, uint8_t chr)
{uint8_t temp, pos;uint16_t y0 = y;chr = chr - ' ';//得到偏移后的值for (uint8_t t = 0; t < 16; t++){temp = asc_1608[chr][t];//调用1608字体//对一个字节开始解码for (uint8_t t1 = 0; t1 < 8; t1++){pos = 7 - (y / 8);//计算页数if (temp & 0x1){OLED_GRAM[x][pos] |= lut[y % 8];}else{OLED_GRAM[x][pos] &= ~lut[y % 8];}temp >>= 1;y++;//从上到下,如果满16字高则换一列if ((y - y0) == 16){y = y0;x++;break;}}}
}//显示字符串
//x,y:起点坐标
//size:字体大小
//*p:字符串起始地址
void OLED_ShowString(uint8_t x, uint8_t y, const uint8_t *p, uint8_t size)
{while ((*p <= '~') && (*p >= ' '))//判断是不是非法字符!{if (x > (128 - (size / 2))){x = 0;y += size;}if (y > (64 - size)){y = x = 0;}// OLED_ShowChar(x, y, *p, size, 1);x += size / 2;p++;}
}
//显示矩形框
void OLED_Rectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t width)
{OLED_Line_In(x, y, x + w, y, width);OLED_Line_In(x + w, y, x + w, y + h, width);OLED_Line_In(x, y + h, x + w, y + h, width);OLED_Line_In(x, y, x, y + h, width);
}
//显示线条
//void OLED_Line_nowidth(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
//{
// unsigned int t;
// int xerr=0,yerr=0,delta_x,delta_y,distance;
// int incx,incy,uRow,uCol;
//
// delta_x=x2-x1; //计算坐标增量
// delta_y=y2-y1;
// uRow=x1;
// uCol=y1;
//
// if(delta_x>0)
// incx=1; //设置单步方向
// else if(delta_x==0)
// incx=0;//垂直线
// else
// {
// incx=-1;delta_x=-delta_x;
// }
// if(delta_y>0)
// incy=1;
// else if(delta_y==0)
// incy=0;//水平线
// else
// {
// incy=-1;delta_y=-delta_y;
// }
// if( delta_x>delta_y)
// distance=delta_x; //选取基本增量坐标轴
// else
// distance=delta_y;
// for(t=0;t<=distance+1;t++ )//画线输出
// {
// OLED_Point(uRow,uCol);//画点
// xerr+=delta_x ;
// yerr+=delta_y ;
// if(xerr>distance)
// {
// xerr-=distance;
// uRow+=incx;
// }
// if(yerr>distance)
// {
// yerr-=distance;
// uCol+=incy;
// }
// }
//}void OLED_Line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width)
{OLED_Line_In(x1, y1, x2, y2, width);
}
//显示圆
void OLED_Circle(uint16_t x, uint16_t y, uint16_t r, uint16_t width)
{int d = 3 - 2 * r;int x0 = 0;int y0 = r;// 绘制外圆drawCircleHelper_In(x, y, x0, y0, width);while (x0 <= y0){if (d < 0){d += 4 * x0 + 6;}else{d += 4 * (x0 - y0) + 10;y0--;}x0++;// 每次迭代都要画圆的所有八分之一drawCircleHelper_In(x, y, x0, y0, width);}
}