最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

I2C協(xié)議的超簡(jiǎn)單解讀,小學(xué)生都能學(xué)得會(huì)

2023-06-19 11:13 作者:熱愛(ài)科學(xué)的百草園主人  | 我要投稿

I2C是由兩根線組成的一種串行通信線路,如何用兩根線約定傳輸信號(hào)呢?

I2C兩根線分別為SCL時(shí)鐘同步線,SDA數(shù)據(jù)傳輸線,兩根線通過(guò)上拉電阻拉高電勢(shì),這個(gè)拉高有個(gè)好處就是可以釋放總線。這些先不說(shuō),先講如何標(biāo)記不同的信號(hào):

規(guī)定SCL為高的時(shí)候切換SDA跳變記作開(kāi)始信號(hào)與結(jié)束信號(hào);

規(guī)定SCL為低的時(shí)候切換SDA跳變記作數(shù)據(jù)傳輸信號(hào)。

記SDA釋放后拉低信號(hào)為響應(yīng)信號(hào)(應(yīng)答ACK),不拉低信號(hào)為非響應(yīng)信號(hào)(非應(yīng)答NACK)。

于是乎我們就可以用兩根線在SCL不同狀態(tài)下的跳變傳輸信號(hào)了。

開(kāi)始信號(hào):SCL為高電平時(shí)候SDA產(chǎn)生一個(gè)下降沿

????SCL_H

????????SDA_H

????????SDA_L

結(jié)束信號(hào):SCL為高電平時(shí)候產(chǎn)生一個(gè)上升沿

? ? SCL_H

????? ? SDA_L

????? ? SDA_H

數(shù)據(jù)傳輸信號(hào):SCL低電平時(shí)候切換SDA到要發(fā)送的電平,然后拉高準(zhǔn)備下一位發(fā)送。

????傳輸一個(gè)0

????SCL_L

????????SDA_L

? ? SCL_H

? ? 傳輸一個(gè)1

? ? SCL_L

????????SDA_H

? ? SCL_H

應(yīng)答與非應(yīng)答:SCL拉低釋放SDA,SCL再拉高后讀取SDA的狀態(tài),如果為高則非應(yīng)答,如果為低則為應(yīng)答。最后拉低SCL確保在停止信號(hào)前保證為時(shí)鐘低電平。

SCL_L

? ? ? ? SDA_H

SCL_H

讀取SDA狀態(tài)判斷是否有應(yīng)答

SCL_L

以上所有的信號(hào)都解讀完成了,你看懂了嗎?

接下來(lái)就是利用上述的I2C基礎(chǔ)信號(hào)組合成能發(fā)送字節(jié)的信號(hào)。

#include<REG52.h>



sbit OLED_SCL=P2^0;//時(shí)鐘 D0(SCLK)時(shí)鐘

sbit OLED_SDIN=P2^1;//D1(MOSI) 數(shù)據(jù)



#define IO_SCL_SET_L() OLED_SCL=0

#define IO_SCL_SET_H() OLED_SCL=1


#define IO_SDA_SET_H() OLED_SDIN=1

#define IO_SDA_SET_L() OLED_SDIN=0


#define Get_IO_SDA() OLED_SDIN


#define OLED_CMD? 0 //寫(xiě)命令

#define OLED_DATA 1 //寫(xiě)數(shù)據(jù)


/*

I2C Start

起始信號(hào):時(shí)鐘信號(hào)在高電平狀態(tài)時(shí)候,數(shù)據(jù)線產(chǎn)生一個(gè)下降沿表示開(kāi)始信號(hào)

*/

void I2C_Start()

{

IO_SCL_SET_H();


IO_SDA_SET_H();

IO_SDA_SET_L();

}


/*

I2C Stop

停止信號(hào):時(shí)鐘信號(hào)在高電平狀態(tài)時(shí)候,數(shù)據(jù)線產(chǎn)生一個(gè)上升沿表示停止

*/

void I2C_Stop()

{

IO_SCL_SET_H();


IO_SDA_SET_L();

IO_SDA_SET_H();

}


/*

I2C ACK/NACK

應(yīng)答信號(hào):第九個(gè)時(shí)鐘周期的時(shí)鐘高電平時(shí)候讀取SDA數(shù)據(jù),如果SDA此時(shí)為0,則表示應(yīng)答,如果為1則表示非應(yīng)答。

*/

void I2C_ACK()

{

IO_SDA_SET_H();


IO_SCL_SET_H();

if(Get_IO_SDA()==0)

IO_SCL_SET_L();

else

while(Get_IO_SDA()==1);

IO_SCL_SET_L();

}


