树梅派 -- 通过/sys读写ADC芯片 pcf8591

通过wiringPi等library, 在user space 通过/dev/i2c来读写i2c设备的方案不在本文讨论了。

编译SENSORS_PCF8591 模块

在Default raspberryPi的内核中,pcf591模块是没有编译的。

查看drivershwmonMakefile

obj-$(CONFIG_HWMON)        += hwmon.o
...

obj-$(CONFIG_SENSORS_PCF8591)  += pcf8591.o
...

修改archarmconfigscm2709_defconfig, 增加一行 CONFIG_SENSORS_PCF8591=m

CONFIG_HWMON=m
...
CONFIG_SENSORS_PCF8591=m

执行

make mrproper
make modules

将pcf8591.ko copy到raspberryPi板子

如果单独编译hwmon下的模块,

make modules SUBDIRS=drivers/hwmon/

install module

pi@raspberrypi:/lib/modules/4.14.48-v7+/kernel/drivers/hwmon $ sudo insmod pcf8591.ko

查看module是否install

pi@raspberrypi:/lib/modules/4.14.48-v7+/kernel/drivers/hwmon $ lsmod
Module                  Size  Used by
pcf8591                16384  0

insmode 参数

The PCF8591 has 4 analog inputs programmable as single-ended or
differential inputs :
- mode 0 : four single ended inputs
Pins AIN0 to AIN3 are single ended inputs for channels 0 to 3

  • mode 1 : three differential inputs
    Pins AIN3 is the common negative differential input
    Pins AIN0 to AIN2 are positive differential inputs for channels 0 to 2

  • mode 2 : single ended and differential mixed
    Pins AIN0 and AIN1 are single ended inputs for channels 0 and 1
    Pins AIN2 is the positive differential input for channel 3
    Pins AIN3 is the negative differential input for channel 3

  • mode 3 : two differential inputs
    Pins AIN0 is the positive differential input for channel 0
    Pins AIN1 is the negative differential input for channel 0
    Pins AIN2 is the positive differential input for channel 1
    Pins AIN3 is the negative differential input for channel 1

/* Insmod parameters */
I2C_CLIENT_INSMOD_1(pcf8591);

static int input_mode;
module_param(input_mode, int, 0);
MODULE_PARM_DESC(input_mode,
    "Analog input mode:
"
    " 0 = four single ended inputs
"
    " 1 = three differential inputs
"
    " 2 = single ended and differential mixed
"
    " 3 = two differential inputs
");

创建i2c device

查看i2c总线上的设备。 在使用中的0x68为RTC. 0x48为PCF8591

pi@raspberrypi:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- 76 -- 

创建设备

pi@raspberrypi:/sys/class/i2c-adapter/i2c-1 $ echo pcf8591 0x48 | sudo tee new_device
pcf8591 0x48
pi@raspberrypi:/sys/class/i2c-adapter/i2c-1 $ ls
1-0048  delete_device  i2c-dev  new_device  power      uevent
1-0068  device         name     of_node     subsystem

再次查看总线,可以看到0x48设置为UU, 表示在使用中

pi@raspberrypi:/sys/class/i2c-adapter/i2c-1 $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- 76 --     

查看

pi@raspberrypi:/sys/class/i2c-adapter/i2c-1/1-0048 $ ls
driver  in0_input  in2_input  modalias  out0_enable  power      uevent
hwmon   in1_input  in3_input  name      out0_output  subsystem

/sys Interface

The PCF8591 is plainly impossible to detect! Thus the driver won’t
even try. You have to explicitly instantiate the device at the
relevant address (in the interval [0x48..0x4f]) either through
platform data, or using the sysfs interface. See
Documentation/i2c/instantiating-devices for details.

Directories are being created for each instantiated PCF8591:

/sys/bus/i2c/devices/<0>-<1>/ where <0> is the bus the chip is
connected to (e. g. i2c-0) and <1> the chip address ([48..4f])

Inside these directories, there are such files: in0_input, in1_input,
in2_input, in3_input, out0_enable, out0_output, name

Name contains chip name.

The in0_input, in1_input, in2_input and in3_input files are RO.
Reading gives the value of the corresponding channel. Depending on the
current analog inputs configuration, files in2_input and in3_input may
not exist. Values range from 0 to 255 for single ended inputs and -128
to +127 for differential inputs (8-bit ADC).

The out0_enable file is RW. Reading gives “1” for analog output
enabled and “0” for analog output disabled. Writing accepts “0” and
“1” accordingly.

The out0_output file is RW. Writing a number between 0 and 255 (8-bit
DAC), send the value to the digital-to-analog converter. Note that a
voltage will only appears on AOUT pin if aout0_enable equals 1.
Reading returns the last value written.

Reference

https://www.kernel.org/doc/Documentation/hwmon/pcf8591

原文地址:https://www.cnblogs.com/feiwatson/p/9478201.html