树莓派3B 之IIC通信

上一篇我们将了树莓派的uart通信。

本篇幅我们来讲一下,树莓派IIC通信。

读取slave 的数据。

树莓派3B 之IIC通信_第1张图片

依然我们用wirningPi库,驱动IIC 的引脚编号8/9,分别用作SDA/SCL。

我们用来读取陀螺仪模块的三个方向姿态角数据。

bsp_iic.cpp:

#include "jy901_Init.h"
#include 


//读取到的原始角度
float x_angle = 0;  // roll
float y_angle = 0;  // pitch
float z_angle = 0;  // yaw

//===========================================================================
//使用何种滤波器
#define USE_MIDDLE_FILTER   1
#define USE_AVERAGE_FILTER  1 - USE_MIDDLE_FILTER

static const int SIZE = 5;   //排序数组长度
short x_f = 0;
short y_f = 0;
short z_f = 0;
short x_buff[SIZE],y_buff[SIZE],z_buff[SIZE];

#if USE_MIDDLE_FILTER
/*
 * bubble sort  冒泡法排序
 */
void bubble_sort(short *data, short size)
{
    short i;
    short temp;

    while(size > 1)
    {
        for(i = 0; i < size; i++)
        {
            if(data[i] > data[i+1])
            {
                temp = data[i];
                data[i] = data[i+1];
                data[i+1] = temp;
            }
        }
        size--;
    }

}

//中值滤波器
short median_filter(short data[])
{
    short output;

    bubble_sort(data,SIZE);
    return output = data[SIZE/2];
}
#endif/*USE_MIDDLE_FILTER*/

#if USE_AVERAGE_FILTER
//均值滤波器
short average_calculate(short *data, short size)
{
    int i,j,temp,sum = 0;
    short ave;

    for(j = 0; j < size; j++)          //冒泡排序
    {
        for(i = j; i < size - j; i++)
        {
            if(data[i] > data[i+1])
            {
                temp = data[i];
                data[i] = data[i+1];
                data[i+1] = temp;
            }
        }
    }

    for(i = 0; i < size; i++)  //原本用来虑掉突变的最大最小值
    {
        sum += data[i];
    }

    ave = sum/(SIZE);
    return ave;
}

short average_filter(short data[])
{
    short output;

    output = average_calculate(data,SIZE);

    return output;
}
#endif /*USE_AVERAGE_FILTER*/


int fd;

//初始化树莓派的IIC
void Bsp_Jy901Init(void)
{
        wiringPiSetup();
        fd = wiringPiI2CSetup(DEV_SLAVE);
}
//原始角度数据读取
static void Bsp_Jy901_SrcDataRead(short *roll_angSrc, short *pitch_angSrc, short *yaw_angSrc)
{
//    int fd;

//    wiringPiSetup();
//    fd = wiringPiI2CSetup(DEV_SLAVE);
    *roll_angSrc  = wiringPiI2CReadReg16(fd, Roll);
    *pitch_angSrc = wiringPiI2CReadReg16(fd, Pitch);
    *yaw_angSrc   = wiringPiI2CReadReg16(fd, Yaw);
}

//数据采样
void sample_data(void)
{
    short i;
    short x_buff_efs[SIZE],y_buff_efs[SIZE],z_buff_efs[SIZE];
    static int first_time = 0;

    if(first_time == 0) //第一次开机读取五个数据
       {
           for(i = 0; i < SIZE; i++)
           {
               Bsp_Jy901_SrcDataRead(&x_buff[i], &y_buff[i], &z_buff[i]);
           }
           first_time = 1;
       }

        for(i = 0; i < SIZE; i++)       //先将读取的组数据放到备份缓冲区
        {
            x_buff_efs[i] = x_buff[i];
            y_buff_efs[i] = y_buff[i];
            z_buff_efs[i] = z_buff[i];
        }

#if USE_MIDDLE_FILTER
        x_f = median_filter(x_buff_efs); //取出中间值
        y_f = median_filter(y_buff_efs);
        z_f = median_filter(z_buff_efs);
#endif
#if USE_AVERAGE_FILTER
          x_f = average_filter(x_buff_efs);
          y_f = average_filter(y_buff_efs);
          z_f = average_filter(z_buff_efs);
#endif
        for(i = 0; i < SIZE-1; i++)      // 依次左移,最后一位放新数据
        {
            x_buff[i] = x_buff[i+1];
            y_buff[i] = y_buff[i+1];
            z_buff[i] = z_buff[i+1];
        }

        Bsp_Jy901_SrcDataRead(&x_buff[SIZE-1], &y_buff[SIZE-1], &z_buff[SIZE-1]);

}
//===========================================================================
//===============================MODE_CHANGE==================
/*
 *  mode change :
 *   0    6axis
 *   1    9axis 
 */