/*

I2C 上發(fā)送一個(gè)字節(jié)數(shù)據(jù)

發(fā)送字節(jié):發(fā)送字節(jié)是時(shí)鐘信號(hào)的低電平時(shí)候修改數(shù)據(jù),發(fā)送完要讓時(shí)鐘總線保持在低電平。

*/

void Write_I2C_Byte(unsigned char I2C_Byte)

{

unsigned char i;


for(i=0;i<8;i++)

{

IO_SCL_SET_L();


if((I2C_Byte<<i)&0x80)

IO_SDA_SET_H();

else

IO_SDA_SET_L();


IO_SCL_SET_H();

}

IO_SCL_SET_L();

}

/*

add:7位地址;

rwbit:讀寫(xiě)位,1表示讀,0表示寫(xiě)

dat:數(shù)據(jù)字節(jié)

命令或數(shù)據(jù):1表示發(fā)送的字節(jié)是數(shù)據(jù),0表示發(fā)送的字節(jié)是命令


*/

void OLED_WR_Byte(unsigned char dat,unsigned char cmd)

{

I2C_Start();

Write_I2C_Byte(0x78);

I2C_ACK();

if(cmd)

Write_I2C_Byte(0x40);

else

Write_I2C_Byte(0x00);

I2C_ACK();

Write_I2C_Byte(dat);

I2C_ACK();

I2C_Stop();

}


//坐標(biāo)設(shè)置

void OLED_Set_Pos(unsigned char x, unsigned char y)?

{

OLED_WR_Byte(0xb0+y,OLED_CMD);

OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);

OLED_WR_Byte((x&0x0f),OLED_CMD);

}?


//開(kāi)啟OLED顯示? ??

void OLED_Display_On(void)

{

OLED_WR_Byte(0X8D,OLED_CMD);? //SET DCDC命令

OLED_WR_Byte(0X14,OLED_CMD);? //DCDC ON

OLED_WR_Byte(0XAF,OLED_CMD);? //DISPLAY ON

}


//關(guān)閉OLED顯示? ? ?

void OLED_Display_Off(void)

{

OLED_WR_Byte(0X8D,OLED_CMD);? //SET DCDC命令

OLED_WR_Byte(0X10,OLED_CMD);? //DCDC OFF

OLED_WR_Byte(0XAE,OLED_CMD);? //DISPLAY OFF

}


//清屏函數(shù),清完屏,整個(gè)屏幕是黑色的!和沒(méi)點(diǎn)亮一樣!!! ??

void OLED_Clear(void)??

{??

unsigned char i,n; ? ??

for(i=0;i<4;i++)??

{??

OLED_WR_Byte (0xb0+i,OLED_CMD);? ? //設(shè)置頁(yè)地址(0~7)

OLED_WR_Byte (0x00,OLED_CMD);? ? ? //設(shè)置顯示位置—列低地址

OLED_WR_Byte (0x10,OLED_CMD);? ? ? //設(shè)置顯示位置—列高地址? ?

for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);?

} //更新顯示

}


//反顯函數(shù)

void OLED_ColorTurn(unsigned char i)

{

if(i==0)

{

OLED_WR_Byte(0xA6,OLED_CMD);//正常顯示

}

if(i==1)

{

OLED_WR_Byte(0xA7,OLED_CMD);//反色顯示

}

}


//屏幕旋轉(zhuǎn)180度

void OLED_DisplayTurn(unsigned char i)

{

if(i==0)

{

OLED_WR_Byte(0xC8,OLED_CMD);//正常顯示

OLED_WR_Byte(0xA1,OLED_CMD);

}

if(i==1)

{

OLED_WR_Byte(0xC0,OLED_CMD);//反轉(zhuǎn)顯示

OLED_WR_Byte(0xA0,OLED_CMD);

}

}



//初始化 ? ??

void OLED_Init(void)

