1.OLED相關(guān)
參見—->51 軟件模擬SPI驅(qū)動OLED
2.硬件SPI
參見—->SPI專題(二)——STM32驅(qū)動FLASH(W25Q64)
3.驅(qū)動程序
驅(qū)動程序參照51單片機進行移植,只不過模擬的SPI換成STM32硬件SPI,不用再寫時序部分的代碼。對于STM32的硬件SPI,我們在驅(qū)動FLASH中已有介紹,這里就不再做介紹。
OLED引腳部分定義:
#ifndef __OLED_H
#define __OLED_H
#include "spi.h"
#include "stm32f10x.h"
#include "stm32f10x_conf.h"
#define Max_Column 128
#define Max_Row 64
#define SIZE 16 //顯示字體選擇
#define RCC_APB2Periph_OLED_PORT RCC_APB2Periph_GPIOA
#define OLED_PORT GPIOA
#define OLED_CS_PIN GPIO_Pin_2
#define OLED_CS_LOW GPIO_ResetBits(GPIOA,GPIO_Pin_2)
#define OLED_CS_HIGH GPIO_SetBits(GPIOA,GPIO_Pin_2)
#define OLED_DC_PIN GPIO_Pin_3
#define OLED_DC_LOW GPIO_ResetBits(GPIOA,GPIO_Pin_3)
#define OLED_DC_HIGH GPIO_SetBits(GPIOA,GPIO_Pin_3)
#define OLED_RST_PIN GPIO_Pin_4
#define OLED_RST_LOW GPIO_ResetBits(GPIOA,GPIO_Pin_4)
#define OLED_RST_HIGH GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define OLED_CLK_PIN GPIO_Pin_5
#define OLED_DATA_PIN GPIO_Pin_7
void SPI_OLED_Init(void);
void OLED_Write_Byte(uint8_t dat);
void OLED_Write_Data(uint8_t dat);
void OLED_Write_Cmd(uint8_t cmd);
void OLED_Set_Pos(u8 x,u8 y);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Display_Clear(void);
void OLED_Display_Onechar(u8 x,u8 y,u8 str);
void OLED_Display_String(u8 x,u8 y,u8 *str);
void OLED_Display_Chinese(u8 x,u8 y,u8 no);
void OLED_Display_Picture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[]);
u32 OLED_Pow(u8 m,u8 n);
void OLED_Display_Num(u8 x,u8 y,u32 num,u8 len,u8 size_num);
void OLED_Init(void);
#endif
連接的時候需要看清楚,一開始我就不小心把SPI的CLK與DO接反了,半天找不到原因,這種問題就太低級了,一定得多細心。
OLED初始化:
void SPI_OLED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_OLED_PORT, ENABLE );
//片選信號初始化
GPIO_InitStructure.GPIO_Pin = OLED_CS_PIN|OLED_DC_PIN|OLED_RST_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //復(fù)用推挽輸出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(OLED_PORT, &GPIO_InitStructure);
GPIO_SetBits(OLED_PORT,OLED_CS_PIN|OLED_DC_PIN|OLED_RST_PIN);
SPI1_Init(); //初始化SPI
SPI1_SetSpeed(SPI_BaudRatePrescaler_16); //設(shè)置為18M時鐘,高速模式
}
OLED寫數(shù)據(jù)實現(xiàn):
//硬件SPI發(fā)送數(shù)據(jù)
void OLED_Write_Byte(uint8_t dat)
{
SPI1_ReadWriteByte(dat);
}
//寫入數(shù)據(jù)
void OLED_Write_Data(uint8_t dat)
{
OLED_CS_LOW;
OLED_DC_HIGH;
OLED_Write_Byte(dat);
}
//寫入命令
void OLED_Write_Cmd(uint8_t cmd)
{
OLED_CS_LOW;
OLED_DC_LOW;
OLED_Write_Byte(cmd);
}
下面就是OLED的具體實現(xiàn),開啟,初始化,寫一個字節(jié),寫字符串等,也是在51MCU的基礎(chǔ)上修改而成。
//Function:設(shè)置顯示坐標(biāo)
//Input:x:橫坐標(biāo);y:縱坐標(biāo)
//Output:無
//Return:無
//Others:無
void OLED_Set_Pos(uint8_t x,uint8_t y)
{
OLED_Write_Cmd(0xb0+y);//列偏移
OLED_Write_Cmd(((x&0xf0)>>4)|0x10);//行高四位地址
OLED_Write_Cmd((x&0x0f)|0X01);//行低四位地址
}
//Function:開啟OLED顯示
//Input:無
//Output:無
//Return:無
//Others:無
void OLED_Display_On(void)
{
OLED_Write_Cmd(0X8D);//設(shè)置DCDC
OLED_Write_Cmd(0X14);//打開DCDC
OLED_Write_Cmd(0XAF);//打開OLED
}
//Function:關(guān)閉OLED顯示
//Input:無
//Output:無
//Return:無
//Others:無
void OLED_Display_Off(void)
{
OLED_Write_Cmd(0X8D);//設(shè)置DCDC
OLED_Write_Cmd(0X10);//關(guān)閉DCDC
OLED_Write_Cmd(0XAE);//關(guān)閉OLED
}
//Function:清屏
//Input:無
//Output:無
//Return:無
//Others:無
void OLED_Display_Clear(void)
{
u8 page,len;
for(page=0;page<8;page++)
{
OLED_Write_Cmd(0xB0+page);//設(shè)置頁地址(0--7)
OLED_Write_Cmd(0X00);//設(shè)置顯示位置—列低地址
OLED_Write_Cmd(0X10); //設(shè)置顯示位置—列高地址
for(len=0;len<128;len++)
OLED_Write_Data(0);//寫入0;屏熄滅
}
}
//Function:在指定位置顯示一個字符,包括部分字符
//x:0~127;y:0~63;size:選擇字體 16/12
//Input:x:橫坐標(biāo);y:縱坐標(biāo);str:顯示的字符
//Output:無
//Return:無
//Others:無
void OLED_Display_Onechar(u8 x,u8 y,u8 str)
{
u8 i=0,ret=0;
//ret = str -32;
ret = str - ' ';//得到偏移后的值,對ASCLL碼進行一個減法.即在二維數(shù)組里找它的位置
if(x>Max_Column-1)
{
x = 0;
y = y + 2;//針對16號的字符
}
if(SIZE == 16 )
{
OLED_Set_Pos(x,y);
//16的字體分成兩部分寫入
for(i=0;i<8;i++)
OLED_Write_Data(F8X16[ret*16+i]);
OLED_Set_Pos(x,y+1);
for(i=0;i<8;i++)
OLED_Write_Data(F8X16[ret*16+i+8]);
}
else{
OLED_Set_Pos(x,y+1);
for(i=0;i<6;i++)
OLED_Write_Data(F6x8[ret][i]);
}
}
//Function:顯示字符串
//Input:x:橫坐標(biāo);y:縱坐標(biāo);str:顯示的字符串
//Output:無
//Return:無
//Others:無
void OLED_Display_String(u8 x,u8 y,u8 *str)
{
u8 i=0;
while(str[i]!='\0')
{
OLED_Display_Onechar(x,y,str[i]);
x += 8;
if(x>120)
{
x = 0;
y += 2;
}
i++;
}
}
//Function:顯示中文
//Input:x:橫坐標(biāo);y:縱坐標(biāo);no:顯示的字的序號
//Output:無
//Return:無
//Others:無
void OLED_Display_Chinese(u8 x,u8 y,u8 no)
{
u8 ch,addr=0;
OLED_Set_Pos(x,y);
for(ch=0;ch<16;ch++)//數(shù)組行列尋址
{
OLED_Write_Data(TEST[2*no][ch]);//漢字是2個字節(jié)
addr += 1;
}
OLED_Set_Pos(x,y+1);
for(ch=0;ch<16;ch++)
{
OLED_Write_Data(TEST[2*no+1][ch]);
addr += 1;
}
}
//Function:顯示圖片
//Input:x0,x1:橫坐標(biāo);y0,y1:縱坐標(biāo);BMP:顯示的圖片
//注意:y1<8,頁尋址模式
//Output:無
//Return:無
//Others:無
void OLED_Display_Picture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[])
{
u8 x,y;
u32 i=0;
if(y1%8==0)
y = y1 / 8;
else
y = y1 /8 + 1;
for(y=y0;y { OLED_Set_Pos(x0,y); for(x=x0;x { OLED_Write_Data(BMP[i++]); } } } //計算m的n次方 u32 OLED_Pow(u8 m,u8 n) { u32 ret = 1; while(n--) ret *= m; return ret; } //Function:顯示數(shù)字 //Input:x:橫坐標(biāo);1:縱坐標(biāo);num:顯示的數(shù)字:len:數(shù)字長度;size_num:數(shù)字字體 //Output:無 //Return:無 //Others:無 void OLED_Display_Num(u8 x,u8 y,u32 num,u8 len,u8 size_num) { u8 t,temp; u8 enshow = 0; for(t=0;t { temp = (num/OLED_Pow(10,len-t-1))%10;//把顯示的數(shù)字一位一位取出來 if(enshow==0&&t<(len-1)) { if(temp==0) { OLED_Display_Onechar(x+(size_num/2)*t,y,' '); continue; } else enshow = 1; } OLED_Display_Onechar(x+(size_num/2)*t,y,temp+'0'); } } //初始化SSD1306 //命令設(shè)置與開啟函數(shù)作用重疊...... void OLED_Init(void) { SPI_OLED_Init(); OLED_RST_HIGH; delay_ms(200); OLED_RST_LOW; delay_ms(200); OLED_RST_HIGH; OLED_Write_Cmd(0xAE);//關(guān)閉OLED OLED_Write_Cmd(0x00);//設(shè)置列低位地址 OLED_Write_Cmd(0x10);//設(shè)置列高位地址 OLED_Write_Cmd(0x40);//設(shè)置起始行地址及映射RAM顯示起始行 (0x00~0x3F) OLED_Write_Cmd(0x81);//對比度設(shè)置 OLED_Write_Cmd(0xCF); // Set SEG Output Current Brightness 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);//設(shè)置顯示方式;bit0:1,反相顯示;0,正常顯示 OLED_Write_Cmd(0xA8);//設(shè)置驅(qū)動路數(shù)(1 to 64) OLED_Write_Cmd(0x3f);//--1/64 duty OLED_Write_Cmd(0xD3);//-設(shè)置顯示偏移(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);//設(shè)置頁地址模式(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);//禁用顯示開啟;bit0:1,開啟;0,關(guān)閉;(白屏/黑屏)(0xa4/0xa5) OLED_Write_Cmd(0xA6);// 不使用反向顯示 (0xa6/a7) OLED_Write_Cmd(0xAF);//打開顯示 OLED_Write_Cmd(0xAF); /*display ON*/ OLED_Display_Clear(); OLED_Set_Pos(0,0); } 實現(xiàn)效果:
上一篇:STM32F4使用硬件SPI驅(qū)動ADS8322
下一篇:STM8L051之低功耗停機配置問題
推薦閱讀
史海拾趣
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- 意法半導(dǎo)體推出先進的 1600 V IGBT,面向高性價比節(jié)能家電市場
- EDPF-NT+分散控制系統(tǒng)網(wǎng)絡(luò)防護解決方案
- 基于PLC控制的易驅(qū)變頻器在布袋除塵器上的應(yīng)用
- 如何利用伺服自動化實現(xiàn)成本降低和產(chǎn)能最大化?
- 壓力傳感器有哪些抗干擾措施?
- 破局!補盲dToF固態(tài)激光雷達輪番“出手”,禾賽FT120也要靠邊
- 利用正壓送風(fēng)壓力傳感器自動控制火災(zāi)風(fēng)口壓力
- 多個傳感器間相互位置關(guān)系校準(zhǔn)方法
- 樓宇自控BA系統(tǒng)傳感器有哪些?
- 常見壓力傳感器工業(yè)原理匯總
- 暢游安富利人工智能云會展,挑戰(zhàn)60天打卡學(xué)習(xí)養(yǎng)成記!沖擊華為Mate40 Pro、Apple iPad Air等豪禮啦!
- 大聯(lián)大世平集團有獎直播:最新功能安全牽引逆變器方案:助力汽車提升續(xù)航與節(jié)省成本!預(yù)約有禮
- 泰科電子邀您云逛展——2023中國國際工業(yè)博覽會
- 下載泰克高速接口標(biāo)準(zhǔn)電子書,參與翻蓋有禮,驚喜多多!
- 下載《ADI 任意波形發(fā)生器方案》搶樓有禮啦!
- 微信直播慕尼黑東芝大展臺,好禮多多等你來
- 泰科電子物聯(lián)網(wǎng)應(yīng)用資料下載中心 限時免費開放!
- 最后一天!Beetle ESP32-C3免費測評,趕緊上車