OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 51|回复: 0

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

[复制链接]

1323

主题

1339

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
5656
金钱
5656
注册时间
2019-5-8
在线时间
1518 小时
发表于 昨天 09:31 | 显示全部楼层 |阅读模式
第三十七章 光环境传感器实验

1)实验平台:正点原子STM32H7R7开发板

2)章节摘自【正点原子】STM32H7R7开发指南 V1.1

3)购买链接: https://detail.tmall.com/item.htm?id=820823382459

4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/stm32/zdyz_stm32h7rx.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子STM32开发板技术交流群:756580169


2.jpg

3.png

上一章,我们介绍了IIC驱动PCF8574T,本章我们将向大家介绍如何使用IIC来驱动光环境传感器。在本章中,我们将使用STM32H7R7的普通IO口模拟IIC时序,来驱动AP3216C,从而检测环境光强度(ALS)、接近距离(PS)和红外线强度(IR)等环境参数。
本章分为如下几个小节:
37.1 光敏传感器简介
37.2 硬件设计
37.3 程序设计
37.4 下载验证


37.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的框图如图37.1.1所示:


第三十七章 光环境传感器实验573.png
图37.1.1 AP3216C框图

1.引脚说明
AP3216C的引脚说明如表37.1.1所示:


1.png
表37.1.1 AP3216C引脚说明

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

2.写寄存器
AP3216C的写寄存器时序如图37.1.2所示:


第三十七章 光环境传感器实验919.png
图37.1.2 AP3216C写寄存器时序

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

3.读寄存器
AP3216C的读寄存器时序如图37.1.3所示:


第三十七章 光环境传感器实验1112.png
图37.1.3 AP3216C读寄存器时序

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

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


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

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


37.2 硬件设计

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

2. 硬件资源
1)LED灯
       LED0 – PD14
2)串口1(PB14/PB15连接在板载USB转串口芯片CH340上面)
3)正点原子2.8/3.5/4.3/7/10寸TFTLCD模块(包括MCU屏和RGB屏,都支持)
4)AP3216C(通过IIC接口连接)
       IIC_SCL  –PF1
       IIC_SDA –PF0

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


第三十七章 光环境传感器实验2422.png
图37.2.1 光敏传感器与开发板连接示意图

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

37.3 程序设计

37.3.1 程序解析

1. AP3216C驱动代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。AP3216C驱动源码包括两个文件:ap3216c.c和ap3216.h。
ap3216c.h头文件代码非常简单,主要是函数声明以及宏定义标识符,这里大家只需要注意,宏定义标识符AP3216C_ADDR配置的是器件AP3216C的IIC地址。
下面介绍ap3216c.c的函数,首先是光环境传感器初始化函数,其定义如下:

  1. /**
  2. * @brief   AP3216C初始化
  3. * [url=home.php?mod=space&uid=271674]@param[/url]   无
  4. * @retval  初始化结果
  5. * @arg     0: 成功
  6. * @arg     1: 失败
  7. */
  8. uint8_t ap3216c_init(void)
  9. {
  10.     uint8_t dat;
  11.    
  12.     /* 初始化IIC */
  13.     iic_init();
  14.    
  15.     /* 软复位 */
  16.     ap3216c_write_reg(0x00, 0x04);
  17.     delay_ms(20);
  18.    
  19.     /* 开启ALS、PS、IR功能并回读校验 */
  20.     ap3216c_write_reg(0x00, 0x03);
  21.     dat = ap3216c_read_reg(0x00);
  22.     if (dat != 0x03)
  23.     {
  24.         return 1;
  25.     }
  26.    
  27.     return 0;
  28. }

  29. /**
  30. * @brief   读取AP3216C数据
  31. * @param   ir: IR传感器数据
  32. * @param   ps: PS传感器数据
  33. * @param   als: ALS传感器数据
  34. * @retval  无
  35. */
  36. void ap3216c_read_data(uint16_t *ir, uint16_t *ps, uint16_t *als)
  37. {
  38.     uint8_t buf[6];
  39.     uint8_t i;
  40.    
  41.     for (i=0; i<6; i++)
  42.     {
  43.         buf[i] = ap3216c_read_reg(0x0A + i);
  44.     }
  45.    
  46.     if ((buf[0] & 0x80) != 0)
  47.     {
  48.         *ir = 0;
  49.     }
  50.     else
  51.     {
  52.         *ir = ((uint16_t)buf[1] << 2) | (buf[0] & 0x03);
  53.     }
  54.    
  55.     *als = ((uint16_t)buf[3] << 8) | buf[2];
  56.    
  57.     if ((buf[4] & 0x40) != 0)
  58.     {
  59.         *ps = 0;
  60.     }
  61.     else
  62.     {
  63.         *ps = ((uint16_t)(buf[5] & 0x3F) << 4) | (buf[4] & 0x0F);
  64.     }
  65. }

  66. /**
  67. * @brief   读AP3216C寄存器
  68. * @param   reg: 寄存器地址
  69. * @retval  寄存器值
  70. */
  71. static uint8_t ap3216c_read_reg(uint8_t reg)
  72. {
  73.     uint8_t dat;
  74.    
  75.     iic_start();
  76.     iic_send_byte((AP3216C_IIC_ADDR << 1) | 0x00);
  77.     if (iic_wait_ack() != 0)
  78.     {
  79.         iic_stop();
  80.         return 1;
  81.     }
  82.     iic_send_byte(reg);
  83.     if (iic_wait_ack() != 0)
  84.     {
  85.         iic_stop();
  86.         return 1;
  87.     }
  88.     iic_start();
  89.     iic_send_byte((AP3216C_IIC_ADDR << 1) | 0x01);
  90.     if (iic_wait_ack() != 0)
  91.     {
  92.         iic_stop();
  93.         return 1;
  94.     }
  95.     dat = iic_read_byte(0);
  96.     iic_stop();
  97.    
  98.     return dat;
  99. }

  100. /**
  101. * @brief   写AP3216C寄存器
  102. * @param   reg: 寄存器地址
  103. * @param   dat: 寄存器值
  104. * @retval  无
  105. */
  106. static uint8_t ap3216c_write_reg(uint8_t reg, uint8_t dat)
  107. {
  108.     iic_start();
  109.     iic_send_byte((AP3216C_IIC_ADDR << 1) | 0x00);
  110.     if (iic_wait_ack() != 0)
  111.     {
  112.         iic_stop();
  113.         return 1;
  114.     }
  115.     iic_send_byte(reg);
  116.     if (iic_wait_ack() != 0)
  117.     {
  118.         iic_stop();
  119.         return 1;
  120.     }
  121.     iic_send_byte(dat);
  122.     if (iic_wait_ack() != 0)
  123.     {
  124.         iic_stop();
  125.         return 1;
  126.     }
  127.     iic_stop();
  128.    
  129.     return 0;
  130. }
