2014年2月6日 星期四

LPD8806 晶片的使用說明以及通訊格式的解釋

賣場中各 LED 驅動晶片簡介與比較,請參考部落格網頁中的說明:

LPD8806晶片 ,可至露天賣場訂購:

LPD8806 是一顆兩線式通訊控制六通道帶 256 級 PWM 可程式編輯恒流 LED 驅動晶片,且經由硬體接腳的設置,可控制輸出級性 ( OMODE ) 與設定是否讓通道同步輸出 ( PMODE ) ...等,其他晶片特色有:

  • 兩線控制模式,移位時鐘可達 20MHz
  • 獨特的數據時鐘再生機制,超強信驅動能力,支持串接長度超過 2000 點
  • 內建 1.2MHz 震盪電路,支持 FREE-RUN 模式,方便於控制器程式編輯設計 ( 更新頻率大於 4000 Hz )
  • 每個通道內置獨立的 256 PWM 灰度控制電路,通過程式編輯可實現 1024 級灰度效果
  • 輸出級性可選,可支持外接驅動模式或作為大功率 LED 驅動電路的信號源
  • 工業級設計,輸入信號經施密特處理,抗干擾性能極強。

應用範圍:
  • LED 裝飾照明系統
  • PWM 信號產生器
  • LCD 背光驅動器
LED 驅動晶片的簡介與比較可參考網頁最上面所提供連結網頁。

LPD8806 ( 應該是說 LED 驅動晶片 ) 適合作為 PWM 信號產生器,因為穩定的 PWM 輸出才會讓 LED 燈維持穩定,在控制 LED 亮度以及 RGB 調色時才能呈現讓人滿意的性能表現。且使用專用晶片可降低微處理器的負荷和程式撰寫的複雜性。

此顆晶片可使用簡單的線路做驅動也可以使用外接驅動模式,在資料手冊上提供了多個電路可供參考,由於內部恆流驅動模式的最大輸出電流 IOMAX = 20mA 所以就直接拿來做實驗線路,因為此電路不需加任何電阻就可以直接驅動單顆 LED。

電路如下所示:

樹莓派控制 LPD8806 - 內部恒流驅動 LED
樹莓派控制 LPD8806 - 內部恒流驅動 LED

上圖的線路很容易就可以實現 LED 調光和混色的要求。因為手邊沒有共陽極的 RGB LED,所以採用三顆紅、綠和藍色 LED 來取代;在晶片的電源輸入處,建議接一個退耦電容提高雜訊抵抗能力和穩定電壓;VIN 是額外提供的 5V 電源,但建議不要用直接用樹莓派上的 5V 來接;PMODE 和 OMODE 浮接就可以

LPD8806 內部恆流驅動 LED 亮度實計接線測試圖
上面兩張照片就是使用樹莓派傳送控制碼給 LPD8806 晶片後,LED 呈現的不同亮度樣子。麵包板上的兩顆晶片都是 LPD8806,共有兩組電路:作為 LED 調光測試用 ( 下方 )與馬達調速用 ( 上方 )。網頁說明的是下方的 LED 驅動電路,馬達驅動線路會在另一個網頁中用到,但是驅動方式都是大同小異的。

剩下的工作就是測試程式的撰寫。


LPD8806 LED 調光測試:

這個部份對於 eZ430 運動手錶控制的樹莓派小車 很重要 ( 因為小車馬達驅動的 PWM 信號產生就是使用這顆晶片,不使用其他晶片是因為這顆先拿到,所以其他 LED 驅動晶片也可以用也可以 ) ,所以必須知道所傳送出去的數值 ( PWM 的 Duty Cycle ( 工作週期或占空比 ) ) 對 LED 亮度值的影響,進而可知道 PWM 的變化。

LED 驅動晶片的比較網頁中,LPD8806 的 PWM 調變細膩度為 7-bit,可設定的範圍 0 - 127,但對應到 0 - 255。看起來是如此,實際的測試卻不是。

在 LPD8806 的資料手冊中,並沒有關於晶片控制的說明或是範例程式可供參考。但經由網路中的搜尋可找到很有參考價值的資料,其中說明了此顆晶片的控制程式碼是封閉的,並不是可容易取得的。但是我們卻可以在網路上買到此顆晶片做的燈條以及控制器,也因為買得到控制器,所以使用逆向工程反向取得信號作分析之後,可以得出一些規則。

因為之前做過 LPD6803 的燈條控制,所以這兩者的訊號控制方式應該相差不遠!配合網路上蒐集的資料以及之前所撰寫的 LPD6803 程式,相互對照之下就完成了此份程式。

程式在樹莓派中完成,需要安裝 WiringPi 函示庫,可控制 OUT 1 ~ OUT6 六個通道 PWM 輸出。因為我不是要做控制器而是之後要控制馬達轉速,因此只能控制單顆 LPD8806,但是很容易就可以改寫適用於燈條的控制上,這部分請拿到程式的各位再自己弄吧!


