stm32 IIC oled 介紹
阿新 • • 發佈:2018-11-08
IIC 簡介
IIC oled 介紹找另一篇文章,這裡主要有IIC,和如何編寫oled.c程式碼
IIC(Inter-Integrated Circuit)匯流排是一種由 PHILIPS 公司開發的兩線式 匯流排,
用於連線微控制器及其外圍裝置。它是由資料線 SDA 和時鐘 SCL 構成的序列匯流排, 可傳送和接收資料。
在 CPU 與被控 IC 之間、IC 與 IC 之間進行雙向傳送,高速 IIC 匯流排一般可達 400kbps 以上。
I2C 匯流排在傳送資料過程中共有三種類型訊號, 它們分別是:開始訊號、結束訊號和應答訊號。
開始訊號:SCL 為高電平時,SDA 由高電平向低電平跳變,開始傳送資料。
結束訊號:SCL 為高電平時,SDA 由低電平向高電平跳變,結束傳送資料。
應答訊號:接收資料的 IC 在接收到 8bit 資料後,向傳送資料的 IC 發出特定 的低電平脈
衝,表示已收到資料。CPU 向受控單元發出一個訊號後,等待受控單元發出一個應答訊號,CPU 接收到應答訊號後,根據實際情況作出是否繼續傳遞訊號的判斷。若未收到應答訊號,由判斷為 受控單元出現故障。
這些訊號中,起始訊號是必需的,結束訊號和應答訊號,都可以不要
軟體設計
- IIC設定
void I2C_Configuration(void) { I2C_InitTypeDef I2C_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); /*STM32F103C8T6晶片的硬體I2C: PB6 -- SCL; PB7 -- SDA */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//I2C必須開漏輸出 GPIO_Init(GPIOB, &GPIO_InitStructure); I2C_DeInit(I2C1);//使用I2C1 I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x30;//主機的I2C地址,隨便寫的 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 400000;//400K I2C_Cmd(I2C1, ENABLE); I2C_Init(I2C1, &I2C_InitStructure); }
- IIC傳送資料
void I2C_WriteByte(uint8_t addr,uint8_t data) { while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C1, ENABLE);//開啟I2C1 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/ I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);//器件地址 -- 預設0x78 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, addr);//暫存器地址 while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1, data);//傳送資料 while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C1, ENABLE);//關閉I2C1匯流排 }
oled的寫命令和資料
void WriteCmd(unsigned char I2C_Command)//寫命令
{
I2C_WriteByte(0x00, I2C_Command);
}
void WriteDat(unsigned char I2C_Data)//寫資料
{
I2C_WriteByte(0x40, I2C_Data);
}
OLEd初始化
void OLED_Init(void)
{
delay_ms(100); //這裡的延時很重要
WriteCmd(0xAE); //開顯示
WriteCmd(0x20); //設定記憶體定址模式
WriteCmd(0x10); //00,水平定址模式;01,垂直定址模式;10,頁面定址模式(重置);11,無效
WriteCmd(0xb0); //為頁面定址模式設定頁面開始地址,0-7
WriteCmd(0xc8); //設定COM輸出掃描方向
WriteCmd(0x00); //---設定低列地址
WriteCmd(0x10); //---設定高列地址
WriteCmd(0x40); //--設定起始行地址
WriteCmd(0x81); //--set contrast control register
WriteCmd(0xff); //亮度調節 0x00~0xff
WriteCmd(0xa1); //--設定段重新對映0到127
WriteCmd(0xa6); //--設定正常顯示
WriteCmd(0xa8); //--設定複用比(1 ~ 64)
WriteCmd(0x3F); //
WriteCmd(0xa4); //0xa4,輸出遵循RAM內容;0xa5,Output忽略RAM內容
WriteCmd(0xd3); //-設定顯示抵消
WriteCmd(0x00); //-not offset
WriteCmd(0xd5); //--設定顯示時鐘分頻/振盪器頻率
WriteCmd(0xf0); //--設定分率
WriteCmd(0xd9); //--設定pre-charge時期
WriteCmd(0x22); //
WriteCmd(0xda); //--設定com大頭針硬體配置
WriteCmd(0x12);
WriteCmd(0xdb); //--設定vcomh
WriteCmd(0x20); //0x20,0.77xVcc
WriteCmd(0x8d); //--設定DC-DC
WriteCmd(0x14); //
WriteCmd(0xaf); //--開啟oled面板
}
設定起始點座標
void OLED_SetPos(unsigned char x, unsigned char y) //設定起始點座標
{
WriteCmd(0xb0+y);
WriteCmd(((x&0xf0)>>4)|0x10);
WriteCmd((x&0x0f)|0x01);
}
全屏填充
void OLED_Fill(unsigned char fill_Data)//全屏填充
{
unsigned char m,n;
for(m=0;m<8;m++)
{
WriteCmd(0xb0+m); //page0-page1
WriteCmd(0x00); //low column start address
WriteCmd(0x10); //high column start address
for(n=0;n<128;n++)
{
WriteDat(fill_Data);
}
}
}
清屏
void OLED_CLS(void)//清屏
{
OLED_Fill(0x00);
}
將OLED從休眠中喚醒
//--------------------------------------------------------------
void OLED_ON(void)
{
WriteCmd(0X8D); //設定電荷泵
WriteCmd(0X14); //開啟電荷泵
WriteCmd(0XAF); //OLED喚醒
}
讓OLED休眠 – 休眠模式下,OLED功耗不到10uA
//--------------------------------------------------------------
void OLED_OFF(void)
{
WriteCmd(0X8D); //設定電荷泵
WriteCmd(0X10); //關閉電荷泵
WriteCmd(0XAE); //OLED休眠
}
顯示codetab.h中的ASCII字元,有68和816可選擇
/
/--------------------------------------------------------------
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{
unsigned char c = 0,i = 0,j = 0;
switch(TextSize)
{
case 1:
{
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 126)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<6;i++)
WriteDat(F6x8[c][i]);
x += 6;
j++;
}
}break;
case 2:
{
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 120)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i]);
OLED_SetPos(x,y+1);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i+8]);
x += 8;
j++;
}
}break;
}
}
//--------------------------------------------------------------
// Prototype : void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
// Calls :
// Parameters : x,y -- 起始點座標(x:0~127, y:0~7); N:漢字在codetab.h中的索引
// Description : 顯示codetab.h中的漢字,16*16點陣
//--------------------------------------------------------------
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;
unsigned int adder=32*N;
OLED_SetPos(x , y);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16[adder]);
adder += 1;
}
OLED_SetPos(x,y + 1);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16[adder]);
adder += 1;
}
}
//--------------------------------------------------------------
// Prototype : void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
// Calls :
// Parameters : x0,y0 -- 起始點座標(x0:0~127, y0:0~7); x1,y1 -- 起點對角線(結束點)的座標(x1:1~128,y1:1~8)
// Description : 顯示BMP點陣圖
//--------------------------------------------------------------
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0)
y = y1/8;
else
y = y1/8 + 1;
for(y=y0;y<y1;y++)
{
OLED_SetPos(x0,y);
for(x=x0;x<x1;x++)
{
WriteDat(BMP[j++]);
}
}
}