搜索
bottom↓
回复: 0

《ESP32-S3使用指南—MicroPython版 V1.0》第二十章 光环境传感器实验

[复制链接]

出0入234汤圆

发表于 3 天前 | 显示全部楼层 |阅读模式
2.jpg
1)实验平台:正点原子ESP32S3开发板
2)购买链接:https://detail.tmall.com/item.htm?id=768499342659
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-347618-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子手把手教你学ESP32S3快速入门视频教程:https://www.bilibili.com/video/BV1sH4y1W7Tc
6)正点原子FPGA交流群:132780729
1.png
3.png

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


       上一章,我们介绍了IIC驱动XL9555,本章我们将向大家介绍如何使用IIC来驱动光环境传感器。在本章中,作者将使用MicroPython 程序来驱动AP3216C,从而检测环境光强度(ALS)、接近距离(PS)和红外线强度(IR)等环境参数。
       本章分为如下几个小节:
       20.1 光敏传感器简介
       20.2 AP3216C C模块解析
       20.3 硬件设计
       20.4 程序设计
       20.5 下载验证

       20.1 光敏传感器简介
       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的框图如下图所示。

第二十章 光环境传感器实验573.png
图20.1.1 AP3216C框图

       1,引脚说明
       AP3216C的引脚说明如下表所示。

1.png
表20.1.1 AP3216C引脚说明

       AP3216C和我们的MCU只需要连接SCL、SDA和INT,就可以实现驱动。其SCL和SDA同24C02共用,连接在IO41和IO42上,INT脚连接在XL9555的P0_0上,见图14.2.1。关于IIC协议的介绍,请参考IO扩展实验。

       2,写寄存器
       AP3216C的写寄存器时序如下图所示。

第二十章 光环境传感器实验941.png
图20.1.2 AP3216C写寄存器时序

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

       3,读寄存器
       AP3216C的读寄存器时序如下图所示。

第二十章 光环境传感器实验1129.png
图20.1.3 AP3216C读寄存器时序

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

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