void Bsp_Jy901ModeChg(int mode)
{
	wiringPiI2CWriteReg16(fd, AXIS_CHG, mode);
}

//===============================MODE_CHANGE==================

short roll_angle  = 0;
short pitch_angle = 0;
short yaw_angle   = 0;

//循环获取原始角度原始数据
static void Bsp20180130_Jy901_SrcDataRead(void)
{
    roll_angle  = wiringPiI2CReadReg16(fd, Roll);
    pitch_angle = wiringPiI2CReadReg16(fd, Pitch);
    yaw_angle   = wiringPiI2CReadReg16(fd, Yaw);
}

//最终输出角度
void Bsp_Jy901_AngOut(void)
{
//    Bsp_Jy901_SrcDataRead();
    Bsp20180130_Jy901_SrcDataRead();
    x_angle  = (roll_angle/32768.0)*181;
    y_angle  = (pitch_angle/32768.0)*181;
    z_angle  = (yaw_angle/32768.0)*181;

}

bsp_iic.h

#ifndef JY901_INIT_H
#define JY901_INIT_H

#include "wiringPiI2C.h"
#include "wiringPi.h"

//从机地址
#define DEV_SLAVE           0x50

//寄存器地址
#define SETUP_SAVE 	        0x00
#define CALSW 		        0x01
#define RSW 			    0x02
#define RRATE			    0x03
#define BAUD 			    0x04
#define AXOFFSET	        0x05
#define AYOFFSET	        0x06
#define AZOFFSET	        0x07
#define GXOFFSET	        0x08
#define GYOFFSET	        0x09
#define GZOFFSET	        0x0a
#define HXOFFSET	        0x0b
#define HYOFFSET	        0x0c
#define HZOFFSET	        0x0d
#define D0MODE		        0x0e
#define D1MODE		        0x0f
#define D2MODE		        0x10
#define D3MODE		        0x11
#define D0PWMH		        0x12
#define D1PWMH		        0x13
#define D2PWMH		        0x14
#define D3PWMH		        0x15
#define D0PWMT		        0x16
#define D1PWMT		        0x17
#define D2PWMT		        0x18
#define D3PWMT		        0x19
#define IICADDR		        0x1a
#define LEDOFF 		        0x1b
#define GPSBAUD		        0x1c

#define YYMM				0x30
#define DDHH				0x31
#define MMSS				0x32
#define MS					0x33
#define AX					0x34
#define AY					0x35
#define AZ					0x36
#define GX					0x37
#define GY					0x38
#define GZ					0x39
#define HX					0x3a
#define HY					0x3b
#define HZ					0x3c

#define Roll				0x3d
#define Pitch				0x3e
#define Yaw					0x3f

#define TEMP				0x40
#define D0Status		    0x41
#define D1Status		    0x42
#define D2Status		    0x43
#define D3Status		    0x44
#define PressureL		    0x45
#define PressureH		    0x46
#define HeightL			    0x47
#define HeightH			    0x48
#define LonL				0x49
#define LonH				0x4a
#define LatL				0x4b
#define LatH				0x4c
#define GPSHeight           0x4d
#define GPSYAW              0x4e
#define GPSVL				0x4f
#define GPSVH				0x50
#define Q0                  0x51
#define Q1                  0x52
#define Q2                  0x53
#define Q3                  0x54

#define DIO_MODE_AIN        0
#define DIO_MODE_DIN        1
#define DIO_MODE_DOH        2
#define DIO_MODE_DOL        3
#define DIO_MODE_DOPWM      4
#define DIO_MODE_GPS        5

#define AXIS_6				0
#define AXIS_9				1
#define AXIS_CHG			0x24		


//读写函数
void Bsp_Jy901Init(void);
void Bsp_Jy901ModeChg(int mode);
void Bsp_Jy901_AngOut(void);

#endif // JY901_INIT_H

 

在这里面我们深究一下,可以知道IIC的内部实现部分被封装。

用户是看不到的,所以我们只能看到函数的借口封装。

树莓派3B 之IIC通信_第2张图片

由图中可以看到,IIC的读1byte/2byte全部都封装好了。

我们直接调用就可以了。

你可能感兴趣的:(树莓派)