NOTE:原始碼 ( lpd8806.c ) 只提供給一起購買 LPD8806 晶片和 L298N 馬達驅動模組的買家
  • LPD8806 調光測試程式 ( C )
  • LPD8806 + L298N 馬達驅動板測試程式 ( C )

所提供的檔案如下:
pi@raspberrypi ~/Codes/LED_LPD8806 $ tar -tvf LPD8806_CC.tgz
-rwxr-xr-x root/root      9589 2014-02-05 16:04 lpd8806_cctest
-rw-r--r-- webide/webide  3086 2014-02-05 15:56 lpd8806_cctest.c
-rw-r--r-- webide/webide   212 2013-12-21 11:28 lpd8806.h
-rw-r--r-- root/root      2684 2014-02-05 16:03 lpd8806.o

欲下載上面檔案,請輸入下面指令或直接點擊下載
pi@raspberrypi ~ $ cd Codes
pi@raspberrypi ~/Codes $ mkdir lpd8806_cctest
pi@raspberrypi ~/Codes $ cd lpd8806_cctest/
pi@raspberrypi ~/Codes/lpd8806_cctest $ wget -O - http://goo.gl/ukcxIJ | tar zxvf -
... << 過程省略 >>
pi@raspberrypi ~/Codes/lpd8806_cctest $ ls -l
總計 24
-rwxr-xr-x 1 pi pi 9589  2月  5 16:04 lpd8806_cctest
-rw-r--r-- 1 pi pi 3086  2月  5 15:56 lpd8806_cctest.c
-rw-r--r-- 1 pi pi  212 12月 21 11:28 lpd8806.h
-rw-r--r-- 1 pi pi 2684  2月  5 16:03 lpd8806.o
pi@raspberrypi ~/Codes/lpd8806_cctest $

若是有重新修改檔案 ( 假設是 lpd8806_cctest.c ),這時若要重新編譯產生新的執行檔,請輸入下面指令重新編譯
$ sudo gcc lpd8806.o lpd8806_cctest.c -lwiringPi -o lpd8806_cctest



下載了上面的程式之後,其中:lpd8806_cctest 是執行檔;lpd8806_cctest.c 是主程式;lpd8806.h 是 lpd8806.o 裡的函示宣告,使用時必須 include;lpd8806.o 是 lpd8806.c 的 Object 檔。

lpd8806.h 宣告四個給外部呼叫的函式:
void pwm_lpd8806_init(int sdi, int sclki, int init_status);
void pwm_lpd8806_set(int ch, int pwmvalue);
int  pwm_lpd8806_get(int ch);
void pwm_lpd8806_output(void);
  • void pwm_lpd8806_init( int sdi, int sclki, int init_status);
    晶片初始化函式。sdi 與 sclki 是樹莓派 GPIO # 連接到晶片 SDI 與 SCLKI 接腳的號碼,並且一開始就要指定晶片的亮度狀態。

    使用這函數可以將一到多的晶片知道我們要開始傳送控制信號過來了,也就起始信號的意思,沒有完成此部分就沒辦法輸入信號到晶片中。

  • void pwm_lpd8806_set ( int ch, int pwmvalue );
  • int    pwm_lpd8806_get ( int ch );
  • 上面兩個函式,顧名思義就是設定與取得各通道的 PWM 調變值。

    由於只有一顆晶片,因此只能取值與設定六個通道 ( 1 ~ 6 )。值得注意的是:值可以由 0 至 255,但是 0 至 127 是一種變化而 128 至 255 是另一種變化,也因此在 lpd8806_cctest.c 程式的 Line: 78,pwm_lpd8806_set ( sel, pwmval | 0x80 ),將所有的 0 至 127 的值轉換為 128 至 255,LED 就會是由暗到亮的變化。看自己的需要再做修改就可以了。

  • pwm_lpd8806_output ( void )
  • 當初始化完成,再設定好每一個通道的 PWM 數值之後,這個函式就是傳送 PWM 數值到各個晶片中 ( 雖然我們只有一個 )。

這四個函數在程式撰寫時呼叫的順序:先完成所有連接的晶片初始化 ( pwm_lpd8806_init ),然後設定 ( pwm_lpd8806_set ) 每個通道上的 PWM 數值。PWM 數值一但設定之後,就可以取得 (  pwm_lpd8806_get ) 與輸出 ( pwm_lpd8806_output ) 到每一顆晶片的各個通道上。詳細的流程都在 lpd8806_cctest.c 裡。
pwm_lpd8806 函式呼叫順序
pwm_lpd8806 函式呼叫順序
即便網頁中沒有提供 lpd8806.c 的原始碼,但只要了解通訊格式要實現他就很簡單 ( 這比搞 74HC595 晶片通訊還容易 )。