{


OLED_WR_Byte(0xAE,OLED_CMD); /*display off*/

OLED_WR_Byte(0x00,OLED_CMD); /*set lower column address*/?

OLED_WR_Byte(0x10,OLED_CMD); /*set higher column address*/

OLED_WR_Byte(0x00,OLED_CMD); /*set display start line*/?

OLED_WR_Byte(0xB0,OLED_CMD); /*set page address*/?

OLED_WR_Byte(0x81,OLED_CMD); /*contract control*/?

OLED_WR_Byte(0xff,OLED_CMD); /*128*/?

OLED_WR_Byte(0xA1,OLED_CMD); /*set segment remap*/?

OLED_WR_Byte(0xA6,OLED_CMD); /*normal / reverse*/?

OLED_WR_Byte(0xA8,OLED_CMD); /*multiplex ratio*/?

OLED_WR_Byte(0x1F,OLED_CMD); /*duty = 1/32*/?

OLED_WR_Byte(0xC8,OLED_CMD); /*Com scan direction*/?

OLED_WR_Byte(0xD3,OLED_CMD); /*set display offset*/?

OLED_WR_Byte(0x00,OLED_CMD);?

OLED_WR_Byte(0xD5,OLED_CMD); /*set osc division*/?

OLED_WR_Byte(0x80,OLED_CMD);?

OLED_WR_Byte(0xD9,OLED_CMD); /*set pre-charge period*/?

OLED_WR_Byte(0x1f,OLED_CMD);?

OLED_WR_Byte(0xDA,OLED_CMD); /*set COM pins*/?

OLED_WR_Byte(0x00,OLED_CMD);?

OLED_WR_Byte(0xdb,OLED_CMD); /*set vcomh*/?

OLED_WR_Byte(0x40,OLED_CMD);?

OLED_WR_Byte(0x8d,OLED_CMD); /*set charge pump enable*/?

OLED_WR_Byte(0x14,OLED_CMD);

OLED_Clear();

OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/?

}


unsigned char code num[][16]={

{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00},/*"0",0*/

{0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00},/*"1",1*/

{0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},/*"2",2*/

{0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00},/*"3",3*/

{0x00,0x00,0x80,0x40,0x30,0xF8,0x00,0x00,0x00,0x06,0x05,0x24,0x24,0x3F,0x24,0x24},/*"4",4*/

{0x00,0xF8,0x88,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x20,0x20,0x20,0x11,0x0E,0x00},/*"5",5*/

{0x00,0xE0,0x10,0x88,0x88,0x90,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00},/*"6",6*/

{0x00,0x18,0x08,0x08,0x88,0x68,0x18,0x00,0x00,0x00,0x00,0x3E,0x01,0x00,0x00,0x00},/*"7",7*/

{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},/*"8",8*/

{0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x01,0x12,0x22,0x22,0x11,0x0F,0x00},/*"9",9*/

};




/*

numb:顯示的數(shù)字,0-9

x:坐標(biāo):0-127

y:坐標(biāo):0-3

flag:0為正顯示,1為反顯示

*/

void numberx(unsigned char numb, unsigned char x, unsigned char y, unsigned char flag) {

? ? unsigned char i;

? ? for (i = 0; i < 16; i++) {

? ? ? ? if (i == 0 || i == 15) {

? ? ? ? ? ? OLED_Set_Pos(x + i, y + 0);

? ? ? ? ? ? OLED_WR_Byte(flag ? ~0xFF : 0xFF, OLED_DATA);

? ? ? ? ? ? OLED_Set_Pos(x + i, y + 1);

? ? ? ? ? ? OLED_WR_Byte(flag ? ~0xFF : 0xFF, OLED_DATA);

? ? ? ? } else if ((i > 0 && i < 4) || (i > 12 && i < 16)) {

? ? ? ? ? ? OLED_Set_Pos(x + i, y + 0);

? ? ? ? ? ? OLED_WR_Byte(flag ? ~0x01 : 0x01, OLED_DATA);

? ? ? ? ? ? OLED_Set_Pos(x + i, y + 1);

? ? ? ? ? ? OLED_WR_Byte(flag ? ~0x80 : 0x80, OLED_DATA);

? ? ? ? } else {

? ? ? ? ? ? OLED_Set_Pos(x + i, y + 0);

? ? ? ? ? ? OLED_WR_Byte(flag ? ~(0x01 | num[numb][i - 4]) : (0x01 | num[numb][i - 4]), OLED_DATA);

? ? ? ? ? ? OLED_Set_Pos(x + i, y + 1);

? ? ? ? ? ? OLED_WR_Byte(flag ? ~(0x80 | num[numb][i + 4]) : (0x80 | num[numb][i + 4]), OLED_DATA);

? ? ? ? }

? ? }

}



I2C協(xié)議的超簡(jiǎn)單解讀,小學(xué)生都能學(xué)得會(huì)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
榕江县| 利川市| 桂阳县| 句容市| 禹城市| 苏尼特右旗| 修文县| 娱乐| 大城县| 陈巴尔虎旗| 金华市| 闸北区| 新巴尔虎右旗| 偏关县| 精河县| 马尔康县| 兴山县| 绥棱县| 涞源县| 萨嘎县| 宜都市| 大姚县| 瑞金市| 馆陶县| 台湾省| 舞钢市| 罗城| 三穗县| 金湖县| 朝阳县| 瓮安县| 南汇区| 洪雅县| 顺平县| 朝阳区| 临湘市| 沙雅县| 卓资县| 株洲市| 拉孜县| 徐水县|