/*文件:AbsDrive_OLED.c * 作者:你遇了我 * 联系:321640253@qq.com * 描述:抽象硬件OLED屏幕,只需要实现指定的抽象函数,即可使用 * 使用:1、根据配置区,在抽象实现区按照要求实现对应函数 */ #include "AbsDrive_OLED.h" #include "AbsDriveOledFont.h" /**************************抽象实现区(BEGIN)************************************/ /*抽象函数:写字节 *要求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_OLED_RES /*抽象函数:复位信号函数 *要求1:根据电平值设置复位引脚电平 *参数1:electrical_level:电平值,1、高电平;0、低电平 */ static void AbsDriveOLED_RES(u8 electrical_level){ /********************请实现抽象复位信号函数********************/ if(electrical_level)HAL_GPIO_WritePin(oled_res_GPIO_Port,oled_res_Pin,GPIO_PIN_SET); else HAL_GPIO_WritePin(oled_res_GPIO_Port,oled_res_Pin,GPIO_PIN_RESET); /********************请实现抽象复位信号函数********************/ } #endif #ifdef Enable_ABS_OLED_DC /*抽象函数:片选信号函数 *要求1:根据电平值设置片选引脚电平 *参数1:electrical_level:电平值,1、高电平;0、低电平 */ static void AbsDriveOLED_DC(u8 electrical_level){ /********************请实现抽象复位信号函数********************/ if(electrical_level)HAL_GPIO_WritePin(oled_DC_GPIO_Port,oled_DC_Pin,GPIO_PIN_SET); else HAL_GPIO_WritePin(oled_DC_GPIO_Port,oled_DC_Pin,GPIO_PIN_RESET); /********************请实现抽象复位信号函数********************/ } #endif #ifdef Enable_ABS_OLED_Delay /*抽象函数:延时函数 *要求1:实现延时函数、 *参数1:t:延时时间 */ static void AbsOledDelay(u32 t){ /********************请实现抽象延时函数********************/ while(t--){} //默认循环while(t--){},可重写 /********************请实现抽象延时函数********************/ } #endif /**************************抽象实现区(END)**************************************/ /*----------------------------------------------分割线(以下内容非开发人员切勿改动)---------------------------------------------------------*/ u8 ABS_OLED_GRAM[ABS_OLED_WIDTH][ABS_OLED_PAGE_SIZE]; //定义显存 /* *函数:AbsOledWriteCMD *功能:写OLED命令 *参数:ABScmd:命令 *返回值:AbsDriveOLED_STATE状态 */ AbsDriveOLED_STATE AbsOledWriteCMD(u8 ABScmd){ #ifdef ABSDrive_4SPI AbsDriveOLED_DC(0); 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 AbsDriveOLED_DC(1); if(AbsOledWriteByte(&ABSdata,1)==ABS_OLED_OK)return ABS_OLED_OK; #endif #ifdef ABSDrive_3SPI #endif return ABS_OLED_ERROR; } /* *函数:ABS_OLED_Refresh *描述:刷新OLED显存 */ void ABS_OLED_Refresh(void) { u8 i,n; for(i=0;i0)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_x;} if(delta_x>delta_y)distance=delta_x; else distance=delta_y; for(t=0;tdistance) { xerr-=distance; uRow+=incx; } if(yerr>distance) { yerr-=distance; uCol+=incy; } } } /*函数:ABS_OLED_DrawCircle **描述:按照中心坐标绘制半径r的圆 **参数1:x:中心x坐标 取值返回小于ABS_OLED_WIDTH **参数2:y:中心y坐标 取值返回小于ABS_OLED_HEIGHT **参数3:mode:绘制模式,1:填充;0:清空 */ void ABS_OLED_DrawCircle(u8 x,u8 y,u8 r) { int a, b,num; a = 0; b = r; while(2 * b * b >= r * r) { ABS_OLED_DrawPoint(x + a, y - b,1); ABS_OLED_DrawPoint(x - a, y - b,1); ABS_OLED_DrawPoint(x - a, y + b,1); ABS_OLED_DrawPoint(x + a, y + b,1); ABS_OLED_DrawPoint(x + b, y + a,1); ABS_OLED_DrawPoint(x + b, y - a,1); ABS_OLED_DrawPoint(x - b, y - a,1); ABS_OLED_DrawPoint(x - b, y + a,1); a++; num = (a * a + b * b) - r*r; if(num > 0) { b--; a--; } } } /*函数:ABS_OLED_ShowChar **描述:在指定位置打印字符 **参数1:x1:起始x坐标 取值返回小于ABS_OLED_WIDTH **参数2:y1:起始y坐标 取值返回小于ABS_OLED_HEIGHT **参数3:chr:需要打印的字符 **参数4:sizel:打印字符的字体大小。字库有8*6、12*6、16*8、24*12 **参数5:mode:打印模式,1:正常显示 ;0:反向显示 */ void ABS_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); chr1=chr-' '; for(i=0;i>=1; y++; } x++; if((size1!=8)&&((x-x0)==size1/2)) {x=x0;y0=y0+8;} y=y0; } } /*函数:ABS_OLED_ShowString **描述:在指定位置打印字符串 **参数1:x1:起始x坐标 取值返回小于ABS_OLED_WIDTH **参数2:y1:起始y坐标 取值返回小于ABS_OLED_HEIGHT **参数3:chr:需要打印的字符 **参数4:sizel:打印字符的字体大小。字库有8*6、12*6、16*8、24*12 **参数5:mode:打印模式,1:正常显示 ;0:反向显示 */ void ABS_OLED_ShowString(u8 x,u8 y,char *chr,u8 size1,u8 mode) { while((*chr>=' ')&&(*chr<='~')) { ABS_OLED_ShowChar(x,y,*chr,size1,mode); if(size1==8)x+=6; else x+=size1/2; chr++; } } /*函数:ABS_OLED_Pow **描述:内部函数,用于求次方 **参数1:m:底数 **参数2:n:指数 */ static u32 ABS_OLED_Pow(u8 m,u8 n) { u32 result=1; while(n--) { result*=m; } return result; } /*函数:ABS_OLED_ShowNum **描述:在指定位置打印数字 **参数1:x1:起始x坐标 取值返回小于ABS_OLED_WIDTH **参数2:y1:起始y坐标 取值返回小于ABS_OLED_HEIGHT **参数3:num:需要打印的数字 **参数3:len:数字长度,几位数 **参数5:sizel:打印字符的字体大小。字库有8*6、12*6、16*8、24*12 **参数6:mode:打印模式,1:正常显示 ;0:反向显示 **/ void ABS_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>=1; y++; } x++; if((x-x0)==size1) {x=x0;y0=y0+8;} y=y0; } } /*函数:ABS_OLED_ScrollDisplay **描述:滚动显示中文字符 **参数1:num:显示汉字个数 **参数2:space:每遍显示的间隔 **参数3:mode:打印模式,1:正常显示 ;0:反向显示 **/ void ABS_OLED_ScrollDisplay(u8 num,u8 space,u8 mode) { u8 i,n,t=0,m=0,r; while(1) { if(m==0) { ABS_OLED_ShowChinese(128,24,t,16,mode); t++; } if(t==num) { for(r=0;r<16*space;r++) { for(i=1;i<144;i++) { for(n=0;n<8;n++) { ABS_OLED_GRAM[i-1][n]=ABS_OLED_GRAM[i][n]; } } ABS_OLED_Refresh(); } t=0; } m++; if(m==16){m=0;} for(i=1;i<144;i++) { for(n=0;n<8;n++) { ABS_OLED_GRAM[i-1][n]=ABS_OLED_GRAM[i][n]; } } ABS_OLED_Refresh(); } } /*函数:ABS_OLED_ShowPicture **描述:显示图片 **参数1:x1:起始x坐标 取值返回小于ABS_OLED_WIDTH **参数2:y1:起始y坐标 取值返回小于ABS_OLED_HEIGHT **参数3:sizex:图片的长 **参数4:sizey:图片的高 **参数5:BMP[]:要写入的图片数组 **参数6:mode:打印模式,1:正常显示 ;0:反向显示 **/ void ABS_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>=1; y++; } x++; if((x-x0)==sizex) { x=x0; y0=y0+8; } y=y0; } } } /* *函数:ABS_OLED_Init *功能:初始化OLED */ void ABS_OLED_Init(void) { #ifdef Enable_ABS_OLED_RES AbsDriveOLED_RES(0); //复位 #endif #ifdef Enable_ABS_OLED_Delay AbsOledDelay(3); //延时 #endif #ifdef Enable_ABS_OLED_RES AbsDriveOLED_RES(1); //启用正常工作 #endif AbsOledWriteCMD(CMD_OFF_OLED); //关闭OLED屏幕、单次命令 AbsOledWriteCMD(CMD_Memory_Addr_Mode_OLED); //设置内存寻址模式;连续命令 AbsOledWriteCMD(0x10); //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 ABS_OLED_Clear(); } /*函数Create_OLED * 描述:创建OLED设备 */ ABS_OLED_Drive Create_OLED(void){ ABS_OLED_Drive drive; drive.Clear = ABS_OLED_Clear; drive.Refresh=ABS_OLED_Refresh; drive.DrawPoint=ABS_OLED_DrawPoint; drive.DrawLine=ABS_OLED_DrawLine; drive.DrawCircle=ABS_OLED_DrawCircle; drive.ShowString=ABS_OLED_ShowString; drive.ShowChinese=ABS_OLED_ShowChinese; drive.ShowNum=ABS_OLED_ShowNum; drive.Showdecimal=ABS_OLED_Showdecimal; drive.ShowImage=ABS_OLED_ShowPicture; ABS_OLED_Init(); return drive; }