打印
[PIC®/AVR®/dsPIC®产品]

【CuriosityNano测评报告】+I2C接口的OLED屏显示驱动

[复制链接]
88049|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
本帖最后由 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模拟函数为:
void IIC_Start()
{
  CLK_SetHigh();
  DIN_SetHigh();
  DIN_SetLow();
  CLK_SetLow();
}
void IIC_Stop()
{
  CLK_SetHigh();
  DIN_SetLow();
  DIN_SetHigh();
}

void IIC_Wait_Ack()
{
   CLK_SetHigh();
   CLK_SetLow();
}

字节数据发送函数为:
void Write_IIC_Byte(unsigned char IIC_Byte)
{
    chari;
    charm,da;
    da=IIC_Byte;
    CLK_SetLow();
    for(i=0;i<8;i++)                 
    {
      m=da;
      m=m&0x80;
      if(m==0x80)
      {
          DIN_SetHigh();
      }
          else  DIN_SetLow();
          DELAY_milliseconds(1);
          da= da << 1;
          CLK_SetHigh();
          CLK_SetLow();
    }
}

其清屏函数为:
void OLED_Clear(void)  
{  
    uint8_ti,n;                  
    for(i=0;i<8;i++)  
    {  
      OLED_WR_Byte(0xb0+i,OLED_CMD);   
      OLED_WR_Byte(0x00,OLED_CMD);      
      OLED_WR_Byte(0x10,OLED_CMD);      
      for(n=0;n<128;n++) OLED_WR_Byte(0,OLED_DATA);
    }
}

相应的字符显示函数是:
void OLED_ShowChar(uint8_t x,uint8_ty,uint8_t chr,uint8_t Char_Size)
{        
   unsigned char c=0,i=0;      
   c=chr-'';
   if(x>Max_Column-1){x=0;y=y+2;}
   if(Char_Size ==16)
   {
     OLED_Set_Pos(x,y);      
     for(i=0;i<8;i++)
     OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
     OLED_Set_Pos(x,y+1);
     for(i=0;i<8;i++)
       OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
   }
}

对应的OLED屏初始化函数是:
void OLED_Init(void)
{
   CLK_SetHigh();
   DIN_SetHigh();
   DELAY_milliseconds(800);
   OLED_WR_Byte(0xAE,OLED_CMD);//--display off
   OLED_WR_Byte(0x40,OLED_CMD);//--setstart line address  
   OLED_WR_Byte(0xB0,OLED_CMD);//--setpage address
   OLED_WR_Byte(0xC8,OLED_CMD);//Comscan direction
   OLED_WR_Byte(0x81,OLED_CMD);// contract control
   OLED_WR_Byte(0xFF,OLED_CMD);//--128   
   OLED_WR_Byte(0xA1,OLED_CMD);//setsegment remap
   OLED_WR_Byte(0xA6,OLED_CMD);//--normal/ reverse
   OLED_WR_Byte(0xA8,OLED_CMD);//--setmultiplex ratio(1 to 64)
   OLED_WR_Byte(0x1F,OLED_CMD);//--1/32duty         
   OLED_WR_Byte(0xD3,OLED_CMD);//-setdisplay offset
   OLED_WR_Byte(0x00,OLED_CMD);//  
   OLED_WR_Byte(0xD5,OLED_CMD);//setosc division
   OLED_WR_Byte(0xf0,OLED_CMD);//   
   OLED_WR_Byte(0xD9,OLED_CMD);//SetPre-Charge Period
   OLED_WR_Byte(0x22,OLED_CMD);//  
   OLED_WR_Byte(0xDA,OLED_CMD);//setcom pin configuartion
   OLED_WR_Byte(0x02,OLED_CMD);//  
   OLED_WR_Byte(0xDB,OLED_CMD);//setVcomh
   OLED_WR_Byte(0x49,OLED_CMD);//  
   OLED_WR_Byte(0x8D,OLED_CMD);//setcharge pump enable
   OLED_WR_Byte(0x14,OLED_CMD);//  
   OLED_WR_Byte(0xAF,OLED_CMD);//--turnon oled panel
   OLED_Clear();
}

实现显示效果的主程序为:
void main(void)
{
   SYSTEM_Initialize();
   LED_SetLow();
   OLED_Init();
   OLED_Clear();
   OLED_ShowString(0,0,"PIC18F16Q40TEST",16);
   OLED_ShowString(0,2,"OLEDDISPLAY",16);
   while (1)
   {
     LED_Toggle();
     DELAY_microseconds(500);
   }
}

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

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








使用特权

评论回复
20
jinglixixi|  楼主 | 2021-7-23 11:49 | 只看该作者
cemaj 发表于 2021-7-3 16:06
字符的字模是怎么获取 的?

使用PCtoLCD2002即可

使用特权

评论回复
19
jinglixixi|  楼主 | 2021-7-23 11:48 | 只看该作者
youtome 发表于 2021-7-3 16:06
能够显示汉字吗

用字模提取软件构建一个小字库,赔相应的汉字显示程序才行。

使用特权

评论回复
18
jinglixixi|  楼主 | 2021-7-23 11:45 | 只看该作者

使用特权

评论回复
17
weihu| | 2021-7-23 11:01 | 只看该作者
主要是不同主频的片子调整时序

使用特权

评论回复
16
andreilei| | 2021-7-4 10:38 | 只看该作者
一只妄自尊大、自取灭亡的发光LED
视频观看:https://mp.weixin.qq.com/s/9OpBOyK1FrZCG4a3ZSYt2A
视频下载(可商用):https://www.vjshi.com/watch/5312264.html

使用特权

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

使用特权

评论回复
14
cemaj| | 2021-7-3 16:06 | 只看该作者
字符的字模是怎么获取 的?

使用特权

评论回复
13
jimmhu| | 2021-7-3 16:06 | 只看该作者
能够硬件驱动吗

使用特权

评论回复
12
youtome| | 2021-7-3 16:06 | 只看该作者
能够显示汉字吗        

使用特权

评论回复
11
houjiakai| | 2021-7-3 16:05 | 只看该作者
显示效果还不错。           

使用特权

评论回复
10
lzbf| | 2021-7-3 16:05 | 只看该作者
分享一个0.96 oled显示程序吧   

使用特权

评论回复
9
1988020566| | 2021-7-3 16:05 | 只看该作者
iic通ssd1306正常  

使用特权

评论回复
8
mmbs| | 2021-7-3 16:04 | 只看该作者
非常适合 Arduino 项目   

使用特权

评论回复
7
pmp| | 2021-7-3 16:04 | 只看该作者
是硬件iic吗        

使用特权

评论回复
6
i1mcu| | 2021-7-3 16:04 | 只看该作者
主要利用的是I2C通讯  

使用特权

评论回复
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端口初始化就可用 真不错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

455

主题

2756

帖子

38

粉丝