Files
WMZ_3rd_STM32G474RET6_FreeRTOS/Core/Src/oled.c
2026-02-24 12:15:29 +08:00

371 lines
7.6 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 "char.h"
#include "cmsis_os.h"
#include "main.h"
#include <cstring>
#include "variables.h"
#define u8 unsigned char;
#define u16 unsigned short int;
#define u32 unsigned int;
#define OLED_CS cs_Pin
#define OLED_RST RES_Pin
#define OLED_DC dc_Pin
#define OLED_SCL D0_Pin
#define OLED_SDA D1_Pin
unsigned char OLED_GRAM[128][8];
void OLED_WR_Byte(unsigned char dat,unsigned char cmd) ///////////////////////////////////////////1
{
taskENTER_CRITICAL();
unsigned char i;
if(cmd==0)
{
HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_RESET);
}
if(cmd==1)
{
HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_SET);
}
HAL_GPIO_WritePin(CS_GPIO_Port,CS_Pin,GPIO_PIN_RESET);
for(i=0;i<8;i++)
{
HAL_GPIO_WritePin(D0_GPIO_Port,D0_Pin,GPIO_PIN_RESET);
if(dat&0x80)
HAL_GPIO_WritePin(D1_GPIO_Port,D1_Pin,GPIO_PIN_SET);
else
HAL_GPIO_WritePin(D1_GPIO_Port,D1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(D0_GPIO_Port,D0_Pin,GPIO_PIN_SET);
dat<<=1;
}
HAL_GPIO_WritePin(CS_GPIO_Port,CS_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_SET);
taskEXIT_CRITICAL();
}
void OLED_Refresh_Gram(void) ///////////////////////////////////2
{
unsigned char i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,0); //设置页地址0~7
OLED_WR_Byte (0x00,0); //设置显示位置—列低地址
OLED_WR_Byte (0x10,0); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],1);
}
}
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
OLED_WR_Byte(0xb0+y,0);
OLED_WR_Byte(((x&0xf0)>>4)|0x10,0);
OLED_WR_Byte((x&0x0f)|0x01,0);
}
//开启OLED显示
void OLED_Display_On(void) ///////////////////////////////////3
{
OLED_WR_Byte(0X8D,0); //SET DCDC命令
OLED_WR_Byte(0X14,0); //DCDC ON
OLED_WR_Byte(0XAF,0); //DISPLAY ON
}
void OLED_DrawPoint(unsigned char x,unsigned char y,unsigned char t)
{
unsigned char pos,bx,temp=0;
if(x>127||y>63)return;//超出范围了.
pos=7-y/8;
bx=y%8;
temp=1<<(7-bx);
if(t)OLED_GRAM[x][pos]|=temp;
else OLED_GRAM[x][pos]&=~temp;
}
void OLED_Fill(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char dot) ///////////////////////////4
{
unsigned char x,y;
for(x=x1;x<=x2;x++)
{
for(y=y1;y<=y2;y++)
{
OLED_DrawPoint(x,y,dot);
}
}
OLED_Refresh_Gram();//更新显示
}
void OLED_Clear(void) ////////////////////////////////////////////////////////////////////////////////5
{
unsigned char i,n;
for(i=0;i<8;i++)
{
for(n=0;n<128;n++)
{
OLED_GRAM[n][i]=0;
}
}
OLED_Refresh_Gram();//更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 12/16/24
void OLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr,unsigned char ucWid,unsigned char mode) ///////////////////////////6
{
unsigned char temp,t,t1;
unsigned char y0=y;
unsigned char cucWid=(ucWid/8+((ucWid%8)?1:0))*(ucWid/2); //得到字体一个字符对应点阵集所占的字节数
chr=chr-' ';//得到偏移后的值
for(t=0;t<cucWid;t++)
{
if(ucWid==12)temp=ascii_1206[chr][t]; //调用1206字体
else if(ucWid==16)temp=ascii_1608[chr][t]; //调用1608字体
else if(ucWid==24)temp=ascii_2412[chr][t]; //调用2412字体
else return; //没有的字库
for(t1=0;t1<8;t1++)
{
if(temp&0x80)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp<<=1;
y++;
if((y-y0)==ucWid)
{
y=y0;
x++;
break;
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
void OLED_ShowFontHZ(unsigned char x,unsigned char y,unsigned char pos,unsigned char size,unsigned char mode)
{
unsigned char temp,t,t1;
unsigned char y0=y;
unsigned char csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数
if(size!=12&&size!=16&&size!=24)return; //不支持的size
for(t=0;t<csize;t++)
{
if(size==12)temp=FontHzk[pos][t]; //调用1206字体
else if(size==16)temp=FontHzk[pos][t]; //调用1608字体
else if(size==24)temp=FontHzk[pos][t]; //调用2412字体
else return; //没有的字库
for(t1=0;t1<8;t1++)
{
if(temp&0x80)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp<<=1;
y++;
if((y-y0)==size)
{
y=y0;
x++;
break;
}
}
}
}
////////////////////////////////////////////
void showstring(char A[], unsigned char x ,unsigned char y) ///////////////////////////////////////////7
{
OLED_Clear();
int len,i=0;
unsigned a=1,b=1;
len=strlen(A);
a=x+a;
b=y+b;
while(i<len)
{
OLED_ShowChar(a,b,A[i],16,1);
a=a+9;
if((i>12)&&(((i-12)%13)==1))
{
a=1+x;
b=b+16;
}
i=i+1;
}
OLED_Refresh_Gram() ;
}
void plusstring(char A[], unsigned char x ,unsigned char y) ///////////////////////////////////////////8
{
int len,i=0;
unsigned a=1,b=1;
len=strlen(A);
a=x+a;
b=y+b;
while(i<len)
{
OLED_ShowChar(a,b,A[i],16,1);
a=a+9;
if((i>12)&&(((i-12)%13)==1))
{
a=1+x;
b=b+16;
}
i=i+1;
}
OLED_Refresh_Gram() ;
}
void roll_x_string(char A[], unsigned char x1 ,unsigned char y1, unsigned char x2) /////////////////////////////////9
{
if(x1>x2)
{
while((x1-x2)>10)
{
showstring(A,x1,y1);
x1=x1-10;
}
showstring(A,x2,y1);
}
else
{
while((x2-x1)>5)
{
showstring(A,x1,y1);
x1=x1+5;
}
showstring(A,x2,y1);
}
}
void roll_y_string(char A[], unsigned char x1 ,unsigned char y1, unsigned char y2) /////////////////////////////////10
{
if(y1>y2)
{
while(y1>y2)
{
showstring(A,x1,y1);
y1=y1-1;
}
}
else
{
while(y1<y2)
{
showstring(A,x1,y1);
y1=y1+1;
}
}
}
void OLED_Init() /////////////////////////////////12
{
HAL_GPIO_WritePin(RES_GPIO_Port,RES_Pin,GPIO_PIN_SET);
osDelay(100);
HAL_GPIO_WritePin(RES_GPIO_Port,RES_Pin,GPIO_PIN_RESET);
osDelay(100);
HAL_GPIO_WritePin(RES_GPIO_Port,RES_Pin,GPIO_PIN_SET);
OLED_WR_Byte(0xAE,0); //关闭显示
OLED_WR_Byte(0xD5,0); //设置时钟分频因子,震荡频率
OLED_WR_Byte(80,0); //[3:0],分频因子;[7:4],震荡频率
OLED_WR_Byte(0xA8,0); //设置驱动路数
OLED_WR_Byte(0X3F,0); //默认0X3F(1/64)
OLED_WR_Byte(0xD3,0); //设置显示偏移
OLED_WR_Byte(0X00,0); //默认为0
OLED_WR_Byte(0x40,0); //设置显示开始行 [5:0],行数.
OLED_WR_Byte(0x8D,0); //电荷泵设置
OLED_WR_Byte(0x14,0); //bit2开启/关闭
OLED_WR_Byte(0x20,0); //设置内存地址模式
OLED_WR_Byte(0x02,0); //[1:0],00列地址模式;01行地址模式;10,页地址模式;默认10;
OLED_WR_Byte(0xA1,0); //段重定义设置,bit0:0,0->0;1,0->127;
OLED_WR_Byte(0xC0,0); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
OLED_WR_Byte(0xDA,0); //设置COM硬件引脚配置
OLED_WR_Byte(0x12,0); //[5:4]配置
OLED_WR_Byte(0x81,0); //对比度设置
OLED_WR_Byte(0x7F,0); //1~255;默认0X7F (亮度设置,越大越亮)
OLED_WR_Byte(0xD9,0); //设置预充电周期
OLED_WR_Byte(0xf1,0); //[3:0],PHASE 1;[7:4],PHASE 2;
OLED_WR_Byte(0xDB,0); //设置VCOMH 电压倍率
OLED_WR_Byte(0x30,0); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
OLED_WR_Byte(0xA4,0); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
OLED_WR_Byte(0xA6,0); //设置显示方式;bit0:1,反相显示;0,正常显示
OLED_WR_Byte(0xAF,0); //开启显示
OLED_Clear();
}
void sciishow(char *box, unsigned char A)
{
unsigned char high, low;
high=(A&0xf0)>>4;
low=A&0x0f;
if(high>=0x0A)
{
box[0]=high+0x37;
}
else
{
box[0]=high+0x30;
}
if(low>=0x0A)
{
box[1]=low+0x37;
}
else
{
box[1]=low+0x30;
}
}