天天看點

51單片機+oled+ds18b20檢測并顯示溫度第一篇:初始化oled顯示

"51單片機+oled+ds18b20檢測并顯示溫度"第一篇:初始化oled顯示

硬體電路簡介

  • 0.96寸oled采用iic接口:scl接 P1^ 1,sda接P1^0;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顯示
  • 起始和停止信号:
    51單片機+oled+ds18b20檢測并顯示溫度第一篇:初始化oled顯示
  • 應答相應:
    51單片機+oled+ds18b20檢測并顯示溫度第一篇:初始化oled顯示
  • 應答0或1:
    51單片機+oled+ds18b20檢測并顯示溫度第一篇:初始化oled顯示

根據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顯示
根據圖檔所知:器件從位址為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+y2);

//set colum

oled_Write_cmd(0x21);

oled_Write_cmd((0x08+0x08*t)*x);

oled_Write_cmd((0x08+0x08*t)*x+(0x07+0x08*t));

}

其中的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個

繼續閱讀