51单片机+oled+ds18b20检测并显示温度第一篇:初始化oled显示

"51单片机+oled+ds18b20检测并显示温度"第一篇:初始化oled显示

硬件电路简介

  • 0.96寸oled采用iic接口:scl接P11;sda接P10;vcc接单片机vcc,gnd接单片机gnd
  • ds18b20:dq接P3^6;vcc接单片机vcc,gnd接单片机gnd
  • 单片机内部ledP2^7点亮,显示系统正常运行

IIC

由于oled模块是0.96英寸olediic接口的,所以配置oled显示之前,需要先配置好iic

I2C(Inter-Integrated Circuit)总线开发的两线式串行总线

I2C 的协议定义了通信的起始和停止信号、数据有效性、响应、仲裁、时钟同步和地址广播等环节

  • 数据有效性规定:51单片机+oled+ds18b20检测并显示温度第一篇:初始化oled显示_第1张图片
  • 起始和停止信号:51单片机+oled+ds18b20检测并显示温度第一篇:初始化oled显示_第2张图片
  • 应答相应:51单片机+oled+ds18b20检测并显示温度第一篇:初始化oled显示_第3张图片
  • 应答0或1:51单片机+oled+ds18b20检测并显示温度第一篇:初始化oled显示_第4张图片

根据IIC的时序图以及定义封装三个函数:

本实验用到延时函数:

(延时大约10us)

void Delay10us(void)
{
unsigned char a,b;
for(b=1;b>0;b–)
{
for(a=2;a>0;a–);
}
}

(粗略的延时)

void delay(unsigned char i)
{
while(i–);
}

  1. 起始信号:

void I2cStart(void)
{
SDA=1;
Delay10us();
SCL=1;
Delay10us(); //建立时间是SDA保持时间大于4.7us
SDA=0;
Delay10us(); //保持时间大于4us
SCL=0;
Delay10us();
}

2.终止信号:

void I2cStop(void)
{
SDA=0;
Delay10us();
SCL=1;
Delay10us(); //建立时间大于4.7us
SDA=1;
Delay10us();
}

3.iic发送单字节的函数

unsigned char I2cSendByte(unsigned char dat)
{
unsigned char a=0,b=0; //最大255,一个机器周期为1us,最大延时255us。
for(a=0;a<8;a++) //要发送8位,从最高位开始
{
SDA=dat>>7; //起始信号之后SCL=0,所以可以直接改变SDA信号
dat=dat<<1;
Delay10us();
SCL=1;
Delay10us();//建立时间>4.7us
SCL=0;
Delay10us();//时间大于4us
}
SDA=1;
Delay10us();
SCL=1;
while(SDA) //等待应答,也就是等待从设备把SDA拉低
{
b++;
if(b>200) //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
{
SCL=0;
Delay10us();
return 0;
}
}
SCL=0;
Delay10us();
return 1;
}

到此IIC的相关函数封装完毕~~~

配置oled显示相关函数

51单片机+oled+ds18b20检测并显示温度第一篇:初始化oled显示_第5张图片

根据图片所知:器件从地址为0x78

1.封装写操作相关函数

1.1 写使能函数

void oled_Write_cmd(unsigned char cmd)
{
I2cStart();
I2cSendByte(0x78); //发送写器件地址
I2cSendByte(0x00); //发送要写入内存地址
I2cSendByte(cmd); //写入命令
I2cStop();
}

1.2写字节函数

void oled_Write_data(unsigned char dat)
{
I2cStart();
I2cSendByte(0x78);//发送写器件地址
I2cSendByte(0x40);//发送要写入内存地址
I2cSendByte(dat); //写入数据
I2cStop();
}

2.封装oled初始化函数

当封装好oled的写操作相关函数之后

就可封装oled的初始化函数

2.1 清屏函数