复制代码
该部分为AP3216C的驱动代码,其中的IIC相关函数,直接是用第三十六章myiic.c里面提供的相关函数,这里不做介绍。
这里总共有4个函数:ap3216c_init函数用于初始化并检测AP3216C,先设置AP3216C软复位,随后设置其工作在ALS+PS+IR模式,通过对系统模式寄存器的读写操作,来判断AP3216C是否正常(在位);ap3216c_write_reg和ap3216c_read_reg这两个函数实现AP3216C的寄存器写入和读取功能;ap3216c_read_data函数,则用于读取ALS+PS+IR传感器的数据,一般我们只需要调用该函数获取数据即可。

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

  1. int main(void)
  2. {
  3.     uint16_t ir, als, ps;
  4.    
  5.     sys_mpu_config();                   /* 配置MPU */
  6.     sys_cache_enable();                 /* 使能Cache */
  7.     HAL_Init();                         /* 初始化HAL库 */
  8.     sys_stm32_clock_init(300, 6, 2);    /* 配置时钟,600MHz */
  9.     delay_init(600);                    /* 初始化延时 */
  10.     usart_init(115200);                 /* 初始化串口 */
  11.     led_init();                         /* 初始化LED */
  12.     hyperram_init();                    /* 初始化HyperRAM */
  13.     lcd_init();                         /* 初始化LCD */
  14.    
  15.     lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
  16.     lcd_show_string(30, 70, 200, 16, 16, "AP3216C TEST", RED);
  17.     lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
  18.    
  19.     while (ap3216c_init())              /* 检测不到AP3216C */
  20.     {
  21.         lcd_show_string(30, 130, 200, 16, 16, "AP3216C Check Failed!", RED);
  22.         delay_ms(500);
  23.         lcd_show_string(30, 130, 200, 16, 16, "Please Check!      ", RED);
  24.         delay_ms(500);
  25.         LED0_TOGGLE();                  /* 红灯闪烁 */
  26.     }

  27.     lcd_show_string(30, 130, 200, 16, 16, "AP3216C Ready!", RED);
  28.     lcd_show_string(30, 160, 200, 16, 16, " IR:", RED);
  29.     lcd_show_string(30, 180, 200, 16, 16, " PS:", RED);
  30.     lcd_show_string(30, 200, 200, 16, 16, "ALS:", RED);

  31.     while (1)
  32.     {
  33.         ap3216c_read_data(&ir, &ps, &als);            /* 读取数据  */
  34.         lcd_show_num(30 + 32, 160, ir, 5, 16, BLUE);  /* 显示IR数据 */
  35.         lcd_show_num(30 + 32, 180, ps, 5, 16, BLUE);  /* 显示PS数据 */
  36.         lcd_show_num(30 + 32, 200, als, 5, 16, BLUE); /* 显示ALS数据  */

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

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

第三十七章 光环境传感器实验7186.png
图37.4.1 光环境传感器实验测试图

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

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-5-9 02:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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