1199 字
6 分钟
STM32中的I2C通信【AP3216C光传感器】

AP3216C#

简介#

AP3216C 是敦南科技推出的一款三合一环境传感器, 它包含了:数字环境光传感器(ALS)、接近传感器(PS)和一个红外 LED(IR)。该芯片通过 IIC 接口和 MCU 连接,并支持中断(INT)输出。AP3216C 的特点如下:

  • IIC 接口,支持高达 400KHz 通信速率
  • 支持多种工作模式(ALS、PS+IR、ALS+PS+IR 等)
  • 内置温度补偿电路
  • 工作温度支持-30~80℃
  • 环境光传感器具有 16 位分辨率
  • 接近传感器具有 10 位分辨率
  • 红外传感器具有 10 位分辨率
  • 超小封装(4.12.41.35mm)

因为以上一些特性,AP3216C 被广泛应用于智能手机上面,用来检测光强度(自动背光控制),和接近开关控制(听筒靠近耳朵,手机自动灭屏功能)。

写寄存器#

AP3216C写寄存器时序 先发送 AP3216C 的地址(7 位,为0X1E,左移一位后为 0X3C),最低位 W=0 表示写数据,随后发送 8 位寄存器地址,最后发送 8 位寄存器值。其中:S,表示 IIC 起始信号;W,表示读/写标志位(W=0 表示写,W=1 表示读);A,表示应答信号;P,表示 IIC 停止信号。

读寄存器#

AP3216C寄存器说明

注意:AP3216C的读取间隔至少需要大于112.5ms(一次ALS+PS+IR转换的时间)

工程#

ap3216c.h#

#include "sys.h"
#include "main.h"
#ifndef __AP3216C_H
#define __AP3216C_H
#define AP3216C_ADDR 0x3C /* 原设备地址为0x1E,左移一位为0x3C*/
#endif
uint8_t ap3216c_init(void);
uint8_t ap3216c_write_one_byte(uint8_t reg, uint8_t data);
uint8_t ap3216c_read_one_byte(uint8_t reg);
void ap3216c_read_data(uint16_t *ir, uint16_t *ps, uint16_t *als);

ap3216c.c#

