1. 程式人生 > >ARM40-A5應用——W1LED的使用說明

ARM40-A5應用——W1LED的使用說明

ARM40-A5應用——W1LED的使用說明

2018.11.7

  ARM40的一些產品上需要用到較多的LED指示燈,此時推薦使用W1LED來實現。
  ARM40主機監測GPIO、串列埠(RS232和RS485)、CAN等外設的輸入/輸出狀態,定期(例如每100ms)給W1LED指示燈板傳送資料,控制LED指示燈的亮/滅。
  W1LED指示燈板上有一顆MCU,接收ARM40主機發來的資料,根據接收到的指令,來控制燈板上的LED。
  W1LED指示燈板使用3根線(VCC、GND、DQ)即可,並且多個W1LED指示燈板可共享ARM40主機板上的DQ訊號,根據各自的ID號來執行發給自己的指令。DQ訊號在ARM40-A5上預設為PE20.
  W1LED佔用IO少,使用靈活方便,並且LED反應了主機的工作狀態,而不僅僅是反應了局部硬體電路的狀態。當然,也可以在電路板上增加硬體控制的指示裝置,與W1LED的方法並無衝突。
  

一、W1LED的硬體電路

在這裡插入圖片描述
  圖1為W1LED燈板的硬體電路,MCU可外接LED0~LED23共24個LED,這24個LED分別接到MCU的如下IO,且IO為高電平時點亮LED。

P10~P17;        //接LED0~LED7;
P20~P27;        //接LED8~LED15;
P30, P31, P55, P33, P34, P35, P36, P37;        //接LED16~LED23

  W1LED燈板的工作溫度-40℃~85℃。
  W1LED燈板VCC電壓範圍為2.4V~5.5V,VCC電壓應不低於DQ的高電平:

若DQ高電平為3.3V,VCC為3.3V~5V;
若DQ高電平為5V,則VCC為5V。

  使用時,應按照LED0到LED23的順序,先使用小數值的LED。例如,使用了4顆LED,則應占有LED0~LED3,而不應隨意排列組合。

二、ARM40上的配置

  ARM40主機監測GPIO、串列埠(RS232和RS485)、CAN等外設的輸入/輸出狀態,核心執行緒 kw1ledd 定期(例如每100ms)給W1LED指示燈板傳送資料,控制LED指示燈的亮/滅。
  核心執行緒 kw1ledd 的配置如下:
  (1) /etc/init.d/S01user3module 檔案

touch /etc/init.d/S01user3module
chmod 755 /etc/init.d/S01user3module

  其內容為:

#!/bin/sh
set -e
modprobe w1led.ko

  (2) /lib/modules/3.18.0/w1led.ko
  將核心模組 w1led.ko 拷貝到 /lib/modules/3.18.0/ 目錄。
  (3) /lib/modules/3.18.0/modules.dep
touch /lib/modules/3.18.0/modules.dep
  其內容為:
w1led.ko:
  (4) /etc/modprobe.conf
touch /etc/modprobe.conf
  其內容為:

options w1led ID1_pio=136,137,138,139,140,141,142,143,144
options w1led ID1_hla=0xfff000
options w1led ID2_pio=136,137,138,139,140,141,142,143,144
options w1led ID2_hla=0
options w1led ID3_pio=136,137,138,139,140,141,142,143,144
options w1led ID3_hla=0xffffff

  載入核心模組 modprobe w1led.ko 時,會解讀 /etc/modprobe.conf 檔案,參考《Kernel module (簡體中文)》。
  下文解釋其中的引數ID1_pio 和 ID1_hla;引數ID2_pio、ID3_pio 、ID2_hla、ID3_hla是類似的。

三、W1LED的資料格式

  ARM40-A5主機目前暫支援最多3個W1LED燈板,ID號分別是:

  W1LED_ID1(0x0100 0000),對應 ID1_pio 和 ID1_hla;
  W1LED_ID2(0x0200 0000),對應 ID2_pio 和 ID2_hla;
  W1LED_ID3(0x0300 0000),對應 ID3_pio 和 ID3_hla;

  W1LED指示燈板接收32bit的資料,格式如下:
在這裡插入圖片描述
  W1LED燈板收到32bit的資料,計算異或和校驗,若校驗和為0(正確),則對比 ID 號,若與其自身 ID 號相同,則分析b23-b0的資料。b23-b0中為1的位,則使能 LED23-LED0 中相應的LED點亮。
  W1LED資料格式示例見附(1),校驗和演算法見附(2)。

四、/etc/modprobe.conf 檔案

4.1、 ID1_pio

  檔案 /etc/modprobe.conf 中的 ID1_pio:
  (1)ID1_pio中的引數與ARM40-A5的pio對應;
  (2)ID1_pio中引數的位置與 W1LED 資料格式中的b0-b23對應。

options w1led ID1_pio=136,137,138,139,140,141,142,143,144    //最多24個,因LED0-LED23只有24個LED
options w1led ID1_hla=0xfff000

  先分析與ARM40-A5的pio對應,ARM40-A5共有160個pio,分別為PA0-PA31、PB0-PB31、PC0-PC31、PD0-PD31、PE0-PE31。對應的數值為:

PA0~PA31:  0~31;
PB0~PB31:  32~63;
PC0~PC31:  64~95;
PD0~PD31:  96~127;
PE0~PE31:  128~159;

  因此 ID1_pio=136,137,138,139,140,141,142,143,144 對應 PE8~PE16,為方便理解,我們示意性的寫為(w1led.ko不認可這種示意寫法):