2.png
表20.1.2 AP3216C相关寄存器及其说明

       上表中,0X00是一个系统模式控制寄存器,主要在初始化的时候配置,初始化的时候,我们先设置其值为100,实行一次软复位,随后设置其值为011,开启ALS+PS+IR检测功能。
       剩下的6个寄存器,为数据寄存器,输出AP3216C内部三个传感器所检测到的数据(ADC值),描述如表所示,这里需要注意的是:读取间隔至少要大于112.5ms,因为,AP3216C内部完成一次ALS+PS+IR的数据转换,需要112.5ms的时间。
       AP3216C的简介,我们就介绍到这里,关于该芯片的详细说明,请大家参考其数据手册。

       20.2 AP3216C C模块解析

       20.2.1 C模块解析
       作者将简要介绍正点原子AP3216C C模块驱动。这个讲解内容会分为几个部分:AP3216C构造函数、读写数据。AP3216C C模块驱动可在A盘6,软件资料1,软件2,MicroPython开发工具01-Windows2,正点原子MicroPython驱动CModules_LibIIC路径下找到。

       1,AP3216C构造函数
  1. mp_obj_t ap3216c_make_new(const mp_obj_type_t *type,size_t n_args,
  2. size_t n_kw,const mp_obj_t *all_args )
  3. {
  4.     /* 创建对象的参数 */
  5.     enum
  6.     {
  7.         ARG_iic,
  8.     };

  9.     static const mp_arg_t allowed_args[] = {
  10.         { MP_QSTR_iic, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
  11.     };
  12.     mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  13. mp_arg_parse_all_kw_array(n_args, n_kw, all_args,
  14.                           MP_ARRAY_SIZE(allowed_args), allowed_args, args);

  15.     /* 创建对象 */
  16.     ap3216c_self = m_new_obj(ap3216c_obj_t);
  17.     ap3216c_self->base.type = &ap3216c_type;
  18.     /* 设置对象参数 */
  19. mp_obj_base_t *ap3216c_obj   = (mp_obj_base_t*)
  20. MP_OBJ_TO_PTR(args[ARG_iic].u_obj);

  21.     if (ap3216c_obj == MP_OBJ_NULL)
  22.     {
  23.         mp_raise_ValueError(MP_ERROR_TEXT("I2C init ???"));
  24.     }

  25.     ap3216c_self->iic_obj        = ap3216c_obj;
  26.     /* 初始化ap3216c */
  27.     ap3216c_init();
  28.    
  29.     return MP_OBJ_FROM_PTR(ap3216c_self);
  30. }
复制代码
       从这里可以发现,ap3216c的构造函数与xl9555、AT24Cxx的构造函数类似,它们都需要传入IIC控制块,然后调用ap3216c_init函数来初始化光环境传感器。以下是该初始化代码的示例:
  1. /**
  2. * @brief       初始化AP3216C
  3. * @param       无
  4. * @retval      0, 成功;
  5.                 1, 失败;
  6. */
  7. uint8_t ap3216c_comfig(void)
  8. {
  9.     uint8_t temp;
  10.     esp_err_t err;
  11.     int retry = 3;
  12.    
  13.     ap3216c_write_one_byte(0x00, 0X04); /* 复位AP3216C */
  14.     mp_hal_delay_ms(50);                /* AP33216C复位至少10ms */
  15.     ap3216c_write_one_byte(0x00, 0X03); /* 开启ALS、PS+IR */
  16.     ap3216c_read_one_byte(&temp,0X00);  /* 读取刚刚写进去的0X03 */

  17.     if (temp == 0X03)
  18.     {
  19.         ESP_LOGI("AP3216C", "AP3216C success!!!");
  20.         return 0;                       /* AP3216C正常 */
  21.     }
  22.     else
  23.     {
  24.         ESP_LOGE("AP3216C", "AP3216C fail!!!");
  25.         return 1;                       /* AP3216C失败 */
  26.     }
  27. }

  28. /**
  29. * @brief       ap3216c初始化
  30. * @param       无
  31. * @retval      无
  32. */
  33. void ap3216c_init(void)
  34. {   
  35.     while (ap3216c_comfig())            /* 检测不到AP3216C */
  36.     {
  37.         ESP_LOGE("ap3216c", "ap3216c init fail!!!");
  38.         mp_hal_delay_ms(500);
  39.     }
  40. }
复制代码
       我们可以看到,init函数中调用了ap3216c_comfig函数,用于初始化和配置AP3216C光环境传感器模块。在ap3216c_comfig函数中,我们首先复位AP3216C器件,接着,开启ALS、PS和IR检测功能,最后,判断是否写入成功。如果是0x03,则设备通信成功;否则,通信失败。

       2,向ap3216c写入16位IO值
       根据20.1章节的写时序为基准,编写ap3216c光环境传感器写时序代码,如下所示:
  1. /**
  2. * @brief       向ap3216c写入16位IO值
  3. * @param       data:要写入的数据
  4. * @retval      ESP_OK:读取成功;其他:读取失败
  5. */
  6. static esp_err_t ap3216c_write_one_byte(uint8_t reg,uint8_t data)
  7. {
  8.     int data_len = 0;
  9.     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(ap3216c_self->iic_obj);
  10. mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)
  11. MP_OBJ_TYPE_GET_SLOT(self->type, protocol);

  12.     mp_machine_i2c_buf_t bufs[2] = {
  13.         {.len = 1, .buf = ®},
  14.         {.len = 1, .buf = &data},
  15.     };

  16. data_len=i2c_p->transfer(self, AP3216C_ADDR,2,
  17. bufs,MP_MACHINE_I2C_FLAG_STOP);
  18.    
  19.     if (data_len != 0)
  20.     {
  21.         return ESP_OK;
  22.     }
  23.     else
  24.     {
  25.         return ESP_FAIL;
  26.     }
  27. }