LPD8806 通訊格式說明:

 注意到!LPD8806 是一顆擁有 6 通道 ( 也就是可控制 2 顆 RGB LED ) 的晶片,所以晶片串接之後傳送的 PWM 數值都是以六為一個單位做連接。

通訊格式為起頭的通訊,中間資料 ( PWM 數值 ) 的傳送,以及通訊結尾的輸出三個部分,這與 74HC595 的通訊類似,不同的地方是,數據輸出不是由接腳來完成而是由第三個部分輸入通訊結尾碼來完成所有晶片所有通道同步一次性輸出。

 上述說明的部分非常重要,只要掌握通訊格式的三個部分就可以完全控制 lpd8806 晶片。而下面通訊格式的說明,將涵蓋一至多顆晶片 ( 根據資料手冊上的資料,串聯點數超過 2000 點 )。

 假設串接的 LPD8806 為 Cx 顆,則 PWM 數值點數為 Cx * 6 = 6Cx = PWMx;SDI 與 SCLKI 非別為數據接腳以及同步時脈腳位,1 為高準位,0 為低準位。

** 通訊格式 - 起始:


 一開始,LPD8806 晶片們並不知道傳送的是什麼東西。所以程式一開始必須讓所有的晶片與微處理器建立通訊,開始等待 PWM 數值的輸入或是將其輸出到通道上。

 LPD8806 晶片雖然是 7-bit 的解析度,但是在資料傳送時是以一個 Byte ( 位元組 ) 為一個單位做傳送,因此在通訊建立的起頭,必須讓所有的晶片都知道通訊已經開始,所以通訊格式的起始,就是輸入一連串的 0 到每個晶片的每個通道中。
SDI = 0;
for ( i = 0; i < PWMx; i++)
{
  SCLKI = 1;
  SCLKI = 0;
}


** 通訊格式 - PWM 數值傳送:

接著要做的就是要設定每個晶片每個通道上的 PWM 數值。LPD8806 一般都是使用在燈串上,每一顆晶片可接兩顆共陽極的 RGB LED 燈,因此若是要做混色就要參考相關資料再去做設定。

假設有一個字元矩陣,長度是 PWMx,命名為 pwm_lpd8806,宣告如下:
#define Cx          // Cx 的數目自己設
#define PWMx  (6*Cx)
unsigned char  pwm_lpd8806[PWMx];

for( j = 0; j < PWMx; j++)
{
  // 指定每個晶片每個通道的數值
  // 變化也是在這邊做
  pwm_lpd8806[j] = 0x88;
}

完成 PWM 數值的設定之後,就可以開始傳送數據到每個晶片了。每一個 PWM 數值以 Bit ( 位元 ) 的方式做傳送,由高位元至低位元做傳送,每傳送一個位元,時脈上下振盪一次將資料移入,如下示意程式:
for( k =0; k < PWMx; K++)
{
  for( m = 0; m < 8; m++ )
  {
    // 1. 比較 pwm_lpd8806 每一個位元組裡的位元,由高位元至低位元
    //    if(true) SDI = 1;
    //    else     SDI = 0;
  
    // 2. 傳送至晶片
    SCLKI = 1;
    SCLKI = 0;
  }
}


** 通訊格式 - 結尾:

完成中間資料的程序之後,通訊結尾格式一出,每個晶片就會同步輸出。

結尾部分與起始部分的程式碼類似,都是傳送一定數量的 0 到晶片中就可以。但比較不同的是,這必須用公式做運算,下邊提供較簡單的方式:

NOTE:一顆 LPD8806 可連接兩顆 RGB LED,所以 NUM_LED = 2。因為 Cx 表示 LPD8806 晶片的數量,因此 NUM_LED = Cx * 2 = 2Cx

當 Cx <= 32 ( 不包括 0 ):傳送的 0 數目等於 24 ( 3 Bytes )

也就是以 32 為一個單位,每等於或超過 32 顆,就加 24 個 0

最後再加入幾 ms 的延遲時間就可以看到燈光輸出了 !!!

示意程式如下:
SDI = 0;
// zeros 的數目計算在這邊
for( n = 0; n < zeros; ++)
{
  SCLKI = 1;
  SCLKI = 0;
}

// 延遲幾 ms。更小應該也可以,但要自己試試!!!
delay_ms(5);


以上就是整個 LPD8806 晶片的使用說明以及通訊格式的解釋,期能對此晶片有期待的各位有所助益!

沒有留言:

張貼留言

留言屬名為"Unknown"或"不明"的用戶,大多這樣的留言都會直接被刪除掉,不會得到任何回覆!

發問問題,請描述清楚你(妳)的問題,別人回答前不會想去 "猜" 問題是什麼?

不知道怎麼發問,請看 [公告] 部落格提問須知 - 如何問問題 !