搜索
打印

[PIC®/AVR® MCU] 【CuriosityNano测评报告】+I2C接口的OLED屏显示驱动

[复制链接]
41266|5
跳转到指定楼层
本帖最后由 jinglixixi 于 2021-6-7 10:21 编辑

#申请原创#
PIC18F16Q40开发板是一款小巧的开发工具,为其配上一个小型的显示器件能使它更便于使用,这次就为它配上一个0.91寸的单色OLED屏,该显示屏采用I2C接口来工作,故十分节省引脚资源。此外,它在信息显示量上也不逊色于LCD1602这样的液晶屏。
该OLED屏的显示效果如下图所示,它与开发板的连接关系为:
VCC---5V
GND---GND
DIN---RC4
CLK---RC6
图1 OLED屏显示效果
为此其MCC的引脚配置情况如图2所示,相应的引脚命名如图3所示。
图2引脚配置
3 引脚命名
此外,为便于编程还调用了系统的延时函数,见图4所示。
图4 启用延时函数

OLED屏的参数定义为:
#define OLED_MODE 0
#define SIZE 16
#define XLevelL      0x02
#define XLevelH      0x10
#define Max_Column   128
#define Max_Row      64
#define Brightness   0xFF
#define X_WIDTH  128
#define Y_WIDTH  64
#define OLED_CMD  0

#define OLED_DATA 1

为显示字符所使用的字模被存放在数组中,其格式为:
uint8_t F8X16[]=      
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//0
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//!1
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//"2
  ...
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//016

0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//117
  ...
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A33
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B34
  ...
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a65
0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b66
  ...
};

相关的I2C模拟函数为:
  1. void IIC_Start()
  2. {
  3.   CLK_SetHigh();
  4.   DIN_SetHigh();
  5.   DIN_SetLow();
  6.   CLK_SetLow();
  7. }
  8. void IIC_Stop()
  9. {
  10.   CLK_SetHigh();
  11.   DIN_SetLow();
  12.   DIN_SetHigh();
  13. }

  14. void IIC_Wait_Ack()
  15. {
  16.    CLK_SetHigh();
  17.    CLK_SetLow();
  18. }
复制代码

字节数据发送函数为:
  1. void Write_IIC_Byte(unsigned char IIC_Byte)
  2. {
  3.     chari;
  4.     charm,da;
  5.     da=IIC_Byte;
  6.     CLK_SetLow();
  7.     for(i=0;i<8;i++)                 
  8.     {
  9.       m=da;
  10.       m=m&0x80;
  11.       if(m==0x80)
  12.       {
  13.           DIN_SetHigh();
  14.       }
  15.           else  DIN_SetLow();
  16.           DELAY_milliseconds(1);
  17.           da= da << 1;
  18.           CLK_SetHigh();
  19.           CLK_SetLow();
  20.     }
  21. }
复制代码

其清屏函数为:
  1. void OLED_Clear(void)  
  2. {  
  3.     uint8_ti,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(0,OLED_DATA);
  10.     }
  11. }
复制代码

相应的字符显示函数是:
  1. void OLED_ShowChar(uint8_t x,uint8_ty,uint8_t chr,uint8_t 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. }
复制代码