复制代码
       在上述源代码中,作者根据传入的IIC控制块,调用了IIC收发函数来发送AP3216C的命令和数据。发送完成后,函数返回了ESP_OK状态。

       3,读取ap3216c的16位IO值
       根据20.1章节的读时序为基准,编写ap3216c光环境传感器读时序代码,如下所示:
  1. /**
  2. * @brief       读取ap3216c的16位IO值
  3. * @param       data:存储区
  4. * @param       reg :寄存器
  5. * @retval      ESP_OK:读取成功;其他:读取失败
  6. */
  7. static esp_err_t ap3216c_read_one_byte(uint8_t* data,uint8_t reg)
  8. {
  9.     int data_len = 0;
  10.     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(ap3216c_self->iic_obj);
  11. mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)
  12. MP_OBJ_TYPE_GET_SLOT(self->type, protocol);

  13.     mp_machine_i2c_buf_t bufs[2] = {
  14.         {.len = 1, .buf = ®},
  15.         {.len = 1, .buf = data},
  16.     };

  17. data_len = i2c_p->transfer(self, AP3216C_ADDR, 2, bufs,
  18. MP_MACHINE_I2C_FLAG_WRITE1
  19. | MP_MACHINE_I2C_FLAG_READ
  20. | MP_MACHINE_I2C_FLAG_STOP);
  21.    
  22.     if (data_len != 0)
  23.     {
  24.         return ESP_OK;
  25.     }
  26.     else
  27.     {
  28.         return ESP_FAIL;
  29.     }
  30. }
复制代码
       同样地,AP3216C的读时序也是利用IIC收发函数来实现的。写时序和读时序的唯一区别在于最后的flag标志位不同,从而导致发送流程有所不同。如果读者想了解i2c_p->transfer函数的收发流程,可以在MicroPython源代码中找到machine_i2c.c文件(位于micropython\ports\esp32路径下)。

       20.2.2 C模块构造与类的方法

       1,atk_ap3216类的构造方法
       ap3216的构造对象方法如下:
  1. class atk_ap3216.init(iic)
  2. 使用示例:
  3. i2c0 = I2C(0, scl = Pin(42), sda = Pin(41), freq = 400000)
  4. ap3216 = atk_ap3216.init(i2c0)
复制代码
       该构造方法的参数描述,如下表所示。

3.png
表20.2.2.1 atk_ap3216.init构造方法参数描述

       返回值: ap3216c对象。

       2,ap3216类的方法

       ①:向ap3216设备读数据。
       其方法原型如下:
  1. ap3216.ap3216_read()
复制代码
       返回值:环境光强度(ALS)、接近距离(PS)和红外线强度(IR)数据。

       20.3 硬件设计

       1. 例程功能
       本章实验功能简介:开机的时候先检测AP3216C是否存在,如检测不到AP3216C,则在SPILCD屏幕上面显示报错信息。如果检测到AP3216C,则显示正常,并在主循环里面,循环读取ALS+PS+IR的传感器数据,并显示在SPILCD屏幕上面。同时,LED闪烁,提示程序正在运行。

       2. 硬件资源

       1)XL9555
              IIC_INT-IO0(需在P5连接IO0)
              IIC_SDA-IO41
              IIC_SCL-IO42

       2)SPILCD
              CS-IO21
              SCK-IO12
              SDA-IO11
              DC-IO40(在P5端口,使用跳线帽将IO_SET和LCD_DC相连)
              PWR- IO1_3(XL9555)
              RST- IO1_2(XL9555)

       3)AP3216C
              IIC_SDA-IO41
              IIC_SCL-IO42
              AP_INT-IO0_0(XL9555)

       3. 原理图
       AP3216C硬件部分的原理图,如下图所示。

第二十章 光环境传感器实验7005.png
图20.3.1 IIC连接原理

       20.4 程序设计

       20.4.1 程序流程图
       程序流程图能帮助我们更好的理解一个工程的功能和实现的过程,对学习和设计工程有很好的主导作用。下面看看本实验的程序流程图。


