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
}