#include "main.h"
#include "sys.h"
#include "ap3216c.h"
#include "custom_i2c.h"
#include "delay.h"
/**
* @brief 初始化 AP3216C
* @param 无
* @retval 返回值:0,初始化成功; 1,初始化失败
*/
uint8_t ap3216c_init(void)
{
uint8_t temp = 0;
iic_init();
ap3216c_write_one_byte(0x00, 0x04); /* 软复位AP3216C */
delay_ms(50); /* IC复位至少需要11.5ms */
ap3216c_write_one_byte(0x00, 0x03); /* ALS+PS+IR功能激活 */
temp = ap3216c_read_one_byte(0x00); /* 读取刚刚写入的0x03指令 */
if (temp == 0x03) return 0; /* IC初始化成功 */
else return 1; /* IC初始化失败 */
}
/**
* @brief AP3216C 写入一个字节
* @param reg : AP3216C目标寄存器地址
* @param data : 待写入数据
* @retval 0, 成功;
1, 失败;
*/
uint8_t ap3216c_write_one_byte(uint8_t reg, uint8_t data)
{
iic_start();
iic_send_byte(AP3216C_ADDR | 0x00); /* 发送设备地址,最低位为0,写命令 */
if (iic_wait_ack()) /* 等待应答*/
{
iic_stop(); /* 等待应答失败则直接停机 */
return 1;
}
iic_send_byte(reg); /* 发送目标寄存器地址(指针)*/
iic_wait_ack(); /* 等待应答 */
iic_send_byte(data); /* 发送待写入数据 */
if (iic_wait_ack()) /* 等待应答*/
{
iic_stop(); /* 等待应答失败则直接停机 */
return 1;
}
iic_stop();
return 0;
}
/**
* @brief AP3216C 读取一个字节
* @param reg : 待读取寄存器地址
* @retval 读到的数据
*/
uint8_t ap3216c_read_one_byte(uint8_t reg)
{
uint8_t result;
iic_start();
iic_send_byte(AP3216C_ADDR | 0x00); /* 发送设备地址,最低位为0,写命令*/
iic_wait_ack();
iic_send_byte(reg); /* 发送待读取寄存器地址 */
iic_wait_ack();
iic_start(); /* 准备开始读取,重新启动IIC以切换模式 */
iic_send_byte(AP3216C_ADDR | 0x01); /* 发送设备地址,最低位为1,读命令*/
iic_wait_ack();
result = iic_read_byte(0); /* 读取一个字节,读完后发送NACK,表示读取结束 */
iic_stop();
return result; /* 返回读取结果 */
}
/**
* @brief 读取 AP3216C 的数据
* @note 读取原始数据,包括 ALS,PS 和 IR
* 如果同时打开 ALS,IR+PS 的话两次数据读取的时间间隔要大于 112.5ms
* @param ir : IR 传感器值
* @param ps : PS 传感器值
* @param als : ALS 传感器值
* @retval 无
*/
void ap3216c_read_data(uint16_t *ir, uint16_t *ps, uint16_t *als)
{
uint8_t rx_buf[6]; /* 读取缓冲区 */
uint8_t i;
for (i = 0; i < 6; i++) /* 循环6次以读取6个寄存器的值 */
{
rx_buf[i] = ap3216c_read_one_byte(0x0A + i);
}
/* 提取IR传感器值 */
if (rx_buf[0] & 0x80) /* 判断IR第7位是否为1 */
{
*ir = 0; /* 第7位若为1则IR数据无效 */
}
else
{
/* rx_buf[1] << 2:0x0B(IR高位)数据左移2位,给低位数据留出空余*/
/* rx_buf[0] & 0x03:提取0x0A(IR低位)数据的第0位和第1位,也就是IR的最低2位*/
/* 二者进行或运算得到IR的最终值 */
*ir = ((uint16_t)rx_buf[1] << 2) | (rx_buf[0] & 0x03);
}
/* 提取ALS传感器值 */
*als = rx_buf[2] | ((uint16_t)rx_buf[3] << 8);
/* 提取PS传感器值 */
if (rx_buf[4] & 0x40) /* 判断0x0E第6位是否为1*/
{
*ps = 0; /* PS数据无效 */
}
else
{
/* (rx_buf[4] & 0x0F):取0x0E的3:0位,也就是PS的低4位 */
/* ((uint16_t)(rx_buf[5] & 0x3F) << 4):取0x0F的5:0位然后左移4位,给低4位留位置 */
/* 二者进行或运算得到PS的最终值 */
*ps = ((uint16_t)(rx_buf[5] & 0x3F) << 4) | (rx_buf[4] & 0x0F);
}
}

main.c#

/* USER CODE BEGIN 2 */
while (ap3216c_init()) /* AP3216C初始化失败 */
{
uint8_t txbuf[] = "ap3216c init failed!\n";
HAL_UART_Transmit_IT(&huart1, txbuf, sizeof(txbuf));
led_red(1);
}
/* USER CODE END 2 */
while (1)
{
/* USER CODE END WHILE */
ap3216c_read_data(&ir, &ps, &als);
uint8_t txbuf[23];
sprintf(txbuf, "ir:%d, ps:%d, als:%d\r\n", ir, ps, als);
HAL_UART_Transmit_IT(&huart1, (uint8_t *)txbuf, sizeof(txbuf));
led_green_toggle();
delay_ms(120); /* 延时120ms以保证AP3216C采样正确 */
/* USER CODE BEGIN 3 */
}

测试#

串口打印结果

STM32中的I2C通信【AP3216C光传感器】
https://arkmostima.pages.dev/posts/stm32中的i2c通信ap3216c光传感器/
作者
Aki
发布于
2024-12-13
许可协议
CC BY-NC-SA 4.0