第二十章 光环境传感器实验7133.png
图20.4.1.1 程序流程图

       20.4.2 程序解析
       本书籍的代码都在main.py脚本下编写的,读者可在光盘资料下找到对应的源码。光环境传感器实验main.py源码如下:
  1. from machine import Pin,SPI,I2C
  2. import atk_xl9555 as io_ex
  3. import atk_lcd as lcd
  4. import atk_ap3216 as ap3216c
  5. import time


  6. """
  7. * @brief       程序入口
  8. * @param       无
  9. * @retval      无
  10. """
  11. if __name__ == '__main__':
  12.    
  13.     # 初始化LED并输出高电平
  14.     led = Pin(1,Pin.OUT,value = 1)
  15.     # IIC初始化
  16.     i2c0 = I2C(0, scl = Pin(42), sda = Pin(41), freq = 400000)
  17.     # 初始化XL9555
  18.     xl9555 = io_ex.init(i2c0)
  19.    
  20.     # 复位LCD
  21.     xl9555.write_bit(io_ex.SLCD_RST,0)
  22.     time.sleep_ms(100)
  23.     xl9555.write_bit(io_ex.SLCD_RST,1)
  24.     time.sleep_ms(100)
  25.     # 初始化SPI
  26.     spi = SPI(2,baudrate = 80000000, sck = Pin(12), mosi=Pin(11), miso=Pin(13))
  27.     # 初始化LCD,lcd = 0为正点原子2.4寸屏幕;lcd = 1为正点原子1.3寸SPILCD屏幕;
  28.     display = lcd.init(spi,dc = Pin(40,Pin.OUT),cs=Pin(21, Pin.OUT),dir=1,lcd=0)
  29.     # 开启背光
  30.     xl9555.write_bit(io_ex.SLCD_PWR,1)
  31.     time.sleep_ms(100)
  32.     # 显示实验信息
  33.     display.string(30, 50, 240, 16, 16, "ESP32-S3",lcd.RED)
  34.     display.string(30, 70, 200, 16, 16, "AP3216C TEST", lcd.RED)
  35.     display.string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", lcd.RED)
  36.     display.string(30, 110, 200, 16, 16, "ir:", lcd.RED)
  37.     display.string(30, 130, 200, 16, 16, "ps:", lcd.RED)
  38.     display.string(30, 150, 200, 16, 16, "als:", lcd.RED)
  39.     # 初始化AP1632C
  40.     ap3216 = ap3216c.init(i2c0)

  41.     while True:
  42.         # 获取数据
  43.         data = tuple(ap3216.ap3216c_read())
  44.         # 对数据进行换算
  45.         ir = (data[1] << 8) | data[0]
  46.         ps = (data[3] << 8) | data[2]
  47.         als = (data[5] << 8) | data[4]
  48.         # 延时换算结果
  49.         display.num(110, 110,int(ir),5,16,lcd.BLUE)
  50.         display.num(110, 130,int(ps),5,16,lcd.BLUE)
  51.         display.num(110, 150,int(als),5,16,lcd.BLUE)
  52.         led_state = led.value()
  53.         led.value(not led_state)
  54.         time.sleep_ms(500)         # 延时500ms
复制代码
       这示例代码首先初始化了LED灯并使其输出高电平,然后初始化了I2C总线设备,并使用I2C总线初始化了一个XL9555芯片。接着,通过这个芯片来复位LCD显示屏,并使用SPI总线设备初始化了一个LCD显示屏。然后开启LCD显示屏的背光,并在显示屏上显示一些信息。然后,代码初始化了AP3216C传感器,进入一个无限循环,在循环中不断从AP3216C传感器读取环境光强度(ALS)、接近距离(PS)和红外线强度(IR)数据,将数据进行换算,然后将换算结果显示在LCD显示屏上。同时,还会切换LED灯的状态。最后,代码延时500毫秒。

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

第二十章 光环境传感器实验9335.png
图20.5.1 光环境传感器实验测试图

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 06:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表