完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1)实验平台:alientek 阿波罗 STM32F767 开发板
2)摘自《STM32F7 开发指南(HAL 库版)》关注官方微信号公众号,获取更多资料:正点原子 第三十二章 光环境传感器实验 上一章,我们介绍了 IIC 驱动 PCF8574T,本章我们将向大家介绍如何使用 IIC 来驱动光环 境传感器。在本章中,我们将使用 STM32F767 的普通 IO 口模拟 IIC 时序,来驱动 AP3216C, 从而检测环境光强度(ALS)、接近距离(PS)和红外线强度(IR)等环境参数。本章分为如下几个 部分: 32.1 AP3216C 简介 32.2 硬件设计 32.3 软件设计 32.4 下载验证 32.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 的框图如图 32.1.1 所 示: 图 32.1.1 AP3216C 框图 1,引脚说明 AP3216C 的引脚说明如表 32.1.1 所示: 表 32.1.1 AP3216C 引脚说明 AP3216C 和我们的 MCU 只需要连接 SCL、SDA 和 INT,就可以实现驱动。其 SCL 和 SDA 同 24C02 共用,连接在 PH4 和 PH5 上,INT 脚连接在 PCF8574 的 P1 上,见图 31.2.1。关于 IIC 协议的介绍,请参考 IIC 实验,这个章节。 2,写寄存器 AP3216C 的写寄存器时序如图 32.1.2 所示: 图 32.1.2 AP3216C 写寄存器时序 图中,先发送 AP3216C 的地址(7 位,0X1E,左移一位后为:0X3C),最低位 W=0 表示 写数据,随后发送 8 位寄存器地址,最后发送 8 位寄存器值。其中:S,表示 IIC 起始信号;W, 表示读/写标志位(W=0 表示写,W=1 表示读);A,表示应答信号;P,表示 IIC 停止信号。 3,读寄存器 AP3216C 的读寄存器时序如图 32.1.3 所示: 图 32.1.3 AP3216C 读寄存器时序 图中,同样是先发送 7 位地址+写操作,然后再发送寄存器地址,随后,重新发送起始信 号(Sr),再次发送 7 位地址+读操作,然后读取寄存器值。其中:Sr,表示重新发送 IIC 起始 信号;N,表示不对 AP3216C 进行应答;其他简写同上。 4,寄存器描述 AP3216C 有一系列寄存器,由这些寄存器来控制 AP3216C 的工作模式,以及中断配置和 数据输出等。这里我们仅介绍我们在本章需要用到的一些寄存器,其他寄存器的描述和说明, 请大家参考 AP3216C 的数据手册。 本章需要用到 AP3216C 的寄存器如表 32.1.2 所示: 表 32.1.2 AP3216C 相关寄存器及其说明 上表中,0X00 是一个系统模式控制寄存器,主要在初始化的时候配置,初始化的时候,我 们先设置其值为 100,实行一次软复位,随后设置其值为 011,开启 ALS+PS+IR 检测功能。 剩下的 6 个寄存器,为数据寄存器,输出 AP3216C 内部三个传感器所检测到的数据(ADC 值),描述如表所示,这里需要注意的是:读取间隔至少要大于 112.5ms,因为 AP3216C 内部 完成一次 ALS+PS+IR 的数据转换,需要 112.5ms 的时间。 AP3216C 的简介,我们就介绍到这里,关于该芯片的详细说明,请大家参考其数据手册。 本章实验功能简介:开机的时候先检测 AP3216C 是否存在,如检测不到 AP3216C,则在 LCD 屏幕上面显示报错信息。如果检测到 AP3216C,则显示正常,并在主循环里面,循环读取 ALS+PS+IR 的传感器数据,并显示在 LCD 屏幕上面。同时,DS0 闪烁,提示程序正在运行。 另外,本例程将 AP3216C 的读写操作函数加入 USMART 控制,我们也可以通过 USMART 对 AP3216C 进行控制。 32.2 硬件设计 本章需要用到的硬件资源有: 1)指示灯 DS0 2)串口(USMART 使用) 3)LCD 模块 4)AP3216C 前面 3 部分的资源,我们前面已经介绍了,请大家参考相关章节。这里介绍 AP3216C 与 STM32F767 和的连接,AP3216C 同 24C02 等共用一个 IIC 接口,SCL 和 SDA 分别连在 STM32F767 的 PH4 和 PH5 上的,另外 INT 脚连接在 PCF8574T 的 P1 口上,见图 30.2.1。连接 关系如图 32.2.1 所示: 图 32.2.1 AP3216C 与 STM32F767 的连接图 这里需要说明一下:AP3216C的AP_INT脚,是连接在PCF8574T的P1脚上的(见图30.2.1), 如果大家想要用 AP3216C 的中断输出功能,则必须初始化 PCF8574T,并监控 PCF8574T 的中 断引脚,然后在发现有中断输入的时候,读取 PCF8574T,判断 P1 脚是否有低电平出现,从而 检测AP3216C的中断。本章,我们并没有用到AP3216C的中断功能,所以,不需要配置PCF8574T。 32.3 软件设计 打开本章实验工程可以看到,我们在 HARDWARE 分组下面添加了源文件 ap3216c.c 并且 包含了其对应的头文件 ap3216c.h,AP3126C 相关驱动代码就放在这两个文件中。 打开 ap3216c.c 文件,代码如下: //初始化 AP3216C //返回值:0,初始化成功 // 1,初始化失败 u8 AP3216C_Init(void) { u8 temp=0; IIC_Init(); //初始化 IIC AP3216C_WriteOneByte(0x00,0X04); //复位 AP3216C delay_ms(50); //AP33216C 复位至少 10ms AP3216C_WriteOneByte(0x00,0X03); //开启 ALS、PS+IR temp=AP3216C_ReadOneByte(0X00); //读取刚刚写进去的 0X03 if(temp==0X03)return 0; //AP3216C 正常 else return 1; //AP3216C 失败 } //读取 AP3216C 的数据 //读取原始数据,包括 ALS,PS 和 IR //注意!如果同时打开 ALS,IR+PS 的话两次数据读取的时间间隔要大于 112.5ms void AP3216C_ReadData(u16* ir,u16* ps,u16* als) { u8 buf[6]; u8 i; for(i=0;i<6;i++) { buf=AP3216C_ReadOneByte(0X0A+i); //循环读取所有传感器数据 } if(buf[0]&0X80)*ir=0; //IR_OF 位为 1,则数据无效 else *ir=((u16)buf[1]<<2)|(buf[0]&0X03); //读取 IR 传感器的数据 *als=((u16)buf[3]<<8)|buf[2]; //读取 ALS 传感器的数据 if(buf[4]&0x40)*ps=0; //IR_OF 位为 1,则数据无效 else *ps=((u16)(buf[5]&0X3F)<<4)|(buf[4]&0X0F); //读取 PS 传感器的数据 } //IIC 写一个字节 //reg:寄存器地址 //data:要写入的数据 //返回值:0,正常 // 其他,错误代码 u8 AP3216C_WriteOneByte(u8 reg,u8 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; } //IIC 读一个字节 //reg:寄存器地址 //返回值:读到的数据 u8 AP3216C_ReadOneByte(u8 reg) { u8 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_WriteOneByte 和 AP3216C_ReadOneByte 这两个函数实 现 AP3216C 的寄存器写入和读取功能;AP3216C_ReadData 函数,则用于读取 ALS+PS+IR 传 感器的数据,一般我们只需要调用该函数获取数据即可。 ap3216c.h 头文件代码非常简单,主要是函数声明以及宏定义标识符,这里大家只需要注意, 宏定义标识符 AP3216C_ADDR 配置的是器件 AP3216C 的 IIC 地址。 最后我们看看主函数内容,程序如下: int main(void) { u16 ir,als,ps; Cache_Enable(); //打开 L1-Cache HAL_Init(); //初始化 HAL 库 Stm32_Clock_Init(432,25,2,9); //设置时钟,216Mhz delay_init(216); //延时初始化 uart_init(115200); //串口初始化 LED_Init(); //初始化 LED KEY_Init(); //初始化按键 SDRAM_Init(); //初始化 SDRAM LCD_Init(); //LCD 初始化 POINT_COLOR=RED; LCD_ShowString(30,50,200,16,16,"Apollo STM32F4/F7"); LCD_ShowString(30,70,200,16,16,"AP3216C TEST"); LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK"); LCD_ShowString(30,110,200,16,16,"2016/7/12"); while(AP3216C_Init()) //检测不到 AP3216C { LCD_ShowString(30,130,200,16,16,"AP3216C Check Failed!"); delay_ms(500); LCD_ShowString(30,130,200,16,16,"Please Check! "); delay_ms(500); LED0_Toggle; //DS0 闪烁 } LCD_ShowString(30,130,200,16,16,"AP3216C Ready!"); LCD_ShowString(30,160,200,16,16," IR:"); LCD_ShowString(30,180,200,16,16," PS:"); LCD_ShowString(30,200,200,16,16,"ALS:"); POINT_COLOR=BLUE; //设置字体为蓝色 while(1) { AP3216C_ReadData(&ir,&ps,&als); //读取数据 LCD_ShowNum(30+32,160,ir,5,16); //显示 IR 数据 LCD_ShowNum(30+32,180,ps,5,16); //显示 PS 数据 LCD_ShowNum(30+32,200,als,5,16);//显示 ALS 数据 LED0_Toggle;; //提示系统正在运行 delay_ms(120); } } 该段代码,就是根据 31.1 节最后的功能简介来编写的,在初始化完成以后,我们 main 函 数死循环里面,调用 AP3216C_ReadData 函数,读取 ALS+PS+IR 的数据,并显示在 LCD 上面。 同时,DS0 闪烁,提示程序正在运行。这里我们延时 120ms 读取一次,确保 ALS+PS+IR 的转 换全部完成,以保证数据正常。 至此,我们的软件设计部分就结束了。 32.4 下载验证 在代码编译成功之后,我们通过下载代码到 ALIENTEK 阿波罗 STM32 开发板上,得到如 图 32.4.1 所示的界面: 图 32.4.1 程序运行界面 此时,大家可以用手遮挡/靠近 AP3216C 传感器,可以看到三个传感器的数据变化,说明 我们的代码是工作正常的。 |
|
相关推荐
|
|
2255 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
2071 浏览 3 评论
4687 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
2215 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
2757 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-27 09:08 , Processed in 0.624474 second(s), Total 65, Slave 48 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号