ID1_pio=PE8,PE9,PE10,PE11,PE12,PE13,PE14,PE15,PE16
  
  再分析與 W1LED 資料格式中b0-b23的對應。
ID1_pio=136,137,138,139,140,141,142,143,144 分別與b0~b8對應,我們示意性的寫為(w1led.ko不認可這種示意寫法):
ID1_pio=b0,b1,b2,b3,b4,b5,b6,b7,b8
  
  我們把這兩個對應關係結合起來理解:
  ARM40_PE8 決定 W1LED_ID1_LED0 的亮和滅;
  ARM40_PE9 決定 W1LED_ID1_LED1 的亮和滅;
  … …
  ARM40_PE16 決定 W1LED_ID1_LED8 的亮和滅;

  那麼,ARM40_PE8為高電平時, W1LED_ID1_LED0 亮; 還是為低電平時,W1LED_ID1_LED0 亮呢?
  這是由 ID1_hla 決定的。

4.2、ID1_hla

  我們看例子:
ID1_pio= b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,b16,b17,b18,b19,b20,b21,b22,b23 //示意性寫法
  若 ID1_hla=0xfff000 表示 b0-b11為低電平有效,b12-b23為高電平有效。
  若 ID1_hla=0xf0f0f0 表示 b0-b3, b8-b11, b16-b19為低電平有效,b4-b7, b12-b15, b20-b23為高電平有效。

4.3、 ID1_pio 和 ID1_hla 例項

  多數情況下,我們可能只用到一個W1LED燈板,此時 /etc/modprobe.conf 為:

options w1led ID1_pio=134,57,138    //只有3個LED,對應PE6,PB25,PE10
options w1led ID1_hla=6             //PE6低電平有效; PB25,PE10高電平有效

  我們用下圖表示這個關係:
在這裡插入圖片描述
  注:
  (1)圖中將ID1_hla=6 改為了低位在前,與ID1_pio低位在前保持一致,方便作圖。
  (2)圖中紫色小圓圈表示PE6的低電平將點亮LED0,紅色圓點表示高電平點亮LED。
  修改 ID1_pio= 中的值,即可指定ARM40-A5上哪個pio與LED0、LED1、LED2對應;
  修改 ID1_hla= 的值,即可指定ARM40-A5上的pio是高電平還是低電平點亮相應的LED。

4.4、gpio的測試

  見《ARM40-A5應用程式——GPIO輸出高低電平》,例如對PE10輸出高/低電平,觀察W1LED燈板上LED的狀態。
  配置 /etc/modprobe.conf :

options w1led ID1_pio=138     //只有1個LED,對應PE10
options w1led ID1_hla=1       //PE10高電平有效

  在shell中操作PED10,輸出高/低電平,觀察W1LED燈板上LED0的狀態。

echo 138 > /sys/class/gpio/export
echo out > /sys/class/gpio/pioE10/direction
echo 1 > /sys/class/gpio/pioE10/value
echo 0 > /sys/class/gpio/pioE10/value
echo 138 > /sys/class/gpio/unexport

五、串列埠與W1LED

5.1、 串列埠的ID1_pio

  對串列埠來說,不像gpio要區分高/低電平有效,串列埠是收到資料即點亮W1LED板上的一個LED,發出資料點亮W1LED板上的另一個LED。串列埠會無視ID1_hla。
  IDx_pio中的引數與串列埠傳送/接收的對應關係如下:
在這裡插入圖片描述
舉個 /etc/modprobe.conf 的例子:

options w1led ID1_pio=134,-2,138     //只有3個LED,對應PE6,ttyS0_RXRDY,PE10
options w1led ID1_hla=6              //PE6低電平有效,PE10高電平有效; ttyS0會無視IDx_hla的配置

5.2、串列埠的測試

  串列埠接收/傳送資料,觀察W1LED燈板上LED的狀態。
  配置 /etc/modprobe.conf :
options w1led ID1_pio=-13 //只有1個LED,對應ttyS5_TXRDY,ttyS5會無視IDx_hla的配置
  在shell中操作 ttyS5,觀察W1LED燈板上LED0的狀態。

cat /dev/ttyS5 &
echo 1234 > /dev/ttyS5

  

參考文章:

  Kernel module (簡體中文)   https://wiki.archlinux.org/index.php/Kernel_module_(簡體中文)
  linux模組程式設計(二)——執行不息的核心執行緒kthread
  https://blog.csdn.net/qb_2008/article/details/6835783
  Linux核心多執行緒(二)
  https://www.cnblogs.com/zhuyp1015/archive/2012/06/11/2545702.html
  用軟體實現1-Wire®通訊
  https://www.maximintegrated.com/cn/app-notes/index.mvp/id/126
  Linux 驅動之模組引數–Linux裝置驅動程式
  https://blog.csdn.net/gatieme/article/details/51009094
  ARM40-A5應用程式——GPIO輸出高低電平
  https://blog.csdn.net/vonchn/article/details/63684452
  薈聚計劃:共商 共建 共享 Grant
  

附:

(1)W1LED資料格式示例
  例:資料為 0xd1e7f9fc
在這裡插入圖片描述
例:資料為 0x91e7f9bc
在這裡插入圖片描述
(2)W1LED資料格式的校驗和
  異或和校驗演算法如下,校驗和為0,表示校驗正確。

unsigned int calc_4bitecc(unsigned int data)
{
        unsigned int xor;       
        xor = data ^ (data >> 16);      
        xor ^= (xor >> 8);
        xor ^= (xor >> 4);      
        return xor & 0xF;           //4bit異或和正確時,返回值是0
}