实验目标:
硬件:STM32MP157AAA开发板+拓展板
管脚:拓展板光照,红外,接近传感器(AP3216C)I2C1_SCL对应核心板PF14,I2C1_SDA对应核心板PF15,可知从机地址为0X1E。
梳理:
I2C各信号下SCL与SDA的机制可查看STM32MP157AAA开发板通过GPIO实现模拟I2C驱动获取温湿度传感器数据-CSDN博客
光照,红外,接近传感器(AP3216C)的地址通过其数据手册可查,其中功能码0X00对应系统模式,共8种模式,因此定义两个enum用于配置功能码和模式:
#ifndef __AP3216C_H_
#define __AP3216C_H_
#include "iic.h"
#include "delay.h"
#define AP3216C_SLAVE_ADDRESS 0X1E
enum
{
System_Configuration , //Control of basic functions
Interrupt_Status , //ALS and PS interrupt status output
INT_Clear_Manner , //Auto/semi clear INT pin selector
IR_Data_Low = 0X0A, //Lower byte for IR ADC channel output
IR_Data_High, //Higher byte for IR ADC channel output
ALS_Data_Low , //Lower byte for ALS ADC channel output
ALS_Data_High , //Higher byte for ALS ADC channel output
PS_Data_Low , //Lower byte for PS ADC channel output
PS_Data_High , //Higher byte for PS ADC channel output
ALS_Configuration , //Control of gain, conversion time of persist for ALS
ALS_Calibration = 0X19, //ALS window loss calibration
ALS_Low_Threshold7 , //Lower byte of ALS low threshold
ALS_Low_Threshold15, // Higher byte of ALS low threshold
ALS_High_Threshold7 , //Lower byte of ALS high threshold
ALS_High_Threshold15, // Higher byte of ALS high threshold
PS_Configuration = 0X20, //Control of gain, integrated time and persist for PS
PS_LED_Driver , //Control of LED pulses number and driver current
PS_INT_Form , //Interrupt algorithms style select of PS
PS_Mean_Time , //PS average time selector
PS_LED_Waiting_Time , //Control PS LED waiting time
PS_Calibration_L = 0x28 , //Offset value to eliminate cross talk
PS_Calibration_H , //Offset value to eliminate cross talk
PS_Low_Threshold2 , //Lower byte of PS low threshold
PS_Low_Threshold10 , //Higher byte of PS low threshold
PS_High_Threshold2 , //Lower byte of PS high threshold
PS_High_Threshold10 //Higher byte of PS high threshold
};
enum
{
POWER_DOWN, //000: Power down (Default)
ALS_ACT, //001: ALS function active
PS_IR_ACT, //010: PS+IR function active
ALS_PS_IR_ACT, //011: ALS and PS+IR functions active
SW_RESET, //100: SW reset
ALS_ONCE, //101: ALS function once
PS_IR_ONCE, //110: PS+IR function once
ALS_PS_IR_ONCE //111: ALS and PS+IR functions once
};
void ap3216c_init(); //初始化光照,红外,接近传感器(AP3216C)
short ap3216c_read_IR(); //读取红外数据
short ap3216c_read_ALS(); //读取光照数据
short ap3216c_read_PS(); //读取距离数据
#endif
初始化光照,红外,接近传感器(AP3216C)设置为ALS_ACT模式:
#include "ap3216c.h"
//初始化光照,红外,接近传感器(AP3216C)
void ap3216c_init()
{
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|0);//从机地址0X1E,W写标志=0
i2c_wait_ack();
i2c_write_byte(System_Configuration); //设置传感器寄存器0X00为ALS模式
i2c_wait_ack();
i2c_write_byte(ALS_ACT); //设置用户寄存器初始化
i2c_wait_ack();
i2c_stop();
}
读取光照数据:
//读取光照数据
short ap3216c_read_ALS()
{
short als;
char als1, als2;
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|0);//从机地址0X1E,W写标志=0
i2c_wait_ack();
i2c_write_byte(ALS_Data_Low); //先读低8bits功能码0X0A
i2c_wait_ack();
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|1);//从机地址0X1E,R读标志=1
i2c_wait_ack();
delay(1);
als1 = i2c_read_byte(1); //读取红外低8bits
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|0);//从机地址0X1E,W写标志=0
i2c_wait_ack();
i2c_write_byte(ALS_Data_High); //再读高8bits功能码0X0B
i2c_wait_ack();
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|1);//从机地址0X1E,R读标志=1
i2c_wait_ack();
als2 = i2c_read_byte(1); //读取红外高8bits
i2c_stop();
als = als2<<8|als1;
return als;
}
函数调用:
#include "iic.h"
#include "ap3216c.h"
int main()
{
i2c_init();
ap3216c_init();
short als;
while(1)
{
als = ap3216c_read_ALS();
printf("als = %d\n", als);
delay(1);
}
return 0;
}
ALS_ACT模式下只读取光照数据的代码运行结果:
初始化光照,红外,接近传感器(AP3216C)设置为PS_IR_ACT模式:
#include "ap3216c.h"
//初始化光照,红外,接近传感器(AP3216C)
void ap3216c_init()
{
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|0);//从机地址0X1E,W写标志=0
i2c_wait_ack();
i2c_write_byte(System_Configuration); //设置传感器寄存器0X00为ALS模式
i2c_wait_ack();
i2c_write_byte(PS_IR_ACT); //设置用户寄存器初始化
i2c_wait_ack();
i2c_stop();
}
读取IR红外数据和PS距离数据:
//读取红外数据
short ap3216c_read_IR()
{
short ir;
char ir1, ir2;
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|0);//从机地址0X1E,W写标志=0
i2c_wait_ack();
i2c_write_byte(IR_Data_Low); //先读低8bits功能码0X0A
i2c_wait_ack();
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|1);//从机地址0X1E,R读标志=1
i2c_wait_ack();
delay(1);
ir1 = i2c_read_byte(1); //读取红外低8bits
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|0);//从机地址0X1E,W写标志=0
i2c_wait_ack();
i2c_write_byte(IR_Data_High); //再读高8bits功能码0X0B
i2c_wait_ack();
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|1);//从机地址0X1E,R读标志=1
i2c_wait_ack();
ir2 = i2c_read_byte(1); //读取红外高8bits
i2c_stop();
ir = ir2<<2|(ir1&0X3);
return ir;
}
//读取距离数据
short ap3216c_read_PS()
{
short PS;
char PS1, PS2;
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|0);//从机地址0X1E,W写标志=0
i2c_wait_ack();
i2c_write_byte(PS_Data_Low); //先读低8bits功能码0X0E
i2c_wait_ack();
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|1);//从机地址0X1E,R读标志=1
i2c_wait_ack();
delay(1);
PS1 = i2c_read_byte(1); //读取红外低8bits
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|0);//从机地址0X1E,W写标志=0
i2c_wait_ack();
i2c_write_byte(PS_Data_High); //再读高8bits功能码0X0F
i2c_wait_ack();
i2c_start();
i2c_write_byte(AP3216C_SLAVE_ADDRESS<<1|1);//从机地址0X1E,R读标志=1
i2c_wait_ack();
PS2 = i2c_read_byte(1); //读取红外高8bits
i2c_stop();
PS = ((PS2&0X3F)<<4)|(PS1&0XF);
return PS;
}
函数调用:
#include "iic.h"
#include "ap3216c.h"
int main()
{
i2c_init();
ap3216c_init();
//short als;
short ir;
short ps;
while(1)
{
//als = ap3216c_read_ALS();
//printf("als = %d\n", als);
ir = ap3216c_read_IR();
printf("ir = %d\n", ir);
ps = ap3216c_read_PS();
printf("ps = %d\n", ps);
delay(1);
}
return 0;
}
PS_IR_ACT模式读取红外数据和距离数据的代码运行结果,从数据手册上可看出如果红外强度过大,会影响PS数据,导致PS数据失效。有一个溢出标志(IR_OF)指示PS数据,看在高红外光下是否有效。如果IR_OF设置为1,设备将强制PS对象状态为离开状态,此处暂不做深度处理。
标签:PS,STM32MP157AAA,IR,开发板,GPIO,byte,AP3216C,ALS,ap3216c From: https://blog.csdn.net/weixin_72755055/article/details/145016011