您现在的位置是:首页 >其他 >IMX6ULL裸机篇之I2C实验之从设备代码实现网站首页其他

IMX6ULL裸机篇之I2C实验之从设备代码实现

凌雪舞 2024-09-01 12:01:03
简介IMX6ULL裸机篇之I2C实验之从设备代码实现

一.   I2C实验

本文介绍 I2C实验,关于 从设备 AP3216C传感器的I2C代码实现。

AP3216C从设备是 三合一传感器,即作为 I2C通信中从设备使用。

以下文章是关于 I2C实验,关于主控制器(即主设备)端的 I2C代码实现:

IMX6ULL裸机篇之I2C实验主控代码说明一_凌雪舞的博客-CSDN博客

IMX6ULL裸机篇之I2C实验主控代码说明二_凌雪舞的博客-CSDN博客

二.   AP3216C从设备 I2C 代码

1.  AP3216C 传感器说明

编写 AP3216C传感器的 I2C相关代码时,这里就需要参考 AP3216C传感器的参考手册。

AP3216C传感器的参考手册目录:/基础资料 / 硬件资料 / 芯片资料 / AP3216C.pdf

AP3216C.pdf 参考手册上可以知道:

1.  AP3216C传感器的设备地址为:   0X1E

2. 所要涉及配置三个功能方面的参数: ALS,IR,PS。分别表示环境光传感器,红外灯,距离传感器。

大体需要配置的寄存器地址如下:

2.  AP3216C 传感器代码

在 之前 I2C主控代码工程下继续编写。

/bsp/ 目录下创建 /ap3216c 目录,在 /ap3216c 目录下创建两个文件:bsp_ap3216c.h 与  bsp_ap3216c.c文件。

bsp_ap3216c.h文件代码如下:

#ifndef      _BSP_AP3216C_H_
#define      _BSP_AP3216C_H_

#include "imx6ull.h"

//ap3216c设备地址
#define   AP3216C_DEVICE_ADDR  0X1E

/* AP3316C寄存器 */
#define AP3216C_SYSTEMCONG	0x00	/* 配置寄存器 */
#define AP3216C_INTSTATUS	0X01	/* 中断状态寄存器 */
#define AP3216C_INTCLEAR	0X02	/* 中断清除寄存器 */
#define AP3216C_IRDATALOW	0x0A	/* IR数据低字节 */
#define AP3216C_IRDATAHIGH	0x0B	/* IR数据高字节 */
#define AP3216C_ALSDATALOW	0x0C	/* ALS数据低字节 */
#define AP3216C_ALSDATAHIGH	0X0D	/* ALS数据高字节 */
#define AP3216C_PSDATALOW	0X0E	/* PS数据低字节 */
#define AP3216C_PSDATAHIGH	0X0F	/* PS数据高字节 */


unsigned char ap3216c_init(void);
unsigned char ap3216c_read_one_byte(unsigned char slave_addr, unsigned char register_addr);
unsigned char ap3216c_write_one_byte(unsigned char slave_addr, unsigned char register_addr, int data);
void ap3216c_read_device_param(unsigned short* ir, unsigned short* ps, unsigned short* als);
#endif

bsp_ap3216c.c 文件的代码如下:

#include "bsp_ap3216c.h"
#include "bsp_i2c.h"
#include "bsp_gpio.h"
#include "bsp_delay.h"
#include "stdio.h"

/*初始化ap3216C*/
unsigned char ap3216c_init(void)
{
    int value = 0;
    //1. IO初始化
    IOMUXC_SetPinMux(IOMUXC_UART4_TX_DATA_I2C1_SCL, 1); //复用为I2C1_SCL功能
    IOMUXC_SetPinMux(IOMUXC_UART4_RX_DATA_I2C1_SDA, 1); //复用为I2C1_SDA功能
    
	IOMUXC_SetPinConfig(IOMUXC_UART4_TX_DATA_I2C1_SCL, 0x70B0); //设置电气属性      
	IOMUXC_SetPinConfig(IOMUXC_UART4_RX_DATA_I2C1_SDA, 0x70B0); //设置电气属性

    //2. I2C接口初始化
    i2c_init(I2C1);
  
    //3. ap3216c传感器初始化
    ap3216c_write_one_byte(AP3216C_DEVICE_ADDR, AP3216C_SYSTEMCONG, 0x04); //复位
    delayms(50);
    ap3216c_write_one_byte(AP3216C_DEVICE_ADDR, AP3216C_SYSTEMCONG, 0x03);
    value = ap3216c_read_one_byte(AP3216C_DEVICE_ADDR, AP3216C_SYSTEMCONG);
    if(value == 0X03) //AP3216C数据写入成功
    {
        return 0;
    }
    else  //AP3216C数据写入失败
    {
        return 1;
    }
}

