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的硬件电路

ARM40-A5应用——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的数据,格式如下:
ARM40-A5应用——W1LED的使用说明
  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高电平有效

  我们用下图表示这个关系:
ARM40-A5应用——W1LED的使用说明
  注:
  (1)图中将ID1_hla=6 改为了低位在前,与ID1_pio低位在前保持一致,方便作图。
  (2)图中紫色小圆圈表示PE6的低电平将点亮LED0,红色圆点表示高电平点亮LED。
  修改 ID1_pio= 中的值,即可指定ARM40-A5上哪个pio与LED0、LED1、LED2对应;
  修改 ID1_hla= 的值,即可指定ARM40-A5上的pio是高电平还是低电平点亮相应的LED。

五、串口与W1LED

5.1、 ID1_pio与ID1_hla 之于串口

  对串口来说,

六、测试

  首先根据"二、ARM40上的配置" 配置好各个文件。

6.1、gpio的测试

  见《ARM40-A5应用程序——GPIO输出高低电平》,例如对PE10输出高/低电平,观察W1LED灯板上LED的状态。

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

6.2、串口的测试

  串口接收/发送数据,观察W1LED灯板上LED的状态。

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

  

参考文章:

  Kernel module (简体中文)   https://wiki.archlinux.org/index.php/Kernel_module_(简体中文)
  linux模块编程(二)——运行不息的内核线程kthread
  https://blog.****.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.****.net/gatieme/article/details/51009094
  ARM40-A5应用程序——GPIO输出高低电平
  https://blog.****.net/vonchn/article/details/63684452
  荟聚计划:共商 共建 共享 Grant
  

附:

(1)W1LED数据格式示例
  例:数据为 0xd1e7f9fc
ARM40-A5应用——W1LED的使用说明
例:数据为 0x91e7f9bc
ARM40-A5应用——W1LED的使用说明
(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
}