[开发工具] 新定义MCU开发板测评+双色OLED屏显示驱动

[复制链接]
 楼主| jinglixixi 发表于 2022-11-4 20:21 | 显示全部楼层 |阅读模式
本帖最后由 jinglixixi 于 2022-11-5 10:16 编辑

前面解决了开发环境的问题,捎带着回顾了一下I/O口的使用,其千万不要小看了它,在ARM中往往是用专有的I2C和SPI接口,在单片机中即使没这些,单凭一个I/O口的模拟也能把问题搞定!
这里就屏2个I/O口来实现双色OLED屏的驱动,该显示屏为0.96寸,显示分辨率为160*80,其实说到它的双色也并不彻底,也就称得上是一个准双色屏,因为它的颜色是按区域指定的,而非随心所欲地用这仅有的2种色彩,不过首行的色彩对突出标题还是很有效果的。
在实现显示驱动的过程中,整体上并没有什么难度,无非是变换了一下所使用的语句形式,这其中关键的则是对延时长短的把控。通常,主频越高,在I/O口产生状态变换时越应注意,否则会影响正常脉冲时序的生成。
经实际测试,当在模拟I2C的启动和停止函数采用如下延时值时,OLED屏是可以显示信息的。
  1. voidIIC_Start()
  2. {
  3.    SCL = high;
  4.    Delay(2);
  5.    SDA = high;
  6.    Delay(2);
  7.    SDA = low;
  8.    Delay(2);
  9.    SCL = low;
  10.    Delay(2);
  11. }

  12. voidIIC_Stop()
  13. {
  14.    SCL = low;
  15.    Delay(2);
  16.    SDA = low;
  17.    Delay(2);
  18.    SCL = high;
  19.    Delay(2);
  20.    SDA = high;
  21.    Delay(2);
  22. }


其模拟I2C发送字节数据的函数为:
  1. voidWrite_IIC_Byte(unsigned char IIC_Byte)
  2. {
  3.     unsigned char i;
  4.     unsigned char m,da;
  5.     da=IIC_Byte;
  6.     SCL=0;
  7.     Delay(2);
  8.     for(i=0;i<8;i++)
  9.     {
  10.         m=da;
  11.         m=m&0x80;
  12.         if(m==0x80)
  13.         {
  14.             SDA=1;
  15.         }
  16.         else  SDA=0;
  17.         Delay(2);
  18.         da=da<<1;
  19.         SCL=1;
  20.         Delay(2);
  21.         SCL=0;
  22.         Delay(2);
  23.      }
  24. }

该屏的初始化函数为:
  1. voidOLED_Init(void)
  2. {
  3. OLED_WR_Byte(0xAE,OLED_CMD);
  4. OLED_WR_Byte(0x02,OLED_CMD);
  5. OLED_WR_Byte(0x10,OLED_CMD);
  6. OLED_WR_Byte(0x40,OLED_CMD);
  7. OLED_WR_Byte(0x81,OLED_CMD);
  8. OLED_WR_Byte(0xff,OLED_CMD);
  9. OLED_WR_Byte(0xA1,OLED_CMD);
  10. OLED_WR_Byte(0xC8,OLED_CMD);
  11. OLED_WR_Byte(0xA6,OLED_CMD);
  12. OLED_WR_Byte(0xA8,OLED_CMD);
  13. OLED_WR_Byte(0x3f,OLED_CMD);
  14. OLED_WR_Byte(0xD3,OLED_CMD);
  15. OLED_WR_Byte(0x00,OLED_CMD);
  16. OLED_WR_Byte(0xd5,OLED_CMD);
  17. OLED_WR_Byte(0x80,OLED_CMD);
  18. OLED_WR_Byte(0xD9,OLED_CMD);
  19. OLED_WR_Byte(0xF1,OLED_CMD);
  20. OLED_WR_Byte(0xDA,OLED_CMD);
  21. OLED_WR_Byte(0x12,OLED_CMD);
  22. OLED_WR_Byte(0xDB,OLED_CMD);
  23. OLED_WR_Byte(0x40,OLED_CMD);
  24. OLED_WR_Byte(0x20,OLED_CMD);
  25. OLED_WR_Byte(0x02,OLED_CMD);
  26. OLED_WR_Byte(0x8D,OLED_CMD);
  27. OLED_WR_Byte(0x14,OLED_CMD);
  28. OLED_WR_Byte(0xA4,OLED_CMD);
  29. OLED_WR_Byte(0xA6,OLED_CMD);
  30. OLED_WR_Byte(0xAF,OLED_CMD);
  31. OLED_WR_Byte(0xAF,OLED_CMD);
  32. OLED_Clear();
  33. OLED_Set_Pos(0,0);
  34. }