void oled_clear(void)
{ unsigned char i,j;
oled_Write_cmd(0x20);
oled_Write_cmd(0x02);
for(i=0;i<8;i++)
{
oled_Write_cmd(0xb0+i);
oled_Write_cmd(0x00);
oled_Write_cmd(0x10);
for(j=0;j<128;j++)
{
oled_Write_data(0x00);
}
}
}

2.2初始化函数

void oled_initial(void)//oled初始化函数
{
delay(500);
oled_Write_cmd(0xae);//–turn off oled panel 关闭显示
oled_Write_cmd(0x00);//—set low column address设置起始列的低四位 0x0x
oled_Write_cmd(0x10);//—set high column address设置起始列的高四位0x1x
oled_Write_cmd(0x40);//–set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
oled_Write_cmd(0x81);//–set contrast control register设置对比度
oled_Write_cmd(0xff); // Set SEG Output Current Brightness对比度为oxff
oled_Write_cmd(0xa1);//–Set SEG/Column Mapping 0xa0左右反置 0xa1正常
oled_Write_cmd(0xc8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
oled_Write_cmd(0xa6);//–set normal display
oled_Write_cmd(0xa8);//–set multiplex ratio(1 to 64)
oled_Write_cmd(0x3f);//–1/64 duty
oled_Write_cmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
oled_Write_cmd(0x00);//-not offset
oled_Write_cmd(0xd5);//–set display clock divide ratio/oscillator frequency
oled_Write_cmd(0x80);//–set divide ratio, Set Clock as 100 Frames/Sec
oled_Write_cmd(0xd9);//–set pre-charge period
oled_Write_cmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
oled_Write_cmd(0xda);//–set com pins hardware configuration
oled_Write_cmd(0x12);
oled_Write_cmd(0xdb);//–set vcomh
oled_Write_cmd(0x40);//Set VCOM Deselect Level
oled_Write_cmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)设置地址模式
//水平寻址,垂直寻址,页寻址
oled_Write_cmd(0x02);// 地址模式为页寻址
oled_Write_cmd(0x8d);//–set Charge Pump enable/disable
oled_Write_cmd(0x14);//–set(0x10) disable
oled_Write_cmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
oled_Write_cmd(0xa6);// Disable Inverse Display On (0xa6/a7)
oled_Write_cmd(0xaf);//–turn on oled panel开启显示
delay(100);
oled_clear();//清屏
}

直接使用即可

初始化oled完成之后,还需要封装一个在oled显示字符的函数

3.封装oled显示函数

void oled_put_char_16x16(unsigned char x,unsigned char y,unsigned char t)
/设置显示坐标函数,t为0时,字符为8x16
t为1时,字符为16x16
/
{
oled_Write_cmd(0x20);
oled_Write_cmd(0x00);//设置地址模式为水平选址
//set page
oled_Write_cmd(0x22);
oled_Write_cmd(y2);
oled_Write_cmd(0x01+y
2);
//set colum
oled_Write_cmd(0x21);
oled_Write_cmd((0x08+0x08*t)x);
oled_Write_cmd((0x08+0x08
t)x+(0x07+0x08t));
}

其中的x代表在oled水平上的位置一般可取的值为0~16;

其中的y表示在oled垂直上的位置一般可取的值为0~4

设置显示坐标函数,t为0时,字符为8x16,t为1时,字符为16x16

根据取模时候的字符大小,选择不同的值

4.如何在oled上显示字符呢

例:显示一个字符可以这样:

  • 1.首先定义好显示位置x,y,以及字符大小t

    oled_put_char_16x16(0,0,0); //水平为0,垂直为0,字符大小为8*16,大约在左上角

  • 2.向oled中写入字模数据(定义一个字模数组,里面存放16进制数)

    ​ for(i=0;i<16;i++)
    ​ {
    ​ oled_Write_data(character[0][i]);
    ​ }

​ 传送字模数组中第一个字模的16进制数,一共有16个

你可能感兴趣的:(51单片机)