对应的OLED屏初始化函数是:
  1. void OLED_Init(void)
  2. {
  3.    CLK_SetHigh();
  4.    DIN_SetHigh();
  5.    DELAY_milliseconds(800);
  6.    OLED_WR_Byte(0xAE,OLED_CMD);//--display off
  7.    OLED_WR_Byte(0x40,OLED_CMD);//--setstart line address  
  8.    OLED_WR_Byte(0xB0,OLED_CMD);//--setpage address
  9.    OLED_WR_Byte(0xC8,OLED_CMD);//Comscan direction
  10.    OLED_WR_Byte(0x81,OLED_CMD);// contract control
  11.    OLED_WR_Byte(0xFF,OLED_CMD);//--128   
  12.    OLED_WR_Byte(0xA1,OLED_CMD);//setsegment remap
  13.    OLED_WR_Byte(0xA6,OLED_CMD);//--normal/ reverse
  14.    OLED_WR_Byte(0xA8,OLED_CMD);//--setmultiplex ratio(1 to 64)
  15.    OLED_WR_Byte(0x1F,OLED_CMD);//--1/32duty         
  16.    OLED_WR_Byte(0xD3,OLED_CMD);//-setdisplay offset
  17.    OLED_WR_Byte(0x00,OLED_CMD);//  
  18.    OLED_WR_Byte(0xD5,OLED_CMD);//setosc division
  19.    OLED_WR_Byte(0xf0,OLED_CMD);//   
  20.    OLED_WR_Byte(0xD9,OLED_CMD);//SetPre-Charge Period
  21.    OLED_WR_Byte(0x22,OLED_CMD);//  
  22.    OLED_WR_Byte(0xDA,OLED_CMD);//setcom pin configuartion
  23.    OLED_WR_Byte(0x02,OLED_CMD);//  
  24.    OLED_WR_Byte(0xDB,OLED_CMD);//setVcomh
  25.    OLED_WR_Byte(0x49,OLED_CMD);//  
  26.    OLED_WR_Byte(0x8D,OLED_CMD);//setcharge pump enable
  27.    OLED_WR_Byte(0x14,OLED_CMD);//  
  28.    OLED_WR_Byte(0xAF,OLED_CMD);//--turnon oled panel
  29.    OLED_Clear();
  30. }
复制代码

实现显示效果的主程序为:
  1. void main(void)
  2. {
  3.    SYSTEM_Initialize();
  4.    LED_SetLow();
  5.    OLED_Init();
  6.    OLED_Clear();
  7.    OLED_ShowString(0,0,"PIC18F16Q40TEST",16);
  8.    OLED_ShowString(0,2,"OLEDDISPLAY",16);
  9.    while (1)
  10.    {
  11.      LED_Toggle();
  12.      DELAY_microseconds(500);
  13.    }
  14. }
复制代码

经编译,去程序空间的占用情况如图5所示。
图5 编译结果

完成程序下载,的界面提示如图6所示。
图6 完成下载








使用特权

评论回复
5
jinglixixi|  楼主 | 2021-6-20 09:08 | 只看该作者
yangjiaxu 发表于 2021-6-7 17:26
模拟I2C方便移植,只要把IO端口初始化就可用 真不错

使用特权

评论回复
地板
qq894308196| | 2021-6-19 15:54 | 只看该作者
楼主你的晶振是跑多少的

使用特权

评论回复
板凳
jinglixixi|  楼主 | 2021-6-8 07:49 | 只看该作者
yangjiaxu 发表于 2021-6-7 17:26
模拟I2C方便移植,只要把IO端口初始化就可用 真不错

使用特权

评论回复
沙发
guijial511| | 2021-6-7 20:40 | 只看该作者
还是硬件IIC效率高

使用特权

评论回复
楼主
yangjiaxu| | 2021-6-7 17:26 | 只看该作者
模拟I2C方便移植,只要把IO端口初始化就可用 真不错

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

本版热帖

本版活跃用户

优质原创写原创,赢大奖

编辑推荐

  • 1 kk的回忆 得到打赏 ¥600.00
  • 2 名字还没想好 得到打赏 ¥350.00
  • 3 天意无罪 得到打赏 ¥312.00
  • 4 wolfe_yu 得到打赏 ¥210.00
  • 5 呐咯密密 得到打赏 ¥170.00
  • 6 gaoyang9992006 得到打赏 ¥120.00
  • 7 CZF11 得到打赏 ¥100.00
  • 8 年轻的国王 得到打赏 ¥90.00
  • 9 hunteredward 得到打赏 ¥90.00
  • 10 blust5 得到打赏 ¥85.00
在线客服 快速回复 返回顶部 返回列表