天天看點

I2C接口協定之HT16C22驅動

        之前工作中使用了一些常見的接口協定,為了防止遺忘和加深記憶,後續會陸陸續續講解分析各種常見的接口協定(如: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初始化過程的波形曲線:

I2C接口協定之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。