This time with SPI. BBB is available in two sets of SPI interfaces, both of which are default disable and need to be enabled in overlay mode, i.e.:
echo bb-spidev0 >/sys/devices/bone_capemgr.9/slots
My BBB current configuration is currently configured
/opt/source/userspace-arduino/overlay/bb-spi0-01-00a0.dts
/dts-v1/;
/plugin/;
/ {
compatible = "Ti,beaglebone", "Ti,beaglebone-black";
/* Identification */
Part-number = "Spi0pinmux";
[Email protected] {
target = <&am33xx_pinmux>;
__overlay__ {
SPI0_PINS_S0:SPI0_PINS_S0 {
Pinctrl-single,pins = <
0x150 0x30/* SPI0_SCLK, Input_pullup | MODE0 * *
0x154 0x30/* spi0_d0, Input_pullup | MODE0 * *
0x158 0x10/* spi0_d1, Output_pullup | MODE0 * *
0X15C 0x10/* Spi0_cs0, Output_pullup | MODE0 * *
>;
};
};
};
[Email protected] {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
Status = "Okay";
Pinctrl-names = "Default";
pinctrl-0 = <&spi0_pins_s0>;
[Email protected] {
Spi-max-frequency = <24000000>;
Reg = <0>;
compatible = "Linux,spidev";
};
};
};
};
on page 30th of the manual, BMP280 supports Mode 00 and 11, which are automatically selected. Can be connected with three or four wires.
DTS file is visible, currently is mode 0, you can directly connect the BMP280.
SPI Wiring –bmp280
Schematic in the previous blog, from the figure can be learned that the BMP280 of the film is Csb,ncs is the nine-axis MPU9250 chip selection pin.
Black to close to the scrap of the tip gave me a reasonable excuse, but also please ignore my rotten to the slag of the welding. The wiring of the SPI0 is as follows:
gy-91 |
|
p9_1 |
gnd |
ground |
p9_3 |
3v3 |
power |
p9_22 |
SCL |
clock |
p9_17 |
CSB |
Slice selection |
SDA |
|
sa0 |
miso |
Enable SPI0:
echo bb-spidev0 >/sys/devices/bone_capemgr.9/slots
Then it will appear in/dev:
spidev1.0 representative Bus number 1 piece election number 0.
SPI read ID Register value for BMP280
Note For example, the image is intercepted from the SPI read mode of BMP280 datasheet,bmp280 a byte from the BBB is a control Byte,control byte bit 7 for controlling read and write, the address is the remaining 7 Bits The Data byte after Control byte is received, such as my four line situation, it appears in the miso, so the expression is more difficult to understand ....
Look at the sequence diagram, see this I better understand some:
In the process of communication, the chip pick is down.
After all, the main character is the nine-axis, BMP280 temperature pressure on a quick try, just try it. C code.
There are several episodes, I first want to use Python, easy to write easy to change, found the Spidev, but in any case can not be used duplex, eventually due to the time relationship, give up. Py-spidev See this link:
Https://pypi.python.org/pypi/spidev. Later instead of C, a variety of Baidu Fq Google, mostly Arduino and the use of Adfruit class library, see a variety of Digital Write, and finally gave up. Finally directly with Linux/spi/spidev to refer to others directly to write.
#include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include < fcntl.h> #include <sys/ioctl.h> #include <linux/spi/spidev.h>char buf[1];char buf2[10];struct spi_ioc_ Transfer xfer[2];int Spi_init (char filename[40]) {int file; __u8 mode = 0; __u8 LSB = 0; __u8 bits = 8; __u32 speed = 10000000; if (file = open (filename,o_rdwr)) < 0) {printf ("Failed to open the bus."); Exit (1); } if (IOCTL (file, Spi_ioc_wr_mode, &mode) <0) {perror ("can ' t set SPI MODE"); Return } if (IOCTL (file, Spi_ioc_rd_mode, &mode) < 0) {perror ("SPI rd_mode"); Return } if (IOCTL (file, Spi_ioc_rd_lsb_first, &LSB) < 0) {perror ("SPI rd_lsb_fist"); Return } if (IOCTL (file, Spi_ioc_wr_bits_per_word, &bits) <0) { Perror ("can ' t set bits per word"); Return } if (IOCTL (file, Spi_ioc_rd_bits_per_word, &bits) < 0) {perror ("SPI Bits_per_word"); Return } if (IOCTL (file, Spi_ioc_wr_max_speed_hz, &speed) <0) {perror ("can ' t set MAX speed HZ"); Return } if (IOCTL (file, Spi_ioc_rd_max_speed_hz, &speed) < 0) {perror ("SPI max_speed_hz"); Return } printf ("%s:spi mode%d,%d bits%sper Word,%d Hz max\n", filename, mode, bits, LSB?) "(LSB first)": "", speed); return file;} char * spi_read (int addr,int nbytes,int file) {int status; memset (buf, 0, sizeof BUF); memset (buf2, 0, sizeof buf2); Buf[0] = addr | 128; Xfer[0].tx_buf = (unsigned long) buf; Xfer[0].len = 1; Xfer[1].rx_buf = (unsigned long) buf2; Xfer[1].len = nbytes; Status = IOCTL (file, Spi_Ioc_message (2), Xfer); if (Status < 0) {perror ("spi_ioc_message"); Return } return buf2;} int main () {char * buffer; int File=spi_init ("/dev/spidev1.0"); Buffer = Spi_read (0xd0,1,file); printf ("0x%x\n", *buffer);}
Code changed from here: Http://linux-sunxi.org/SPIdev, the original is Sunxi, I have modified and removed some unreasonable places.
First configuration, the default mode 0, 8 bit per word then the speed to BMP280 the upper limit of 10MHz, and then with the Read method, two xfer thrown in, a write 0xD0, representing I want to read the ID Register, one is read buf2, return Buf2 to main and print it out. Read inside the bitwise OR is to make sure bit 7 is 1, lest I hit the wrong address incorrectly to manipulate the write. Effect:
Return 0x58,id is correct.
SPI Write BMP280 Register, read current temperature
BMP280 Ctrl_meas Write value, continuous measurement, the highest precision, only detect temperature regardless of air pressure (address and values see previous article), and then read the temperature of the original data and temperature compensation, and then converted to c printf out, code:
#include <stdio.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include < string.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/spi/spidev.h> #define Dig_ START 0x88#define temp_start 0xfa#define ctrl_meas 0xf4#define temp_only_normal_mode 0xe3//111 11char Buf[10];char B Uf2[10];struct spi_ioc_transfer xfer[2];int spi_init (char filename[40]) {int file; __u8 LSB = 0; __u8 mode = 0; __u8 bits = 8; __u32 speed = 10000000; if (file = open (filename,o_rdwr)) < 0) {printf ("Failed to open the bus."); Exit (1); } if (IOCTL (file, Spi_ioc_wr_mode, &mode) <0) {perror ("can ' t set SPI MODE"); Return } if (IOCTL (file, Spi_ioc_rd_mode, &mode) < 0) {perror ("SPI rd_mode"); Return } if (IOCTL (file, Spi_ioc_rd_lsb_first, &LSB) < 0) { Perror ("SPI rd_lsb_fist"); Return } if (IOCTL (file, Spi_ioc_wr_bits_per_word, &bits) <0) {perror ("can ' t set BITS PER WORD"); Return } if (IOCTL (file, Spi_ioc_rd_bits_per_word, &bits) < 0) {perror ("SPI Bits_per_word"); Return } if (IOCTL (file, Spi_ioc_wr_max_speed_hz, &speed) <0) {perror ("can ' t set MAX speed HZ"); Return } if (IOCTL (file, Spi_ioc_rd_max_speed_hz, &speed) < 0) {perror ("SPI max_speed_hz"); Return } return file; char * spi_read (int addr,int nbytes,int file) {int status; memset (buf, 0, sizeof BUF); memset (buf2, 0, sizeof buf2); Buf[0] = addr | 128; Xfer[0].tx_buf = (unsigned long) buf; Xfer[0].len = 1; Xfer[1].rx_buf = (unsigned long) buf2; Xfer[1].len = nbytes; Status = IOCTL (file, Spi_ioc_message (2), Xfer); if (Status < 0) {perror ("spi_ioc_message"); Return } return buf2;} void spi_write (int addr, char value, int file) {int status; memset (buf, 0, sizeof BUF); Buf[0] = addr & 127; BUF[1] = value; Xfer[0].tx_buf = (unsigned long) buf; Xfer[0].len = 2; Status = IOCTL (file, Spi_ioc_message (1), Xfer); if (Status < 0) {perror ("spi_ioc_message"); }}float MyFunc (uint32_t adc_t, unsigned short dig_t1, short dig_t2, short dig_t3) {uint32_t var1, var2; float T; Var1 = ((double) adc_t)/16384.0-((double) dig_t1)/1024.0) * ((double) dig_t2); Var2 = (((double) adc_t)/131072.0-((double) dig_t1)/8192.0) * (((double) adc_t)/131072.0-((double) dig_t1)/8192.0) * ( (double) dig_t2); T = (var1+var2)/5120.0; return T;} int main () {int i; char * ID; char * mode; CharDIG_BUFF[6]; Char tmp_buff[3]; int File=spi_init ("/dev/spidev1.0"); id = spi_read (0xd0,1,file); printf ("id:0x%02x\n", *id); Spi_write (Ctrl_meas,temp_only_normal_mode,file); mode = Spi_read (Ctrl_meas,1,file); printf ("mode:0x%02x\n", *mode); memcpy (Dig_buff, Spi_read (Dig_start, 6, file), 6); memcpy (Tmp_buff, Spi_read (Temp_start, 3, file), 3); printf ("dump:\n"); for (i=0; i<6; i++) {printf ("%02x", Dig_buff[i]); } printf ("\ n"); for (i=0; i<3; i++) {printf ("%02x", Tmp_buff[i]); } printf ("\ n"); int adc_t = ((tmp_buff[0]<<16) | ( TMP_BUFF[1]<<8) | (Tmp_buff[2])) >>4; unsigned short dig_t1 = (dig_buff[1]<<8) | (Dig_buff[0]); Short dig_t2 = (dig_buff[3]<<8) | (Dig_buff[2]); Short dig_t3 = (dig_buff[5]<<8) | (Dig_buff[4]); printf ("adc_t is:%d \ n", adc_t); printf ("Dig_t1 is:%d \ n", DIG_T1); printf ("Dig_t2 is:%d \ n", dig_t2); printf ("Dig_t3 is:%d \ n", dig_t3); printf ("Temperature is:%f \ n", MyFunc (adc_t, Dig_t1, Dig_t2, dig_t3)); return 0;}
Effect:
For temperature compensation and actual centigrade thermometer calculation, please see an i²c demonstration. Spi_write inside the bitwise and is to ensure that bit 7 is zero, write mode. Since I use the same buf and BUF2, the actual application of read requires a copy.
I struggled with the attempt to use Python to do the SPI duplex and wasted a lot of time, and eventually it didn't work out. Finally give up that layer of encapsulation, directly with C Spidev, immediately spring, 28°c.
Next, use SPI to invoke acceleration sensing and tilt angle.
Beaglebone black– Connection GY-91 mpu9250+bmp280 nine-axis sensor (2)