ITPub博客

首页 > 嵌入式/内核开发 > 嵌入式/内核开发 > 《STM32H562开发指南 V1.0 》第三十三章 光环境传感器实验

《STM32H562开发指南 V1.0 》第三十三章 光环境传感器实验

原创 嵌入式/内核开发 作者:正点原子 时间:2025-12-08 11:07:23 0 删除 编辑

第三十三章 光环境传感器实验


       本章,我们将给大家介绍如何使用IIC来驱动光环境传感器。在本章中,我们将使用STM32H5的普通IO口模拟IIC时序,来驱动AP3216C,从而检测环境光强度(ALS)、接近距离(PS)和红外线强度(IR)等环境参数。

       本章分为如下几个小节:

       33.1 光敏传感器简介

       33.2 硬件设计

       33.3 程序设计

       33.4 下载验证


        33.1 AP3216C简介

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

       ·IIC接口,支持高达400KHz通信速率

       ·支持多种工作模式(ALS、PS+IR、ALS+PS+IR等)

       ·内置温度补偿电路

       ·工作温度支持-30~80℃

       ·环境光传感器具有16位分辨率

       ·接近传感器具有10位分辨率

       ·红外传感器具有10位分辨率

       ·超小封装(4.1*2.4*1.35mm)

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


图33.1.1 AP3216C框图


       1.引脚说明

       AP3216C的引脚说明如表33.1.1所示:


表33.1.1 AP3216C引脚说明


       AP3216C和我们的MCU只需要连接SCL和SDA,就可以实现驱动。其SCL和SDA同24C02共用,连接在PB10和PB3上。关于IIC协议的介绍,请参考IIC实验。


       2.写寄存器

       AP3216C的写寄存器时序如图33.1.2所示:


图33.1.2 AP3216C写寄存器时序


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


       3.读寄存器

       AP3216C的读寄存器时序如图33.1.3所示:


图33.1.3 AP3216C读寄存器时序


       图中,同样是先发送7位地址+写操作,然后再发送寄存器地址,随后,重新发送起始信号(Sr),再次发送7位地址+读操作,然后读取寄存器值。其中:Sr,表示重新发送IIC起始信号;N,表示不对AP3216C进行应答;其他简写同上。


       4.寄存器描述

       AP3216C有一些列寄存器,由这些寄存器来控制AP3216C的工作模式,以及中断配置和数据输出等。这里我们仅介绍我们在本章需要用到的一些寄存器,其他寄存器的描述和说明,请大家参考AP3216C的数据手册。

       本章需要用到AP3216C的寄存器如表33.1.2所示:


表33.1.2 AP3216C相关寄存器及其说明


       上表中,0X00是一个系统模式控制寄存器,主要在初始化的时候配置,初始化的时候,我们先设置其值为100,实行一次软复位,随后设置其值为011,开启ALS+PS+IR检测功能。

       剩下的6个寄存器,为数据寄存器,输出AP3216C内部三个传感器所检测到的数据(ADC值),描述如表所示,这里需要注意的是:读取间隔至少要大于112.5ms,因为,AP3216C内部完成一次ALS+PS+IR的数据转换,需要112.5ms的时间。

       AP3216C的简介,我们就介绍到这里,关于该芯片的详细说明,请大家参考其数据手册。


        33.2 硬件设计


       1. 例程功能

       开机的时候先检测AP3216C是否存在,如检测不到AP3216C,则在LCD屏幕上面显示报错信息。如果检测到AP3216C,则显示正常,并在主循环里面,循环读取ALS+PS+IR的传感器数据,并显示在LCD屏幕上面。同时,DS0闪烁,提示程序正在运行。另外,本例程将AP3216C的读写操作函数加入USMART控制,我们也可以通过USMART对AP3216C进行控制。


       2. 硬件资源


       1)LED灯   

              LED0 – PB4

       2)串口1(PA9/PA10连接在板载USB转串口芯片CH340上面)

       3)正点原子2.8/3.5/4.3/7寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)

       4)定时器4

       5)AP3216C(通过IIC接口连接)

              IIC_SCL - PB10

              IIC_SDA - PB3


       3. 原理图

       我们主要来看看光环境传感器和开发板的连接,如下图所示:


图33.2.1 光敏传感器与开发板连接示意图


       这里需要说明一下:AP3216C的AP_INT脚是悬空的,所以不能使用AP3216C的中断输出功能。本实验,我们并没有用到AP3216C的中断功能。


        33.3 程序设计 


       33.3.1 程序流程图


图33.3.1.1 光敏传感器实验程序流程图


       33.3.2 程序解析


       1. AP3216C驱动代码

       这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。AP3216C驱动源码包括两个文件:ap3216c.c和ap3216.h。

       ap3216c.h头文件代码非常简单,主要是函数声明以及宏定义标识符,这里大家只需要注意,宏定义标识符AP3216C_ADDR配置的是器件AP3216C的IIC地址。

       下面介绍ap3216c.c文件的函数,定义如下:

/**
 * @brief       初始化AP3216C
 * @param       无
 * @retval      0, 成功;
                  1, 失败;
 */
uint8_t ap3216c_init(void)
{
    uint8_t temp = 0;
 
    iic_init();                            /* 初始化IIC */
 
    ap3216c_write_one_byte(0x00, 0X04);   /* 复位AP3216C */
    delay_ms(50);                          /* AP33216C复位至少10ms */
    ap3216c_write_one_byte(0x00, 0X03);   /* 开启ALS、PS+IR    */
    temp = ap3216c_read_one_byte(0X00);   /* 读取刚刚写进去的0X03 */
 
    if (temp == 0X03)return 0;             /* AP3216C正常 */
    else return 1;                         /* AP3216C失败 */
} 
 
