之前工作中使用了一些常見的接口協定,為了防止遺忘和加深記憶,後續會陸陸續續講解分析各種常見的接口協定(如:I2C、SPI、USART等)。由于最近項目需求,需要使用HT16C22液晶驅動晶片,而這款晶片和MCU通信使用的是I2C接口,是以本文首先以HT16C22入手,分析I2C接口協定。
對于初學者你是不是也有這種疑惑,這些常見接口協定看那些協定的資料總是雲裡霧裡,不知所雲,看了就忘。本人剛學也有這種困惑,為了解決這種現狀你必須得實際動手去實踐,在實踐中摸索分析才能真正了解。
一、何為I2C接口協定
在這裡我不詳細解釋何為I2C,大家可以去參考其他人寫的部落格有具體分析I2C。這裡我們以實際應用中分析I2C是如何實作在不同IC之間通訊。
你可能需要的兩個最基本的概念:
起始信号:當 SCL 線是高電平時 SDA 線從高電平向低電平切換。
停止信号:當 SCL 線是高電平時 SDA 線由低電平向高電平切換。
二、I2C驅動常用的幾個基本函數
2.1 起始信号代碼
//産生IIC起始信号
void IIC_Start(void)
{
SDA_OUT();
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;
delay_us(4);
IIC_SCL=0; //鉗住I2C總線,準備發送或接收資料
}
2.2 停止信号代碼
//産生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();
IIC_SCL=0;
IIC_SDA=0;
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;
delay_us(4);
}
2.3 CPU産生一個ACK信号
//等待應答信号到來
//傳回值:1,接收應答失敗
// 0,接收應答成功
uint8_t IIC_Wait_Ack(void)
{
uint8_t ucErrTime=0;
SDA_IN(); //SDA設定為輸入
IIC_SDA=1;
delay_us(1);
IIC_SCL=1;
delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//時鐘輸出0
return 0;
}
2.4 CPU向I2C總線裝置發送一個位元組(8bit)資料
//IIC發送一個位元組
//傳回從機有無應答
//1,有應答
//0,無應答
void IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
SDA_OUT();
IIC_SCL=0;//拉低時鐘開始資料傳輸
for(t=0;t<8;t++)
{
if((txd&0x80)>>7)
{
IIC_SDA=1;
}
else IIC_SDA=0;
txd<<=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
除了以上幾個基本函數外,還有幾個常用函數在這裡由于不參與分析就不列舉了。 在以上幾個函數的基礎上,我們再來具體分析HT16C22的初始化過程。
三、HT16C22初始化過程分析
首先用示波器抓取HT16C22初始化過程的波形曲線:
HT16C22初始化過程波形曲線
//HT16C22初始化
void HT16C22_Init(void)
{
IIC_Start();
IIC_Send_Byte(HT16C22_Address);
IIC_Wait_Ack();
IIC_Send_Byte(0x8C);// DrvModeSet 0x8C 80Hz,turn on sys and LCD bias,1/3 bias
IIC_Wait_Ack();
IIC_Send_Byte(0xC0);// Blink 0xC0 //關閉閃爍
IIC_Wait_Ack();
IIC_Stop();
}
我們可以把上面這個過程拆分為10個階段 。
① 起始空閑階段。
這個階段中SCL和SDA都處于高電平;
②起始信号(MCU開始往HT16C22發送資料)
這個階段中,SCL保持高電平不變,而SDA由高電平跳變至低電平;
③發送HT16C22的器件位址和I2C寫資料指令
在這個階段中,SCL每次跳變至高電平時,會将SDA資料發送給HT16C22。從圖中可以看出發給HT16C22的資料為01111110。其中第一位至七位為HT16C22器件位址(0x7E),第一位為0表示:寫資料指令。
④等待傳回Ack
這個階段中,MCU等待HT16C22傳回低電平表示資料接收成功。
⑤發送0x8C
這個階段将資料0x8C發送給HT16C22,至于為什麼是0x8C感興趣可以翻看HT16C22手冊。
⑥等待傳回Ack
同第④
⑦發送0xC0
這個階段将資料0xC0發送給HT16C22,至于為什麼是0xC0感興趣可以翻看HT16C22手冊。
⑧等待傳回Ack
同第④
⑨結束信号
這個階段中,SCL保持高電平不變,而SDA由低電平跳變至高電平;
⑩空閑階段
此階段同起始空閑階段;
自此,HT16C22初始化資料成功被MCU發送給HT16C22。