本帖最后由 jinglixixi_457498010 于 2022-7-5 23:38 编辑

OLED屏的种类比较多,按接口方式可分为I2C与SPI接口方式,按色彩可分为单色、双色及测试屏,按尺寸和分辨率来分,则更是多种多样。
为了显示图片的需要,这里使用的一款SPI接口的彩色OLED屏,其分辨率为160*80像素点,几何尺寸为0.96寸。
image.png
图1 彩色OLED屏
该显示屏与开发板的连接关系为:
CLK---PB13
DIN---PB14
RST---PB15
DC ---PB12
CS ---PB0
BLK---PB1
image.png
图2 使用扩展接口
为便于使用,这里仍以GPIO口模拟SPI的方式来实现显示驱动,各引脚输出高低电平的语句定义为:
#defineOLED_SCLK_Set()   GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_SET)   //CLK
#defineOLED_SCLK_Clr()   GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_RESET)
#defineOLED_SDIN_Set()   GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_SET)   //DIN
#defineOLED_SDIN_Clr()   GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_RESET)
#defineOLED_RST_Set()    GPIO_WriteBit(GPIOB,GPIO_Pin_15,Bit_SET)   //RES
#defineOLED_RST_Clr()    GPIO_WriteBit(GPIOB,GPIO_Pin_15,Bit_RESET)
#defineOLED_DC_Set()     GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET)   //DC
#defineOLED_DC_Clr()     GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET)
#defineOLED_CS_Set()     GPIO_WriteBit(GPIOB,GPIO_Pin_0,Bit_SET)    //CS
#defineOLED_CS_Clr()     GPIO_WriteBit(GPIOB,GPIO_Pin_0,Bit_RESET)
#defineOLED_BLK_Set()    GPIO_WriteBit(GPIOB,GPIO_Pin_1,Bit_SET)    //BLK
#defineOLED_BLK_Clr()    GPIO_WriteBit(GPIOB,GPIO_Pin_1,Bit_RESET)
对相关引脚进行功能配置的函数为:
  1. void app_LCD_Init(void)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  4.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  5.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
  6.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  7.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  8.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  9. }

为便于显示的图片与显示屏相匹配,可使用图3所示的软件加以处理,并将生成的文件类型设为*.h。
image.png
图3 图片处理
显示图片显示的函数为:
  1. void LCD_ShowPicturea(u16 x1,u16 y1,u16 x2,u16 y2)
  2. {
  3.       int i;
  4.       LCD_Address_Set(x1,y1,x2,y2);
  5.       for(i=0;i<12800;i++)
  6.       {
  7.             LCD_WR_DATA8(gImage_FJ[i*2]);
  8.             LCD_WR_DATA8(gImage_FJ[i*2+1]);
  9.       }
  10. }

实现字符串显示的函数为:
  1. void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 color)
  2. {
  3.     while(*p!='\0')
  4.     {
  5.         if(x>LCD_W-16)
  6.        {
  7.               x=0;
  8.               y+=16;
  9.        }
  10.         if(y>LCD_H-16)
  11.         {
  12.              y=x=0;
  13.              LCD_Clear(RED);
  14.         }
  15.         LCD_ShowChar(x,y,*p,0,color);
  16.         x+=8;
  17.         p++;
  18.     }
  19. }

为实现图4和图5的显示效果,其主程序为:
  1. int main(void)
  2. {
  3.     LED1_BLINK_INIT();
  4.     GPIO_ResetBits(GPIOA,GPIO_Pin_0);
  5.     app_LCD_Init();
  6.     Lcd_Init();
  7.     LCD_Clear(BLACK);
  8.     LCD_ShowString(20,10, "CH32V307 TEST",RED);
  9.     LCD_ShowString(20,30,"0.96'  OLED",YELLOW);
  10.     rt_thread_mdelay(2000);
  11.     LCD_ShowPicturea(0,0,159,79);
  12.     rt_thread_mdelay(2000);
  13.     LCD_ShowPictureb(0,0,159,79);
  14.     while(1)
  15.     {
  16.              GPIO_SetBits(GPIOA,GPIO_Pin_0);
  17.              rt_thread_mdelay(500);
  18.              GPIO_ResetBits(GPIOA,GPIO_Pin_0);
  19.              rt_thread_mdelay(500);
  20.     }
  21. }

image.png
图4 文字显示效果
image.png
图5 图片显示效果