在前一篇我们驱动了OLED,这一篇将重构显示buff、全屏更新OLED显存。并添加显示字符串功能。
1、拷贝一个字符文件到工程中:

2、新建一个结构体,用于显示与命令的存放:
static struct OLED_all_buff_t{
	uint8_t cmd;
	uint8_t data[1024]; //显存
} OLED_all_buff;3、修改向OLED写入整个显存的函数如下:
static void OLED_Display(struct DisplayDevice* ptDev)
{
	OLED_all_buff.cmd = 0x40;  //写数据
	//以下为修改为页寻址模式
	OLEDDrvWriteReg(0x20);  
	OLEDDrvWriteReg(0x00);
	OLEDDrvWriteReg(0x21);
	OLEDDrvWriteReg(0x00);
	OLEDDrvWriteReg(127);
	OLEDDrvWriteReg(0x22);
	OLEDDrvWriteReg(0x00);
	OLEDDrvWriteReg(7);
	//向OLED写入整屏
	R_SAU_I2C_Write(&g_sau_i2c_master_ctrl, &OLED_all_buff, 1025, true);
	//等待发送结束
	I2C1WaitTxCplt();
}4、修改画点的函数,将画点修改为向显示缓存修改数据:
static int OLEDDrvSetPixel(struct DisplayDevice* ptDev, unsigned short wX, unsigned short wY, unsigned short wColor)
{
    if(NULL == ptDev->name)    return -1;
    unsigned char *buf = ptDev->FBBase;
    int page;
    unsigned char *byte;
    int bit;
    if (wX >= ptDev->wXres || wY >= ptDev->wYres)
        return -1;
		if(wColor) {
		buf[(wY/8)*128+wX]|= (1<<(wY%8))&0xff;
		} else {
			buf[(wY/8)*128+wX]&= ~((1<<(wY%8))&0xff);
		}
}5、添加字符显示函数:
static void OLED_ShowChar(struct DisplayDevice* ptDev,uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size,uint8_t mode) {
	if(NULL == ptDev->name)    return;
    unsigned char c=0,i=0,tmp,j=0;
    c=chr-' ';//转换为字库里的序号
    if(x>ptDev->wXres-1){x=0;y=y+2;}
    if(Char_Size ==16) {
        for(i=0;i<16;i++) {
          if(mode) {
                tmp = F8X16[c*16+i];
            } else {
                tmp = ~(F8X16[c*16+i]);
            }
            for(j=0;j<8;j++) {
                if(tmp&(0x80>>j)) {
                    ptDev->SetPixel(ptDev,x+j, y+i,1);
                } else {
                     ptDev->SetPixel(ptDev,x+j, y+i,0);
                }
            }
        }
    } else if(Char_Size==8) {
        for(i=0;i<8;i++) {
            if(mode) {
                tmp = F6x8[c][i];
            } else {
                tmp = ~(F6x8[c][i]);
            }
            for(j=0;j<8;j++) {
                if(tmp&(0x80>>j)) {
                     ptDev->SetPixel(ptDev,x+j, y+i,1);
                } else {
                     ptDev->SetPixel(ptDev,x+j, y+i,0);
                }
            }
        }
	} else {
		return;
	}
}6、添加显示字符串的函数如下:
static void OLED_ShowString(struct DisplayDevice* ptDev,uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size,uint8_t mode) {
	unsigned char j=0,csize;
	if(Char_Size == 16) {
        csize = Char_Size/2;
	} else if(Char_Size == 8) {
        csize = Char_Size/2+2;
	} else {
		return;
	}
	while (chr[j]!='\0') {
		OLED_ShowChar(ptDev,x,y,chr[j],Char_Size,mode);
		x+=csize;
		if(x>120) {
			x=0;
			y+=Char_Size;
		}
		j++;
	}
	//OLED_Display();
}7、将上面的函数更新到LCD驱动里面,
static DisplayDevice gOledDev = {
                             .name = "OLED",
                             .FBBase = OLED_all_buff.data,
                             .wXres = 128,
                             .wYres = 64,
                             .wBpp = 1,
                             .dwSize = 128*64*1/8,
                             .Init = OLEDDrvinit,
                             .DisplayON = OLEDDrvDispON,
                             .DisplayOFF = OLEDDrvDispOFF,
                             .SetDisplayWindow = OLEDDrvSetDispWindow,
                             .SetPixel = OLEDDrvSetPixel,
	                     .GUI_DrawPoint = OLED_DrawPoint, //画点
	                     .GUI_ShowChar = OLED_ShowChar,   //画字符
	                     .GUI_ShowString = OLED_ShowString, //显示字符串
	                     .GUI_Display = OLED_Display,       //更新显存
};8、这样,我们在主函数里实例化OLED对象,就可以用他的方法来显示字符或者字符串了,在主函数中加入测试函数如下:
void led_blink(void)
{
	uint32_t cnt;
	UartDevicesRegister();
	DisplayDevice *ptDispDev = OLEDGetDevice();
    if(ptDispDev == NULL)
    {
        printf("Failed to get OLED Display Device!\r\n");
        return;
    }
    ptDispDev->Init(ptDispDev);
	while(1)
	{
           ptDispDev->GUI_Fill(ptDispDev,0); //清理显存
	   ptDispDev->GUI_ShowString(ptDispDev,0,0, (uint8_t *)"HELLO WORLD",16,1);  //显示字符串
	   ptDispDev->GUI_ShowString(ptDispDev,10,16, (uint8_t *)"HELLO EEPW",16,1);
	   ptDispDev->GUI_Display(ptDispDev);  //刷新数据到OLED
	   HAL_Delay(2);
		
	}
}【实现效果】

【总结】
对于面向象对象的编程,我们可以方便的实现模块化的编程。方便在不同的MCU之间的移植。

 
					
				
 
			
			
			
						
			 
					
				 
					
				 
					
				 
					
				 
					
				 
					
				 
					
				 
					
				 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