/*读取ap3216c从设备寄存器的一个字节数据*/
//return: 读取到的值
unsigned char ap3216c_read_one_byte(unsigned char slave_addr, unsigned char register_addr)
{
    unsigned char value = 0;
    struct i2c_transfer master_xfer;
    
    master_xfer.direction = kI2C_Read;
    master_xfer.slaveAddress = slave_addr;
    master_xfer.subaddress = register_addr;
    master_xfer.subaddressSize = 1; //寄存器地址:一个字节
    master_xfer.data = &value;
    master_xfer.dataSize = 1; //读一个字节数据

    i2c_master_transfer(I2C1, &master_xfer);

    return value;
}

/*向ap3216c从设备寄存器地址,写一个字节的数据*/
//return: 错误类型 
unsigned char ap3216c_write_one_byte(unsigned char slave_addr, unsigned char register_addr, int data)
{
    unsigned char write_data = data; 
    int status = 0;
    struct i2c_transfer master_xfer;

    master_xfer.direction = kI2C_Write;
    master_xfer.slaveAddress = slave_addr;
    master_xfer.subaddress = register_addr;
    master_xfer.subaddressSize = 1;
    master_xfer.data = &write_data;
    master_xfer.dataSize = 1;
      
    status = i2c_master_transfer(I2C1, &master_xfer);
    return status;
}

/*AP3216C读取IR数据,PS数据,ALS数据 */
//IR: 红外灯
//PS: 距离传感器
//ALS: 环境光传感器
void ap3216c_read_device_param(unsigned short* ir, unsigned short* ps, unsigned short* als)
{
    int i = 0;
    unsigned char buffer[8] = { 0 };

    for(i=0; i<6; i++)
    {
        buffer[i] = ap3216c_read_one_byte(AP3216C_DEVICE_ADDR, AP3216C_IRDATALOW+i);
    }

    if(buffer[0] & 0x80) //IR数据与PS数据无效
    {
        *ir = 0;
        *ps = 0;
    }
    else
    {
        *ir = (buffer[1] << 2) | (buffer[0] & 0x03);
        *ps = ((buffer[5] & 0x3F) << 4) | (buffer[4] & 0x0F);
    }

    *als = (buffer[3] << 8) | buffer[2];
}

主函数中轮询读取 AP3216C传感器的参数值。main.c文件代码如下:

#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_led.h"
#include "bsp_beep.h"
#include "bsp_key.h"
#include "bsp_int.h"
#include "bsp_uart.h"
#include "bsp_rtc.h"
#include "stdio.h"
#include "bsp_lcd.h"
#include "bsp_lcdapi.h"
#include "bsp_i2c.h"
#include "bsp_ap3216c.h"

int main(void)
{
	unsigned char state = OFF;
    unsigned short ir = 0, ps = 0, als = 0;

	int_init();       /* 初始化中断(一定要最先调用!) */
	imx6u_clkinit();  /* 初始化系统时钟 			*/
	delay_init();	  /* 初始化延时 			*/
	clk_enable();	  /* 使能所有的时钟 			*/
	led_init();		  /* 初始化led 			*/
	beep_init();      /* 初始化beep	 		*/
	uart_init();      /* 初始化串口,波特率115200 */
    rtc_init();       /* RTC时钟初始化      */
    ap3216c_init();   /* ap3216c初始化 */

    while(ap3216c_init()) //AP3216C检测不到
    {
        printf("AP3216C Check Failed!
");
        delayms(500);
    }

	while(1)				
	{
        ap3216c_read_device_param(&ir, &ps, &als);
        printf("AP3216C: ir: %d  ps: %d  als: %d
", ir, ps, als);

		state = !state;
		led_switch(LED0, state);
		delayms(500);
	}
	return 0;
}

I2C实验学习完成。

I2C实验:I2C实验中,是主控制器(即IMX6ULL芯片)与 从设备AP3216C传感器之间的通信。

IMX6ULL作为主设备,AP3216C传感器作为从设备,通过 I2C总线进行通信。

主要实现部分:

1. 主控制器的 I2C初始化,I2C的读、写数据。

2.  AP3216C传感器器件的初始化,读数据、写数据。

其实这里读数据、写数据接口都是调用了第一步中的 I2C读写接口。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。