瑞萨RA0单片机连载⸺OLED面向对象显示字符串
在前一篇我们驱动了OLED,这一篇将重构显示buff 、全屏更新OLED 显存。并添加显示字符串功能。
1.拷贝一个字符文件到工程中:
2.新建一个结构体,用于显示与命令的存放:
view plaincopy to clipboardprint?
1. static struct OLED_all_buff _t{
2. uint8_t cmd;
3. uint8_t data[1024]; // 显存
4. } OLED_all_buff ;
3.修改向OLED 写入整个显存的函数如下:
view plaincopy to clipboardprint?
1. static void OLED_Display(struct DisplayDevice*
ptDev)
2. {
3.
4. OLED_all_buff .cmd = 0x40; // 写数据
5. // 以下为修改为页寻址模式
6. OLEDDrvWriteReg(0x20);
7. OLEDDrvWriteReg(0x00);
8. OLEDDrvWriteReg(0x21);
9. OLEDDrvWriteReg(0x00);
10. OLEDDrvWriteReg(127);
11. OLEDDrvWriteReg(0x22);
12. OLEDDrvWriteReg(0x00);
13. OLEDDrvWriteReg(7);
14. // 向OLED 写入整屏
15. R_SAU_I2C_Write(&g_sau_i2c_master_ctrl, &
OLED_all_buff , 1025, true);
16. // 等待发送结束
17. I2C1WaitTxCplt();
18. }
4.修改画点的函数,将画点修改为向显示缓存修改数据:
view plaincopy to clipboardprint?
1. static int OLEDDrvSetPixel(struct DisplayDevice
* ptDev, unsigned short wX, unsigned short wY, u
nsigned short wColor)
2. {
3. if(NULL == ptDev->name) return -1;
4.
5. unsigned char *buf = ptDev->FBBase;
6. int page;
7. unsigned char *byte;
8. int bit;
9.
10. if (wX >= ptDev->wXres || wY >= ptDev->wYres)
11. return -1;
12. if(wColor) {
13. buf[(wY/8)*128+wX]|= (1<<(wY%8))&0xff ;
14. } else {
15. buf[(wY/8)*128+wX]&= ~((1<<(wY%8))
&0xff);
16. }
17. }
5.添加字符显示函数:
view plaincopy to clipboardprint?
1. static void OLED_ShowChar(struct DisplayDev
ice* ptDev,uint8_t x,uint8_t y,uint8_t chr,uint8_
t Char_Size,uint8_t mode) {
2. if(NULL == ptDev->name) return;
3. unsigned char c=0,i=0,tmp,j=0;
4. c=chr-’ ‘;// 转换为字库里的序号
5. if(x>ptDev->wXres-1){x=0;y=y+2;}
6. if(Char_Size ==16) {
7. for(i=0;i<16;i++) {
8. if(mode) {
9. tmp = F8X16[c*16+i];
10. } else {
11. tmp = ~(F8X16[c*16+i]);
12. }
13. for(j=0;j<8;j++) {
14. if(tmp&(0x80>>j)) {
15. ptDev->SetPixel(ptDev,x+j, y+i,1);
16. } else {
17. ptDev->SetPixel(ptDev,x+j, y+i,0);
18. }
19. }
20. }
21. } else if(Char_Size==8) {
22. for(i=0;i<8;i++) {
23. if(mode) {
24. tmp = F6x8[c][i];
25. } else {
26. tmp = ~(F6x8[c][i]);
27. }
28. for(j=0;j<8;j++) {
29. if(tmp&(0x80>>j)) {
30. ptDev->SetPixel(ptDev,x+j, y+i,1);
31. } else {
32. ptDev->SetPixel(ptDev,x+j, y+i,0);
33. }
34. }
35. }
36. } else {
37. return;
38. }
39. }
6.添加显示字符串的函数如下:
view plaincopy to clipboardprint?
1. static void OLED_ShowString(struct DisplayDev
ice* ptDev,uint8_t x,uint8_t y,uint8_t *chr,uint8_
t Char_Size,uint8_t mode) {
2. unsigned char j=0,csize;
3. if(Char_Size == 16) {
4. csize = Char_Size/2;
5. } else if(Char_Size == 8) {
6. csize = Char_Size/2+2;
7. } else {
8. return;
9. }
10.
11. while (chr[j]!=’�’) {
12. OLED_ShowChar(ptDev,x,y,chr[j],Char_
Size,mode);
13. x+=csize;
14. if(x>120) {
15. x=0;
16. y+=Char_Size;
17. }
18. j++;
19. }
20. //OLED_Display();
21. }
7.将上面的函数更新到LCD 驱动里面,
view plaincopy to clipboardprint?
1. static DisplayDevice gOledDev = {
2. .name = “OLED”,
3. .FBBase = OLED_all_buff.data,
4. .wXres = 128,
5. .wYres = 64,
6. .wBpp = 1,
7. .dwSize = 128*64*1/8,
8. .Init = OLEDDrvinit,
9. .DisplayON = OLEDDrvDispON,
10. .DisplayOFF = OLEDDrvDispOFF,
11. .SetDisplayWindow = OLEDDrvSetDispWindow,
12. .SetPixel = OLEDDrvSetPixel,
13. .GUI_DrawPoint = OLED_DrawPoint, // 画点
14. .GUI_ShowChar = OLED_ShowChar, // 画字符
15. .GUI_ShowString = OLED_ShowString, // 显示字符串
16. .GUI_Display = OLED_Display, // 更新显存
17. };
8.这样,我们在主函数里实例化OLED 对象,就可以用他的方法来显示字符或者字符串了,在主函数中加入测试函数如下:
view plaincopy to clipboardprint?
1. void led_blink(void)
2. {
3. uint32_t cnt;
4. UartDevicesRegister();
5.
6. DisplayDevice *ptDispDev = OLEDGetDevice();
7. if(ptDispDev == NULL)
8. {
9. printf("Failed to get OLED Display Device!rn");
10. return;
11. }
12.
13. ptDispDev->Init(ptDispDev);
14. while(1)
15. {
16. ptDispDev->GUI_Fill(ptDispDev,0); //清理显存
17. ptDispDev->GUI_ShowString(ptDispDev,0,0, (uint8_t *)”HELLO WORLD”,16,1); //显示字符串
18. ptDispDev->GUI_ShowString(ptDispDev,10,
16, (uint8_t *)”HELLO EEPW”,16,1);
19. ptDispDev->GUI_Display(ptDispDev); //刷新数据到OLED
20. HAL_Delay(2);
21.
22. }
23. }
1 实现效果
2 总结
对于面向象对象的编程,我们可以方便的实现模块化的编程。方便在不同的MCU 之间的移植。
(本文来源于《EEPW》202504)