这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » Renesas » 瑞萨RA0单片机连载之六——OLED面向对象显示字符串

共10条 1/1 1 跳转至

瑞萨RA0单片机连载之六——OLED面向对象显示字符串

助工
2024-05-31 20:04:51     打赏

在前一篇我们驱动了OLED,这一篇将重构显示buff、全屏更新OLED显存。并添加显示字符串功能。

1、拷贝一个字符文件到工程中:

image.png

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);
		
	}
}

【实现效果】

image.png

【总结】

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





关键词: 刘工爱评测之瑞萨RA0单片机     OLED    

院士
2024-05-31 21:31:22     打赏
2楼

谢谢楼主的分享~!


工程师
2024-06-01 04:29:58     打赏
3楼

感谢分享


专家
2024-06-01 09:01:34     打赏
4楼

感谢分享


专家
2024-06-01 09:11:17     打赏
5楼

感谢楼主分享


专家
2024-06-01 10:34:03     打赏
6楼

谢谢分享!


高工
2024-06-01 14:39:55     打赏
7楼

谢谢


高工
2024-06-01 16:48:19     打赏
8楼

谢谢


高工
2024-06-01 17:03:27     打赏
9楼

谢谢分享


高工
2024-06-02 16:30:12     打赏
10楼

感谢大佬


共10条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]