本帖最后由 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 完成下载
|