/**
 * @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 buf[6];
    uint8_t i;
 
    for (i = 0; i < 6; i++)
    {
        buf[i] = ap3216c_read_one_byte(0X0A + i);  /* 循环读取所有传感器数据 */
    }
 
    if (buf[0] & 0X80)
    {
        *ir = 0;                                           /* IR_OF位为1,则数据无效 */
    }
    else 
    {
        *ir = ((uint16_t)buf[1] << 2) | (buf[0] & 0X03); /* 读取IR传感器的数据   */
    }
 
    *als = ((uint16_t)buf[3] << 8) | buf[2];       /* 读取ALS传感器的数据   */ 
 
    if (buf[4] & 0x40) 
    {
        *ps = 0;                                          /* IR_OF位为1,则数据无效 */
    }
    else
{
/* 读取PS传感器的数据 */
        *ps = ((uint16_t)(buf[5] & 0X3F) << 4) | (buf[4] & 0X0F);  
    }
}
 
/**
 * @brief       AP3216C写入一个字节
 * @param       reg     : 寄存器地址
 * @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);   /* 发送器件地址+写命令 */
 
    if (iic_wait_ack())                    /* 等待应答 */
    {
        iic_stop();
        return 1;
    }
 
    iic_send_byte(reg);           /* 写寄存器地址 */
    iic_wait_ack();              /* 等待应答 */
    iic_send_byte(data);         /* 发送数据 */
 
    if (iic_wait_ack())        /* 等待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 res;
 
    iic_start();
    iic_send_byte(AP3216C_ADDR | 0X00);  /* 发送器件地址+写命令 */
    iic_wait_ack();                       /* 等待应答 */
    iic_send_byte(reg);                   /* 写寄存器地址 */
    iic_wait_ack();                       /* 等待应答 */
    iic_start();                
    iic_send_byte(AP3216C_ADDR | 0X01);  /* 发送器件地址+读命令 */
    iic_wait_ack();                       /* 等待应答 */
    res = iic_read_byte(0);               /* 读数据,发送nACK   */
    iic_stop();                           /* 产生一个停止条件 */
 
    return res;  
}

       该部分为AP3216C的驱动代码,其中的IIC相关函数,直接是用第三十六章myiic.c里面提供的相关函数,这里不做介绍。

       这里总共有4个函数:ap3216c_init函数用于初始化并检测AP3216C,先设置AP3216C软复位,随后设置其工作在ALS+PS+IR模式,通过对系统模式寄存器的读写操作,来判断AP3216C是否正常(在位);ap3216c_write_one_byte和ap3216c_read_one_byte这两个函数实现AP3216C的寄存器写入和读取功能;ap3216c_read_data函数,则用于读取ALS+PS+IR传感器的数据,一般我们只需要调用该函数获取数据即可。


       2. main.c代码

       在main.c里面编写如下代码:

int main(void)
{
    uint16_t ir, als, ps;
 
    HAL_Init();                                    /* HAL库初始化 */
    HAL_ICACHE_Enable();                         /* 使能指令缓存 */
    sys_stm32_clock_init(250, 4, 2, 2);         /* 系统时钟初始化, 250Mhz */
    delay_init(250);                                /* 延时初始化 */
    usart_init(115200);                          /* 串口初始化 */
    usmart_dev.init(250);                        /* USMART初始化 */
    led_init();                                       /* LED初始化 */
    lcd_init();                                     /* LCD初始化 */
 
    lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "AP3216C TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
 
    while (ap3216c_init())                       /* 检测不到AP3216C */
    {
        lcd_show_string(30, 130, 200, 16, 16, "AP3216C Check Failed!", RED);
        delay_ms(500);
        lcd_show_string(30, 130, 200, 16, 16, "Please Check!      ", RED);
        delay_ms(500);
        LED0_TOGGLE();                            /* 红灯闪烁 */
    }
 
    lcd_show_string(30, 130, 200, 16, 16, "AP3216C Ready!", RED);
    lcd_show_string(30, 160, 200, 16, 16, " IR:", RED);
    lcd_show_string(30, 180, 200, 16, 16, " PS:", RED);
    lcd_show_string(30, 200, 200, 16, 16, "ALS:", RED);
 
    while (1)
    {
        ap3216c_read_data(&ir, &ps, &als);             /* 读取数据  */
        lcd_show_num(30 + 32, 160, ir, 5, 16, BLUE);    /* 显示IR数据 */
        lcd_show_num(30 + 32, 180, ps, 5, 16, BLUE);    /* 显示PS数据 */
        lcd_show_num(30 + 32, 200, als, 5, 16, BLUE);    /* 显示ALS数据  */
 
        LED0_TOGGLE();                                        /* 提示系统正在运行 */
        delay_ms(120); 
    }
}

       该部分的代码逻辑很简单,初始化各个外设之后,进入死循环,通过调用ap3216c_read_data函数,读取ALS+PS+IR的数据,并显示在LCD上面。同时,DS0闪烁,提示程序正在运行。这里我们延时120ms读取一次,确保ALS+PS+IR的转换全部完成,以保证数据正常。


        33 .4 下载验证

       将程序下载到开发板后,可以看到LED0不停的闪烁,提示程序已经在运行了。LCD显示的内容如图33.4.1所示:


图33.4.1 光环境传感器实验测试图


       我们可以用手遮挡/靠近AP3216C传感器,可以看到三个传感器的数据变化,说明我们的代码是工作正常的。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70040860/viewspace-3104632/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2024-08-30

  • 博文量
    588
  • 访问量
    763844