This repository has been archived on 2024-05-05. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ABS-Peripheral-Drive/OLED显示屏/AbsDrive_OLED.c
2023-10-02 03:43:21 +08:00

475 lines
11 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 "AbsDrive_OLED.h"
#include "oledfont.h"
u8 OLED_GRAM[144][8];
/**************************抽象实现************************************/
/*抽象函数:写字节
*要求1实现一个写入多个字节的函数
*要求2返回一个AbsDriveOLED_STATE类型的状态
*参数1_data:写入的数据一个u8指针类型
*参数2_size写入多少个字节
*/
static AbsDriveOLED_STATE AbsOledWriteByte(u8 *_data,u8 _size){
/********************请实现抽象写字节函数********************/
if(HAL_SPI_Transmit(&hspi2,_data,_size,1000)==HAL_OK)return ABS_OLED_OK;else return ABS_OLED_ERROR;
/********************请实现抽象写字节函数********************/
return ABS_OLED_OK;
}
#ifdef Enable_ABS_Delay //启用延时函数时可以实现其内容
/*抽象函数:延时函数
*要求1实现延时函数、
*参数1t:延时时间
*/
static void AbsOledDelay(u32 t){
/********************请实现抽象延时函数********************/
while(t--){} //默认循环while(t--){},可重写
/********************请实现抽象延时函数********************/
}
#endif
/**************************抽象实现************************************/
/*
*函数AbsOledWriteCMD
*功能写OLED命令
*参数ABScmd:命令
*返回值AbsDriveOLED_STATE状态
*/
AbsDriveOLED_STATE AbsOledWriteCMD(u8 ABScmd){
#ifdef ABSDrive_4SPI
HAL_GPIO_WritePin(oled_cs_GPIO_Port, oled_cs_Pin, GPIO_PIN_RESET);
if(AbsOledWriteByte(&ABScmd,1)==ABS_OLED_OK)return ABS_OLED_OK;
#endif
#ifdef ABSDrive_3SPI
#endif
return ABS_OLED_ERROR;
}
/*
*函数AbsOledWriteDATA
*功能写OLED数据
*参数ABScmd:OLED数据
*返回值AbsDriveOLED_STATE状态
*/
AbsDriveOLED_STATE AbsOledWriteDATA(u8 ABSdata){
#ifdef ABSDrive_4SPI
HAL_GPIO_WritePin(oled_cs_GPIO_Port, oled_cs_Pin, GPIO_PIN_SET);
if(AbsOledWriteByte(&ABSdata,1)==ABS_OLED_OK)return ABS_OLED_OK;
#endif
#ifdef ABSDrive_3SPI
#endif
return ABS_OLED_ERROR;
}
void OLED_ColorTurn(u8 i)
{
if(i==0)
{
AbsOledWriteCMD(0xA6);
}
if(i==1)
{
AbsOledWriteCMD(0xA7);
}
}
void OLED_DisplayTurn(u8 i)
{
if(i==0)
{
AbsOledWriteCMD(0xC8);
AbsOledWriteCMD(0xA1);
}
if(i==1)
{
AbsOledWriteCMD(0xC0);
AbsOledWriteCMD(0xA0);
}
}
void OLED_DisPlay_On(void)
{
AbsOledWriteCMD(0x8D);
AbsOledWriteCMD(0x14);
AbsOledWriteCMD(0xAF);
}
void OLED_DisPlay_Off(void)
{
AbsOledWriteCMD(0x8D);
AbsOledWriteCMD(0x10);
AbsOledWriteCMD(0xAE);
}
/*
*函数OLED_Refresh
*描述刷新OLED
*/
void OLED_Refresh(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
AbsOledWriteCMD(0xB0+i);
AbsOledWriteCMD(0x00);
AbsOledWriteCMD(0x10);
for(n=0;n<128;n++)AbsOledWriteDATA(OLED_GRAM[n][i]);
}
}
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
for(n=0;n<128;n++)
{
OLED_GRAM[n][i]=0;
}
}
OLED_Refresh();
}
//<2F><><EFBFBD><EFBFBD>
//x:0~127
//y:0~63
//t:1 <20><><EFBFBD> 0,<2C><><EFBFBD>
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
u8 i,m,n;
i=y/8;
m=y%8;
n=1<<m;
if(t){OLED_GRAM[x][i]|=n;}
else
{
OLED_GRAM[x][i]=~OLED_GRAM[x][i];
OLED_GRAM[x][i]|=n;
OLED_GRAM[x][i]=~OLED_GRAM[x][i];
}
}
//<2F><><EFBFBD><EFBFBD>
//x1,y1:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//x2,y2:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2,u8 mode)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
delta_y=y2-y1;
uRow=x1;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uCol=y1;
if(delta_x>0)incx=1; //<2F><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else if (delta_x==0)incx=0;//<2F><>ֱ<EFBFBD><D6B1>
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if (delta_y==0)incy=0;//ˮƽ<CBAE><C6BD>
else {incy=-1;delta_y=-delta_x;}
if(delta_x>delta_y)distance=delta_x; //ѡȡ<D1A1><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else distance=delta_y;
for(t=0;t<distance+1;t++)
{
OLED_DrawPoint(uRow,uCol,mode);//<2F><><EFBFBD><EFBFBD>
xerr+=delta_x;
yerr+=delta_y;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
//x,y:Բ<><D4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//r:Բ<>İ뾶
void OLED_DrawCircle(u8 x,u8 y,u8 r)
{
int a, b,num;
a = 0;
b = r;
while(2 * b * b >= r * r)
{
OLED_DrawPoint(x + a, y - b,1);
OLED_DrawPoint(x - a, y - b,1);
OLED_DrawPoint(x - a, y + b,1);
OLED_DrawPoint(x + a, y + b,1);
OLED_DrawPoint(x + b, y + a,1);
OLED_DrawPoint(x + b, y - a,1);
OLED_DrawPoint(x - b, y - a,1);
OLED_DrawPoint(x - b, y + a,1);
a++;
num = (a * a + b * b) - r*r;//<2F><><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>Բ<EFBFBD>ĵľ<C4B5><C4BE><EFBFBD>
if(num > 0)
{
b--;
a--;
}
}
}
//<2F><>ָ<EFBFBD><D6B8>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>ʾһ<CABE><D2BB><EFBFBD>ַ<EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>
//x:0~127
//y:0~63
//size1:ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 6x8/6x12/8x16/12x24
//mode:0,<2C><>ɫ<EFBFBD><C9AB>ʾ;1,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1,u8 mode)
{
u8 i,m,temp,size2,chr1;
u8 x0=x,y0=y;
if(size1==8)size2=6;
else size2=(size1/8+((size1%8)?1:0))*(size1/2); //<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
chr1=chr-' '; //<2F><><EFBFBD><EFBFBD>ƫ<EFBFBD>ƺ<EFBFBD><C6BA>ֵ
for(i=0;i<size2;i++)
{
if(size1==8)
{temp=asc2_0806[chr1][i];} //<2F><><EFBFBD><EFBFBD>0806<30><36><EFBFBD><EFBFBD>
else if(size1==12)
{temp=asc2_1206[chr1][i];} //<2F><><EFBFBD><EFBFBD>1206<30><36><EFBFBD><EFBFBD>
else if(size1==16)
{temp=asc2_1608[chr1][i];} //<2F><><EFBFBD><EFBFBD>1608<30><38><EFBFBD><EFBFBD>
else if(size1==24)
{temp=asc2_2412[chr1][i];} //<2F><><EFBFBD><EFBFBD>2412<31><32><EFBFBD><EFBFBD>
else return;
for(m=0;m<8;m++)
{
if(temp&0x01)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp>>=1;
y++;
}
x++;
if((size1!=8)&&((x-x0)==size1/2))
{x=x0;y0=y0+8;}
y=y0;
}
}
//<2F><>ʾ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
//x,y:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//size1:<3A><><EFBFBD><EFBFBD><EFBFBD>С
//*chr:<3A>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ
//mode:0,<2C><>ɫ<EFBFBD><C9AB>ʾ;1,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode)
{
while((*chr>=' ')&&(*chr<='~'))//<2F>ж<EFBFBD><D0B6>Dz<EFBFBD><C7B2>ǷǷ<C7B7><C7B7>ַ<EFBFBD>!
{
OLED_ShowChar(x,y,*chr,size1,mode);
if(size1==8)x+=6;
else x+=size1/2;
chr++;
}
}
//m^n
u32 OLED_Pow(u8 m,u8 n)
{
u32 result=1;
while(n--)
{
result*=m;
}
return result;
}
//<2F><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
//x,y :<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//num :Ҫ<><D2AA>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//len :<3A><><EFBFBD>ֵ<EFBFBD>λ<EFBFBD><CEBB>
//size:<3A><><EFBFBD><EFBFBD><EFBFBD>С
//mode:0,<2C><>ɫ<EFBFBD><C9AB>ʾ;1,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1,u8 mode)
{
u8 t,temp,m=0;
if(size1==8)m=2;
for(t=0;t<len;t++)
{
temp=(num/OLED_Pow(10,len-t-1))%10;
if(temp==0)
{
OLED_ShowChar(x+(size1/2+m)*t,y,'0',size1,mode);
}
else
{
OLED_ShowChar(x+(size1/2+m)*t,y,temp+'0',size1,mode);
}
}
}
//<2F><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
//x,y:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//num:<3A><><EFBFBD>ֶ<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>
//mode:0,<2C><>ɫ<EFBFBD><C9AB>ʾ;1,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ
void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1,u8 mode)
{
u8 m,temp;
u8 x0=x,y0=y;
u16 i,size3=(size1/8+((size1%8)?1:0))*size1; //<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
for(i=0;i<size3;i++)
{
if(size1==16)
{temp=Hzk1[num][i];}//<2F><><EFBFBD><EFBFBD>16*16<31><36><EFBFBD><EFBFBD>
else if(size1==24)
{temp=Hzk2[num][i];}//<2F><><EFBFBD><EFBFBD>24*24<32><34><EFBFBD><EFBFBD>
else if(size1==32)
{temp=Hzk3[num][i];}//<2F><><EFBFBD><EFBFBD>32*32<33><32><EFBFBD><EFBFBD>
else if(size1==64)
{temp=Hzk4[num][i];}//<2F><><EFBFBD><EFBFBD>64*64<36><34><EFBFBD><EFBFBD>
else return;
for(m=0;m<8;m++)
{
if(temp&0x01)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp>>=1;
y++;
}
x++;
if((x-x0)==size1)
{x=x0;y0=y0+8;}
y=y0;
}
}
//num <20><>ʾ<EFBFBD><CABE><EFBFBD>ֵĸ<D6B5><C4B8><EFBFBD>
//space ÿһ<C3BF><D2BB><EFBFBD><EFBFBD>ʾ<EFBFBD>ļ<EFBFBD><C4BC>
//mode:0,<2C><>ɫ<EFBFBD><C9AB>ʾ;1,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ
void OLED_ScrollDisplay(u8 num,u8 space,u8 mode)
{
u8 i,n,t=0,m=0,r;
while(1)
{
if(m==0)
{
OLED_ShowChinese(128,24,t,16,mode); //д<><D0B4>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD>OLED_GRAM[][]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
t++;
}
if(t==num)
{
for(r=0;r<16*space;r++) //<2F><>ʾ<EFBFBD><CABE><EFBFBD>
{
for(i=1;i<144;i++)
{
for(n=0;n<8;n++)
{
OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
}
}
OLED_Refresh();
}
t=0;
}
m++;
if(m==16){m=0;}
for(i=1;i<144;i++) //ʵ<><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
for(n=0;n<8;n++)
{
OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
}
}
OLED_Refresh();
}
}
//x,y<><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//sizex,sizey,ͼƬ<CDBC><C6AC><EFBFBD><EFBFBD>
//BMP[]<5D><>Ҫд<D2AA><D0B4><EFBFBD>ͼƬ<CDBC><C6AC><EFBFBD><EFBFBD>
//mode:0,<2C><>ɫ<EFBFBD><C9AB>ʾ;1,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ
void OLED_ShowPicture(u8 x,u8 y,u8 sizex,u8 sizey,u8 BMP[],u8 mode)
{
u16 j=0;
u8 i,n,temp,m;
u8 x0=x,y0=y;
sizey=sizey/8+((sizey%8)?1:0);
for(n=0;n<sizey;n++)
{
for(i=0;i<sizex;i++)
{
temp=BMP[j];
j++;
for(m=0;m<8;m++)
{
if(temp&0x01)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp>>=1;
y++;
}
x++;
if((x-x0)==sizex)
{
x=x0;
y0=y0+8;
}
y=y0;
}
}
}
/*
*函数ABS_OLED_Init
*功能初始化OLED
*/
void ABS_OLED_Init(void)
{
OLED_RES_Clr();
#ifdef Enable_ABS_Delay
AbsOledDelay(3);
#endif
OLED_RES_Set();
AbsOledWriteCMD(CMD_OFF_OLED); //关闭OLED屏幕
AbsOledWriteCMD(CMD_Memory_Addr_Mode_OLED); //设置内存寻址模式,下一条命令设置值
AbsOledWriteCMD(0x10); //低2位的值[---- --**]00水平寻址模式;01、垂直寻址模式;10、页面寻址模式重置;11、无效
AbsOledWriteCMD(0xB0); //Set Page Start Address for Page Addressing Mode,0-7
AbsOledWriteCMD(0xC8); //Set COM Output Scan Direction
AbsOledWriteCMD(CMD_LColAddr_OLED); //---set low column address
AbsOledWriteCMD(CMD_HColAddr_OLED); //---set high column address
AbsOledWriteCMD(0x40); //--set start line address
AbsOledWriteCMD(CMD_Set_Contrast_Control_OLED); //--set contrast control register
AbsOledWriteCMD(0xFF);
AbsOledWriteCMD(0xA1); //--set segment re-map 0 to 127
AbsOledWriteCMD(CMD_Normal_display_OLED); //--set normal display
AbsOledWriteCMD(0xA8); //--set multiplex ratio(1 to 64)
AbsOledWriteCMD(0x3F); //
AbsOledWriteCMD(CMD_EntireDisplay_OLED); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
AbsOledWriteCMD(0xD3); //-set display offset
AbsOledWriteCMD(CMD_LColAddr_OLED); //-not offset
AbsOledWriteCMD(0xD5); //--set display clock divide ratio/oscillator frequency
AbsOledWriteCMD(0xF0); //--set divide ratio
AbsOledWriteCMD(0xD9); //--set pre-charge period
AbsOledWriteCMD(0x22); //
AbsOledWriteCMD(0xDA); //--set com pins hardware configuration
AbsOledWriteCMD(0x12);
AbsOledWriteCMD(0xDB); //--set vcomh
AbsOledWriteCMD(CMD_Memory_Addr_Mode_OLED); //0x20,0.77xVcc
AbsOledWriteCMD(0x8D); //--set DC-DC enable
AbsOledWriteCMD(0x14); //
AbsOledWriteCMD(CMD_ON_OLED); //--turn on SSD1306 panel
OLED_Clear();
}