前言
本文继续介绍I2C使用设备,带I2C该方法可用于接口传感器,只需根据特定的通信协议进行简单的修改。
I2C本文直接介绍了设备的介绍和具体的使用方法I2C访问AP3216的过程
一、光传感器AP3216简介
AP3216C它是敦南科技退出的三合一环境传感器,包括:数字环境光传感器(ALS)、接近传感器(PS)和一个红外LED(IR)。该芯片通过IIC接口和MCU连接,支持中断(INT)输出。 AP3216内部结构如图所示: 引脚说明: AP3216C与MCU只需要连接SCL、SDA和INT,可实现驱动SCL和SDA同24C02共用,连接在PH4和PH5上,INT脚连接在PCF8574的P1上。 AP3216寄存器的位置定义及其功能描述: AP3216的操作有写读两种模式。写作模式主要配置其系统模式。读取模式是读取传感器数据MCU中。 写模式的时序,比较简单,先写地址(0X1E),然后是结存器地址 寄存器内容: 阅读模式比较复杂,这个过程除了阅读操作还有写作操作,当时序列 先写从机地址 寄存器地址,然后读取操作,从机器地址 寄存器。
二、AP3216操作实例
i2c以上访问方法较少,这里不做太多解释,直接给出实例代码
#include <rtthread.h> #include <board.h> #include <rtdevice.h> #define AP_IIC_DEV_NAME "i2c1" #define AP_IIC_ADD 0x1E static struct rt_i2c_bus_device *i2c_bus=RT_NULL; static struct rt_thread thread1; static char thread1_stack[2048]; static rt_err_t ap3216_write(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t data)////根据通信协议编写相应的写作操作 {
struct rt_i2c_msg msgs; rt_uint16_t buf_size=1; rt_uint8_t send_buf[2]; send_buf[0]=reg; if(data!=RT_NULL) {
send_buf[1]=data; buf_size=2; } msgs.addr=AP_IIC_ADD; msgs.buf=send_buf; msgs.flags=RT_I2C_WR; msgs.len=buf_size; if(rt_i2c_transfer(bus, &msgs, buf_size)==1) return RT_EOK; else return -RT_ERROR; } static rt_err_t ap3216_read(struct rt_i2c_bus_device *bus,rt_uint8_t reg, rt_uint8_t *buf)//根据通信协议编写相应的读操作 {
struct rt_i2c_msg msgs[2]; msgs[0].addr=AP_IIC_ADD; msgs[0].buf=® msgs[0].flags=RT_I2C_WR; msgs[0].len=1; msgs[1].addr=AP_IIC_ADD; msgs[1].buf=buf; msgs[1].flags=RT_I2C_RD; msgs[1].len=1; if(rt_i2c_transfer(bus, msgs, 2)==2) return RT_EOK; else return -RT_ERROR; } static rt_err_t ap3216_init(void) {
rt_uint8_t temp; rt_uint8_t addr; rt_uint8_t data; addr=0x00; data=0x04; ap3216_write(i2c_bus,addr,data);//重启传感器 rt_thread_mdelay(50); data=0x03; ap3216_write(i2c_bus,addr,data);//开启ALS、PS+IR rt_thread_mdelay(50); ap3216_read(i2c_bus,addr, &temp); if(temp == 0x03) return RT_EOK; else{
rt_kprintf("init failed\n"); return -RT_ERROR; } } rt_uint16_t ir, als, ps; static void ap3216_entry(void *parameter) {
rt_uint8_t i; rt_uint8_t buf[6]; i2c_bus=(struct rt_i2c_bus_device *)rt_device_find(AP_IIC_DEV_NAME); if(i2c_bus==RT_NULL) {
rt_kprintf("can't find s% device!\n",AP_IIC_DEV_NAME); return; } else rt_kprintf("find s%!\n",AP_IIC_DEV_NAME); ap3216_init(); while(1){
for(i = 0; i < 6; i++){
ap3216_read(i2c_bus,0x0A+i, buf+i); } if(buf[0] & 0x80) ir=0; //IR_OF位为1,则数据无效 else ir=((rt_uint16_t)buf[1]<<2)|(buf[0]&0x03); //读取IR传感器的数据 als=((rt_uint16_t)buf[3]<<8)|buf[2]; //读取ALS传感器的数据 if(buf[4]&0x40) ps=0; //IR_OF位为1,则数据无效 else ps=((rt_uint16_t)(buf[5] & 0x3F)<<4)|(buf[4]&0x0F); //读取PS传感器的数据 rt_kprintf("%d\t",ir); rt_kprintf("%d\t",als); rt_kprintf("%d\t\n",ps); rt_thread_mdelay(500); } } int ap_thread_init(void) {
rt_thread_init(&thread1,"ap3216_thread", ap3216_entry, RT_NULL, &thread1_stack[0], sizeof(thread1_stack), 20, 10); rt_thread_startup(&thread1); return 0; }
总结
I2C访问传感器的过程,重点是其读操作过程,需要根据特定的传感器协议编写代码。