"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 的協定定義了通信的起始和停止信号、資料有效性、響應、仲裁、時鐘同步和位址廣播等環節
- 資料有效性規定:
- 起始和停止信号:
- 應答相應:
- 應答0或1:
根據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–);
}
- 起始信号:
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顯示相關函數
根據圖檔所知:器件從位址為0x781.封裝寫操作相關函數
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上顯示字元呢
例:顯示一個字元可以這樣: 傳送字模數組中第一個字模的16進制數,一共有16個
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]);
}