概述
文章目录
- 1. AP3216C简介
- 1.1 AP3216C特点
- 1.2 AP3216C框图
- 1.3 AP3216C寄存器描述
- 1.4 AP3216C写寄存器
- 1.5 AP3216C读寄存器
- 2. 程序设计
1. AP3216C简介
AP3216C是一款三合一环境传感器,它内部集成了:数字环境光传感器(Ambilent Light Aensors,ALS)、距离传感器(Proximity Sensor,PS)和一个红外LED(Infrared Radiation LED,IR LED),该芯片通过IIC接口和FOGA连接。
1.1 AP3216C特点
IIC接口,支持高达400KHz通信速率;
支持多种工作模式(ALS、PS+IR、ALS+PS+IR等);
内置温度补偿电路;
工作温度支持-30~80℃;
环境光传感器具有16位分辨率;
接近传感器具有10位分辨率;
红外传感器具有10位分辨率;
超小封装(4.12.41.35mm)。
1.2 AP3216C框图
1.3 AP3216C寄存器描述
AP3216C有一系列寄存器,由这些寄存器来控制AP3216C工作模式,以及中断配置和数据传输等。
1.4 AP3216C写寄存器
图中,先发送AP3216C的地址(7’h1E),最低位W=0表示写数据,随后发送8位寄存器地址,最后发送8位寄存器值。其中:S,表示IIC起始信号;W,表示读/写标志位(W=0表示写,W=1表示读);A,表示应答信号;P,表示IIC停止信号。
1.5 AP3216C读寄存器
图中,同样是先发送7位地址+写操作,然后再发送寄存器地址,随后,重新发送起始信号(Sr),再次发送7位地址+读操作,然后读取寄存器值。其中:Sr,表示重新发送IIC起始信号;N,表示不对AP3216C进行应答;其他简写同上。
2. 程序设计
使用FOGA开发板上AP3216C器件测量环境光强度和物体距离,并在数码管上显示环境光强度,用4个led灯的亮灭来只是物体距离的远近。
系统框图
IIC驱动参考:EEPROM读写–IIC协议
其中LED显示距离远近,距离越近显示的led灯数目越多。
代码
module ap3216c_top(
//global clock
input sys_clk , // 系统时钟
input sys_rst_n , // 系统复位
//ap3216c interface
output i2c_ack , // I2C应答标志 0:应答 1:未应答
output ap_scl , // i2c时钟线
inout ap_sda , // i2c数据线
//user interface
output [3:0] led , // led灯接口
output [5:0] sel , // 数码管位选
output [7:0] seg_led // 数码管段选
);
//parameter define
parameter SLAVE_ADDR = 7'h1e ; // 器件地址
parameter BIT_CTRL = 1'b0 ; // 字地址位控制参数(16b/8b)
parameter CLK_FREQ = 26'd50_000_000; // i2c_dri模块的驱动时钟频率(CLK_FREQ)
parameter I2C_FREQ = 18'd250_000 ; // I2C的SCL时钟频率
//wire define
wire clk ; // I2C操作时钟
wire i2c_exec ; // i2c触发控制
wire [15:0] i2c_addr ; // i2c操作地址
wire [ 7:0] i2c_data_w; // i2c写入的数据
wire i2c_done ; // i2c操作结束标志
wire i2c_rh_wl ; // i2c读写控制
wire [ 7:0] i2c_data_r; // i2c读出的数据
wire [15:0] als_data ; // ALS的数据
wire [ 9:0] ps_data ; // PS的数据
//*****************************************************
//** main code
//*****************************************************
//例化i2c_dri,调用IIC协议
i2c_dri #(
.SLAVE_ADDR (SLAVE_ADDR), // slave address从机地址,放此处方便参数传递
.CLK_FREQ (CLK_FREQ ), // i2c_dri模块的驱动时钟频率(CLK_FREQ)
.I2C_FREQ (I2C_FREQ ) // I2C的SCL时钟频率
) u_i2c_dri(
//global clock
.clk (sys_clk ), // i2c_dri模块的驱动时钟(CLK_FREQ)
.rst_n (sys_rst_n ), // 复位信号
//i2c interface
.i2c_exec (i2c_exec ), // I2C触发执行信号
.bit_ctrl (BIT_CTRL ), // 器件地址位控制(16b/8b)
.i2c_rh_wl (i2c_rh_wl ), // I2C读写控制信号
.i2c_addr (i2c_addr ), // I2C器件内地址
.i2c_data_w (i2c_data_w), // I2C要写的数据
.i2c_data_r (i2c_data_r), // I2C读出的数据
.i2c_done (i2c_done ), // I 2C一次操作完成
.i2c_ack (i2c_ack ), // I2C应答标志 0:应答 1:未应答
.scl (ap_scl ), // I2C的SCL时钟信号
.sda (ap_sda ), // I2C的SDA信号
//user interface
.dri_clk (clk ) // I2C操作时钟
);
//例化AP3216C测量模块
ap3216c u_ap3216c(
//system clock
.clk (clk ), // 时钟信号
.rst_n (sys_rst_n ), // 复位信号
//i2c interface
.i2c_rh_wl (i2c_rh_wl ), // I2C读写控制信号
.i2c_exec (i2c_exec ), // I2C触发执行信号
.i2c_addr (i2c_addr ), // I2C器件内地址
.i2c_data_w (i2c_data_w), // I2C要写的数据
.i2c_data_r (i2c_data_r), // I2C读出的数据
.i2c_done (i2c_done ), // I2C一次操作完成
//user interface
.als_data (als_data ), // ALS的数据
.ps_data (ps_data ) // PS的数据
);
//例化动态数码管显示模块
seg_led u_seg_led(
//module clock
.clk (sys_clk ), // 时钟信号
.rst_n (sys_rst_n), // 复位信号
//seg_led interface
.seg_sel (sel ), // 位选
.seg_led (seg_led ), // 段选
//user interface
.data (als_data ), // 显示的数值
.point (6'd0 ), // 小数点具体显示的位置,从高到低,高电平有效
.en (1'd1 ), // 数码管使能信号
.sign (1'b0 ) // 符号位(高电平显示“-”号)
);
//例化LED模块
led_disp u_led_disp(
//system clock
.clk (clk ), // 时钟信号
.rst_n (sys_rst_n), // 复位信号
//led interface
.led (led ), // led灯接口
//user interface
.data (ps_data ) // PS的数据
);
endmodule
module ap3216c(
//system clock
input clk , // 时钟信号
input rst_n , // 复位信号
//i2c interface
output reg i2c_rh_wl , // I2C读写控制信号
output reg i2c_exec , // I2C触发执行信号
output reg [15:0] i2c_addr , // I2C器件内地址
output reg [ 7:0] i2c_data_w , // I2C要写的数据
input [ 7:0] i2c_data_r , // I2C读出的数据
input i2c_done , // I2C一次操作完成
//user interface
output reg [15:0] als_data , // ALS的数据
output reg [ 9:0] ps_data // PS的数据
);
//parameter define
parameter TIME_PS = 14'd12_500 ; // PS转换时间为12.5ms(clk = 1MHz)
parameter TIME_ALS = 17'd100_000 ; // ALS转换时间为100ms(clk = 1MHz)
parameter TIME_REST = 8'd2 ; // 停止后重新开始的时间间隔控制
//reg define
reg [ 3:0] flow_cnt ; // 状态流控制
reg [18:0] wait_cnt ; // 计数等待
reg [15:0] als_data_t ; // ALS的临时数据
reg als_done ; // 环境光照强度值采集完成信号
reg [ 9:0] ps_data_t ; // PS的临时数据
reg ir_of ; // 溢出标志(判断ps_data是否有效)
reg obj ; // 物体状态标志(0远离1靠近)
//*****************************************************
//** main code
//*****************************************************
//配置AP3216C并读取数据
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
i2c_exec <= 1'b0;
i2c_addr <= 8'd0;
i2c_rh_wl <= 1'b0;
i2c_data_w <= 8'h0;
flow_cnt <= 4'd0;
wait_cnt <= 18'd0;
ps_data <= 10'd0;
ps_data_t <= 10'd0;
ir_of <= 1'b0;
obj <= 1'b0;
als_done <= 1'b0;
als_data_t <= 16'd0;
end
else begin
i2c_exec <= 1'b0;
case(flow_cnt)
//初始化AP3216C
4'd0: begin
if(wait_cnt == 18'd100) begin
wait_cnt <= 18'd0;
flow_cnt <= flow_cnt + 1'b1;
end
else
wait_cnt <= wait_cnt +1'b1;
end
//配置AP3216C的功能模式
4'd1: begin
i2c_exec <= 1'b1 ;
i2c_rh_wl <= 1'b0 ;
i2c_addr <= 8'h00; // 配置系统寄存器
i2c_data_w <= 8'h03; // 激活ALS+PS+IR 功能
flow_cnt <= flow_cnt + 1'b1;
end
//配置完成
4'd2: begin
if(i2c_done)
flow_cnt <= flow_cnt + 1'b1;
end
//等待PS转换完成(12.5ms)
4'd3: begin
if(wait_cnt == TIME_PS) begin
wait_cnt <= 18'd0;
flow_cnt <= flow_cnt + 1'd1;
end
else
wait_cnt <= wait_cnt + 1'b1;
end
//预读PS Data Register(0x0E)
4'd4: begin
i2c_exec <= 1'b1;
i2c_rh_wl<= 1'b1;
i2c_addr <= 8'h0E;
flow_cnt <= flow_cnt + 1'b1;
end
//读PS Data Register(0x0E)
4'd5: begin
if(i2c_done) begin
flow_cnt <= flow_cnt + 1'b1;
ps_data_t[3:0] <= i2c_data_r[3:0];
ir_of <= i2c_data_r[6] ;
obj <= i2c_data_r[7] ;
end
end
//等待一段时间以进行下一次读写
4'd6: begin
if(wait_cnt == TIME_REST) begin//TIME_REST
wait_cnt <= 18'd0;
flow_cnt <= flow_cnt + 1'b1;
end
else
wait_cnt <= wait_cnt +1'b1;
end
//预读PS Data Register(0x0F)
4'd7: begin
i2c_exec <= 1'b1;
i2c_rh_wl<= 1'b1;
i2c_addr <= 8'h0F;
flow_cnt <= flow_cnt + 1'b1;
end
//读PS Data Register(0x0F)
4'd8: begin
if(i2c_done) begin
flow_cnt <= flow_cnt + 1'b1;
ps_data_t[9:4] <= i2c_data_r[5:0];
ir_of <= i2c_data_r[6] ;
obj <= i2c_data_r[7] ;
end
end
//等待ALS转换完成(100ms)
4'd9: begin
if(wait_cnt == TIME_ALS) begin
wait_cnt <= 18'd0;
flow_cnt <= flow_cnt + 1'd1;
ps_data <= ps_data_t;
end
else
wait_cnt <= wait_cnt + 1'b1;
end
//预读ALS Data Register(0x0C)
4'd10: begin
i2c_exec <= 1'b1;
i2c_rh_wl<= 1'b1;
i2c_addr <= 8'h0C;
flow_cnt <= flow_cnt + 1'b1;
end
//读ALS Data Register(0x0C)
4'd11: begin
if(i2c_done) begin
als_done <= 1'b0;
als_data_t[7:0] <= i2c_data_r;
flow_cnt <= flow_cnt + 1'b1;
end
end
//等待一段时间以进行下一次读写
4'd12: begin
if(wait_cnt == TIME_REST) begin
wait_cnt <= 18'd0;
flow_cnt <= flow_cnt + 1'b1;
end
else
wait_cnt <= wait_cnt +1'b1;
end
//预读ALS Data Register(0x0D)
4'd13: begin
i2c_exec <= 1'b1;
i2c_rh_wl<= 1'b1;
i2c_addr <= 8'h0D;
flow_cnt <= flow_cnt + 1'b1;
end
//读ALS Data Register(0x0D)
4'd14: begin
if(i2c_done) begin
als_done <= 1'b1;
als_data_t[15:8] <= i2c_data_r;
flow_cnt <= 4'd3; //跳转到状态3重新读取数据
end
end
endcase
end
end
//当采集的环境光转换成光照强度(单位:lux)
always @ (*) begin
if(als_done)
als_data = als_data_t * 6'd35 / 7'd100;
end
endmodule
module led_disp(
//system clock
input clk , // 时钟信号
input rst_n, // 复位信号
//led interface
output reg [3:0] led , // led灯接口
//user interface
input [9:0] data // 数据
);
//*****************************************************
//** main code
//*****************************************************
//led灯亮灭个数显示数据大小
always @(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0) begin
led <= 4'd0;
end
else if(data < 10'd16)
led <= 4'b0001;
else if(data < 10'd128)
led <= 4'b0011;
else if(data < 10'd512)
led <= 4'b0111;
else
led <= 4'b1111;
end
endmodule
最后
以上就是高挑可乐为你收集整理的环境光传感器1. AP3216C简介2. 程序设计的全部内容,希望文章能够帮你解决环境光传感器1. AP3216C简介2. 程序设计所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复