这与同样尺寸的单色显示屏是存在差异的,应该加以注意。
在测试中,为了获得合适的延时值,是通过清屏函数来进行的,其内容如下:
  1. voidOLED_Clear(void)
  2. {
  3.     unsigned char i,n;
  4.     for(i=0;i<8;i++)
  5.     {
  6.          OLED_WR_Byte(0xb0+i,OLED_CMD);
  7.          OLED_WR_Byte(0x00,OLED_CMD);
  8.          OLED_WR_Byte(0x10,OLED_CMD);
  9.          for(n=0;n<128;n++) OLED_WR_Byte(0xf0,OLED_DATA);
  10.     }
  11. }


其目的不在于清屏,而是在于获得可以观察效果的条纹,当出现图1所示的显示效果时,说明可以为它进行添加更多显示功能了。
1.jpg
图1 显示测试
在配备字库的情况下,其字符显示函数为:
  1. voidOLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr,unsigned char Char_Size)
  2. {
  3.      unsigned char c=0,i=0;
  4.      c=chr-' ';
  5.      if(x>Max_Column-1){x=0;y=y+2;}
  6.      if(Char_Size ==16)
  7.      {
  8.          OLED_Set_Pos(x,y);
  9.          for(i=0;i<8;i++)
  10.          OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
  11.          OLED_Set_Pos(x,y+1);
  12.          for(i=0;i<8;i++)
  13.          OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
  14.       }
  15.       else
  16.       {
  17.          OLED_Set_Pos(x,y);
  18.          for(i=0;i<6;i++)
  19.          OLED_WR_Byte(F6x8[c][i],OLED_DATA);
  20.       }
  21. }

相应的字符串显示函数为:
  1. voidOLED_ShowString(unsigned char x,unsigned char y,char *chr,unsigned char Char_Size)
  2. {
  3.      unsigned char j=0;
  4.      while (chr[j]!='\0')
  5.      {      
  6.           OLED_ShowChar(x,y,chr[j],Char_Size);
  7.           x+=8;
  8.           if(x>120){x=0;y+=2;}
  9.           j++;
  10.     }
  11. }


在使用如下的主程序情况下,则可获得图2所示的显示效果。

  1. void main(void)
  2. {
  3.          IO_Init();
  4.          OLED_Init();
  5.          OLED_Clear();
  6.          OLED_ShowString(10,0,"NBK-RD8x3x",16);
  7.          OLED_ShowString(10,2,"DB0002",16);
  8.          OLED_ShowString(10,6,"jinglixixi",16);
  9.          while(1)
  10.          {
  11.                      P01=1;
  12.                      Delay(1000000);
  13.                      P01=0;
  14.                      Delay(1000000);
  15.          }
  16. }

2.jpg
图2 显示字符串

有了OLED屏的显示功能,在串口调试的基础上就又多了一种观察调试的手段,也是开发板的功能得到了进一步的扩展和加强。

Anrenly 发表于 2022-11-4 22:10 来自手机 | 显示全部楼层
这是用GPIO口模拟的IIC,看介绍开发板的IC自带的硬件IIC可以驱动屏显吗?
 楼主| jinglixixi 发表于 2022-11-5 10:15 | 显示全部楼层
Anrenly 发表于 2022-11-4 22:10
这是用GPIO口模拟的IIC,看介绍开发板的IC自带的硬件IIC可以驱动屏显吗?

没去试,感兴趣可以亲自试试。
henangongda123 发表于 2022-11-6 14:42 | 显示全部楼层
楼主这个屏是多大的?0.96?
 楼主| jinglixixi 发表于 2022-11-6 23:27 | 显示全部楼层
是0.96的
天天向善 发表于 2022-11-8 14:04 | 显示全部楼层
屏幕刷新速率怎么样?
 楼主| jinglixixi 发表于 2022-11-8 15:59 | 显示全部楼层
天天向善 发表于 2022-11-8 14:04
屏幕刷新速率怎么样?

很快
天天向善 发表于 2022-12-3 19:53 | 显示全部楼层

哈哈,量化是多少。。。
 楼主| jinglixixi 发表于 2022-12-3 23:18 | 显示全部楼层
天天向善 发表于 2022-12-3 19:53
哈哈,量化是多少。。。

查手册吧,不涉及产品不关心这个。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

518

主题

2934

帖子

39

粉丝
快速回复 在线客服 返回列表 返回顶部