网站模板套用/公司网站模版

网站模板套用,公司网站模版,做兼职的设计网站有哪些工作,吉林珠海网站建设一,I2C总线介绍 I2C(Inter-Integrated Circuit 集成电路)总线是Philips公司在八十年代初推出的一种串行、半双工的总 线,主要用于近距离、低速的芯片之间的通信;I2C总线有两根双向的信号线,一根数据线SDA用于收 发数据,一根时钟线…

一,I2C总线介绍

 

I2C(Inter-Integrated Circuit 集成电路)总线是Philips公司在八十年代初推出的一种串行、半双工的总 线,主要用于近距离、低速的芯片之间的通信;I2C总线有两根双向的信号线,一根数据线SDA用于收 发数据,一根时钟线SCL用于通信双方时钟的同步;I2C总线硬件结构简单,简化了PCB布线,降低了系 统成本,提高了系统可靠性,因此在各个领域得到了广泛应用。
I2C总线是一种多主机总线,连接在 I2C总线上的器件分为主机和从机。主机有权发起和结束一次通信,从机只能被动呼叫;当总线上有多个主机同时启用总线时,I2C也具备冲突检测和仲裁的功能来防 止错误产生;每个连接到I2C总线上的器件都有一个唯一的地址(7bit),传输数据的设备间是简单的 主/从关系,每个器件都可以作为主机也可以作为从机(但同一时刻只能有一个机),总线上的器件增加和删除不影响其他器件正常工作;I2C总线在通信时总线上发送数据的器件为发送器,接收数据的 器件为接收器。
I2C总线可以通过外部连线进行在线检测,便于系统故障诊断和调试,故障可以立即被寻址,软件也有 利于标准化和模块化,缩短开发时间。 串行的8位双向数据传输速率在标准模式下可达100Kbit/s,快速模式下可达400Kbit/s,高速模式下可达3.4Mbit/s。

二,通信过程

1. 主机发送起始信号启用总线
2. 主机发送一个字节数据指明从机地址和后续字节的传送方向
3. 被寻址的从机发送应答信号回应主机
4. 发送器发送一个字节数据
5. 接收器发送应答信号回应发送器
6. ........ (循环步骤4、5)
7. 通信完成后主机发送停止信号释放总线
注意点
第4步和第5步用的是发送器和接收器,不是主机和从机,这是由第一个字节的最后一位决定主给从发,还是从给主发。也就是说,第一个字节和最后的停止信号一定是主机发给从机,但中间就不一定了。
发送数据过程中不允许改变发送方向.

三、I2C总线的信号类型

I2C总线在传送数据过程中共有3种类型信号:开始信号、结束信号和响应信号。

3.1 开始信号(S)和结束信号(P)

开始信号:SCL 为高电平时,SDA由高电平向低电平跳变,开始传送数据
结束信号:SCL 为高电平时,SDA由低电平向高电平跳变,结束传送数据
起始信号和停止信号都是由主机发出,起始信号产生后总线处于占用状态,停止信号产生后总线被释 放,处于空闲状态。(空闲时,SCL与SDA都是高电平。)
IIC停止通信的情况有两种:
1. 主机不想发了,就发送停止信号;
2. 从机不想接了,不应答,主机就发送停止信号结束此次通信。

3.2 响应信号(ACK)

        接收器在接收到8位数据后,在第9个时钟周期,拉低SDA电平

需要注意:SDA上传输的数据必须在SCL为高电平期间保持稳定,SDA上的数据只能在SCL为低电平期间变化

SCL和SDA发送数据的电平转换图

四、IIC总线的数据传输格式

 

I2C总线通信时每个字节为8位长度,数据传送时,先传送最高位(MSB),后传送低位,发送器发送完一 个字节数据后接收器必须发送1位应答位来回应发送器,即一帧共有9位。
启动一个传输时,主机先发送S信号,然后发出8位数据。这8位数据中前7位为从机的地址,第8位表示 传输的方向(0表示写操作,1表示读操作)。从机收到后会发出一个ACK信号.
注意:
主机接收器在接收到最后一个字节后,也不会发出ACK信号。于是,从机发送器释放SDA线,以许主 机发出P信号结束传输。

五,i.MX6ull I2C控制器介绍

 

Inter IC (I2C)提供标准I2C从机和主机的功能。I2C被设计为兼容标准 NXP I2C总线协议。
I2C是一种双线双向串行总线,它提供了一种简单有效的数据交换方法, 最大限度地减少了设备之间的互连。这种总线适用于需要在许多设备之间 偶尔进行短距离通信的应用。灵活的I2C标准允许将其他设备连接到总线 上,以进行扩展和系统开发。

5.1 II2C控制器设计

5.2 Clocks

 

I2C有两个输入时钟。
I2C的时钟源说明如下表所示。请参阅时钟控制器模块(CCM)时钟设置,
配置和门控信息。
Peripheral clock: This clock is used for peripheral bus register read/writes.
(外围时钟:这个时钟用于外围总线寄存器读/写)
Module clock: This is the functional clock of the I2C. The serial bit clock frequency is derived from the module clock. The module clock and peripheral clocks are synchronous with each other. The
minimum frequency of the module clock should be 12.8 MHz for Fast mode to achieve 400-kbps
operation.
(模块时钟:这是I2C的功能时钟。串行位时钟频率来源于模块时钟。模块时钟与外设时钟是同步的。在Fast模式下,模块时钟的最小频率应为12.8 MHz,以实现400kbps的工作。)

5.3 Arbitration procedure(仲裁程序)

1,如果多个设备同时请求总线,总线时钟由一个同步过程确定,其中低周期 等于设备中最长的时钟低周期,高周期等于最短的时钟低周期。数据仲裁 程序决定了竞争设备的相对优先级。
2,如果一个设备发送高逻辑而另一个发送低逻辑,则失去仲裁;立即切换到Slave Receive模式,停止驱动I2Cn_SDA。在这种情况下,从主模式到从模式的转换不会生成Stop条件。同时,硬件在I2C状态寄存器(I2C_I2SR[IAL]表示仲裁丢失)中设置仲裁丢失位。

5.4 Initialization sequence(初始化顺序)

 

1,初始化程序完成后,可以通过选择主传输模式来发送串行数据。在多主总 线系统中,需要测试忙碌的总线(I2C_I2SR[IBB])以确定串行总线是否 空闲。如果总线是空闲的(IBB = 0),则可以发送起始信号和第一个字 节(从机地址)。写入数据寄存器的数据包括所需从机的地址,并且最低有效位指示传输方向
2,停止和下一个开始条件之间的空闲时间内置在生成开始周期的硬件中。根据系统时钟和SCL周期的相对频率,在将调用地址写入数据寄存器(I2C_I2DR)后,可能需要等到I2C不忙,然后再将数据加载到数据寄存器(I2C_I2DR)中

5.6 Generation of Stop(停止的产生)

 

数据传输结束时,主站发出停止信号,这可能发生在所有数据发送后。对 于主接收器终止数据传输,它必须通过不确认最后一个数据字节来通知从 站发送器。这是通过在读取倒数第二个字节之前设置传输确认位 (I2C_I2CR[TXAK])来完成的。在读取最后一个字节之前,必须生成停
止信号。

5.7 Generation of Repeated Start(重复启动的产生)

在数据传输之后,如果主站仍然需要总线,它可以发出另一个启动信号, 后面跟着另一个从站地址,而不用发出停止信号

5.8 Post-transfer software response(传输后软件响应)

 

发送或接收一个字节设置数据传输位(I2C_I2SR[ICF]),表示一个字节的 通信完成。完成后,中断状态(I2C_I2SR[IIF])也被设置。如果设置了中 断使能(I2C_I2CR[IIEN]),则会产生外部中断。软件必须首先清除中断 例程中的中断状态(I2C_I2SR[IIF])。
数据传输位(I2C_I2SR[ICF])通过在接收模式下从I2C_I2DR读取或在 传输模式下写入该寄存器来清除。
六,代码实现
IIC的驱动程序相比较pwm,adc,gpt复杂了许多,存在软件IIC和硬件IIC.使用哪一种取决于电路中是否含有硬件IIC的电路.硬件IIC要比软件IIC简单,不需要对特定的操作进行延时(此次案例于光环境传感器,AP3216进行通信)

 

1,软件IIC

IIC代码

#include "i2c.h"void i2c_gpio_init(){//tx初始化 alt5 gpio工作模式IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO28 &=~(0xf<<0);IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO28 |=(0x5<<0);//rx初始化 工作模式同上IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO29 &=~(0xf<<0);IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO29 |=(0x5<<0);//延时delay_ms(5);return ;
}void i2c_start_signal(){SCL_OUT_MODE();SDA_OUT_MODE();SCL_OUTPUT_LEVEL(HIGH);SDA_OUTPUT_LEVEL(HIGH);delay_ms(5);SDA_OUTPUT_LEVEL(LOW);delay_ms(5);
}void i2c_stop_signal(){SCL_OUT_MODE();SDA_OUT_MODE();SCL_OUTPUT_LEVEL(LOW);SDA_OUTPUT_LEVEL(LOW);delay_ms(5);SCL_OUTPUT_LEVEL(HIGH);delay_ms(5);SDA_OUTPUT_LEVEL(HIGH);delay_ms(5);
}
//delay_ms(10);
void i2c_write_data(uint_fast8_t data){SDA_OUT_MODE();SCL_OUTPUT_LEVEL(LOW);int i;uint_fast8_t level;for(i=0;i<8;i++){//由高到低去写level = data>>7 & 1;SDA_OUTPUT_LEVEL(level);delay_ms(5);SCL_OUTPUT_LEVEL(HIGH);delay_ms(5);SCL_OUTPUT_LEVEL(LOW);data = data << 1;}
}
//delay_ms(1);
uint_fast8_t i2c_read_data(){uint_fast8_t data = 0;//设置SDA的模式为输入SDA_IN_MODE();//设置SCL的电平状态SCL_OUTPUT_LEVEL(LOW);delay_ms(5);//MSB先写int i;for(i=0;i<8;i++){SCL_OUTPUT_LEVEL(HIGH);delay_ms(1);int level = SDA_INPUT_LEVEL();data <<=1;data|=level;SCL_OUTPUT_LEVEL(LOW);delay_ms(1);}return data;
}//接收端向发送端发送ACK
void i2c_receive_to_transmit_ack(){//设置SDA的方向为输出SDA_OUT_MODE();//将SCL和SDA拉低SCL_OUTPUT_LEVEL(LOW);SDA_OUTPUT_LEVEL(LOW);delay_ms(5);//SDA保持低电平,SCL切换到高电平SCL_OUTPUT_LEVEL(HIGH);delay_ms(5);
}//接收端向发送端发送NACK
void i2c_receive_to_transmit_nack(){//设置SDA的方向为输出SDA_OUT_MODE();//将SCL和SDA拉低SCL_OUTPUT_LEVEL(LOW);SDA_OUTPUT_LEVEL(HIGH);delay_ms(5);//SDA保持高电平,SCL切换到高电平SDA_OUTPUT_LEVEL(HIGH);delay_ms(5);
}//等待接收端向发送端发送应答信号
int i2c_wait_receive_to_transmit_signal(){//SDA为输入SDA_IN_MODE();SCL_OUTPUT_LEVEL(LOW);delay_ms(5);SCL_OUTPUT_LEVEL(HIGH);delay_ms(5);int timeout = 0;int level=0;do{level = SDA_INPUT_LEVEL();//uart_printf("%d\r\n",level);delay_us(20);//两次读或写操作之间需要延时timeout++;if(timeout>50){uart_printf("data transmit stop!\r\n");i2c_stop_signal();return -1;}}while(level);return 0;}

传感器及测试代码

//AP3216C_SENSOR_H
#include "ap3216c_sensor.h"void ap3216c_write_data_to_sensor(uint_fast8_t registerAddr,uint_fast8_t val){//1.主机向从机发送开始信号i2c_start_signal();//2.发送从机地址i2c_write_data(AP3216_WRITE_ADDRESS);//3.主机等待从机应答信号int ret = i2c_wait_receive_to_transmit_signal();if(ret ==-1){return;}//4.发送寄存器地址i2c_write_data(registerAddr);ret = i2c_wait_receive_to_transmit_signal();if(ret == -1){return;}//5.向相应的寄存器写数据i2c_write_data(val);ret = i2c_wait_receive_to_transmit_signal();if(ret == -1){return;}//6.发送停止信号i2c_stop_signal();
}uint_fast8_t ap3216c_read_data_to_sensor(uint_fast8_t registerAddr){//1.主机向从机发送开始信号uint_fast8_t data;i2c_start_signal();//2.发送从机地址i2c_write_data(AP3216_WRITE_ADDRESS);//3.主机等待从机应答信号int ret = i2c_wait_receive_to_transmit_signal();if(ret ==-1){return;}//4.发送寄存器地址i2c_write_data(registerAddr);//5.主机等待从机应答信号ret = i2c_wait_receive_to_transmit_signal();if(ret == -1){return;}//6.主机向从机发送开始信号i2c_start_signal();//7.发送从机地址i2c_write_data(AP3216_READ_ADDRESS);//8.读取数据ret = i2c_wait_receive_to_transmit_signal();if(ret == -1){return;}data = i2c_read_data();//9.发送NASK信号i2c_receive_to_transmit_nack();//10..发送停止信号i2c_stop_signal();return data;
}//配置ap3216传感器
void ap3216c_sensor_config(){//uart_printf("no");//1.复位ap3216c [sw reset 100]//ap3216c_write_data_to_sensor(AP3216_SYSTEM_CONFIGRATION_ADDRESS,0x04);delay_ms(10);//2.激活 ALS + PS+IRap3216c_write_data_to_sensor(AP3216_SYSTEM_CONFIGRATION_ADDRESS,0x03);//delay_ms(10);//3.读取uint_fast8_t ret = ap3216c_read_data_to_sensor(AP3216_SYSTEM_CONFIGRATION_ADDRESS);if(ret == 0x03){uart_printf("ap3216 communication success!\r\n");}
}//读取ALS的数据
uint_fast16_t ap3216c_sensor_read_als(){//1.初始化GPIO管脚i2c_gpio_init();//2.配置ap3216的传感器ap3216c_sensor_config();//3.读取数据uint_fast16_t data=0;uint_fast8_t data_low = ap3216c_read_data_to_sensor(AP3216_ALS_DATA_LOW_ADDRESS);uint_fast8_t data_high = ap3216c_read_data_to_sensor(AP3216_ALS_DATA_HIGH_ADDRESS);data = data_high << 8| data_low;return data;
}uint_fast16_t ap3216c_sensor_read_ps(){//1.初始化GPIO管脚i2c_gpio_init();//2.配置ap3216的传感器ap3216c_sensor_config();//3.读取数据uint_fast16_t data=0;uint_fast8_t data_low = ap3216c_read_data_to_sensor(AP3216_PS_DATA_LOW_ADDRESS);uint_fast8_t data_high = ap3216c_read_data_to_sensor(AP3216_PS_DATA_HIGH_ADDRESS);// if(data_high & 0x40){//   uart_printf("Invalid IR\r\n");//}data = data_high & (0x3f);data <<=4;data |= ((data_low)& 0xf);return data;
}void ap3216_sensor_als_test(){while(1){uint_fast16_t data_als = ap3216c_sensor_read_als();uart_printf("als:%d\r\n",data_als);}}void ap3216_sensor_ps_test(){while(1){uint_fast16_t data_ps = ap3216c_sensor_read_ps();uart_printf("ps:%d\r\n",data_ps);}}

2,硬件IIC

IIC代码

#include "bsp_i2c.h"
#include "stdio.h"/** @description		: 初始化I2C,波特率100KHZ* @param - base 	: 要初始化的IIC设置* @return 			: 无*/
void i2c_init(I2C_Type *base) {/* 1、配置I2C */base->I2CR &= ~(1 << 7); /* 要访问I2C的寄存器,首先需要先关闭I2C *//* 设置波特率为100K* I2C的时钟源来源于IPG_CLK_ROOT=66Mhz* IC2 时钟 = PERCLK_ROOT/dividison(IFDR寄存器)* 设置寄存器IFDR,IFDR寄存器参考IMX6UL参考手册P1260页,表29-3,* 根据表29-3里面的值,挑选出一个还是的分频数,比如本例程我们* 设置I2C的波特率为100K, 因此当分频值=66000000/100000=660.* 在表29-3里面查找,没有660这个值,但是有640,因此就用640,* 即寄存器IFDR的IC位设置为0X15*/base->IFDR = 0X15 << 0;/** 设置寄存器I2CR,开启I2C* bit[7] : 1 使能I2C,I2CR寄存器其他位其作用之前,此位必须最先置1*/base->I2CR |= (1 << 7);
}/** @description			: 发送重新开始信号* @param - base 		: 要使用的IIC* @param - addrss		: 设备地址* @param - direction	: 方向* @return 				: 0 正常 其他值 出错*/
unsigned char i2c_master_repeated_start(I2C_Type *base, unsigned char address,enum i2c_direction direction) {/* I2C忙并且工作在从模式,跳出 */if (base->I2SR & (1 << 5) && (((base->I2CR) & (1 << 5)) == 0))return 1;/** 设置寄存器I2CR* bit[4]: 1 发送* bit[2]: 1 产生重新开始信号*/base->I2CR |= (1 << 4) | (1 << 2);/** 设置寄存器I2DR* bit[7:0] : 要发送的数据,这里写入从设备地址*            参考资料:IMX6UL参考手册P1249*/base->I2DR =((unsigned int)address << 1) | ((direction == kI2C_Read) ? 1 : 0);return 0;
}/** @description			: 发送开始信号* @param - base 		: 要使用的IIC* @param - addrss		: 设备地址* @param - direction	: 方向* @return 				: 0 正常 其他值 出错*/
unsigned char i2c_master_start(I2C_Type *base, unsigned char address,enum i2c_direction direction) {if (base->I2SR & (1 << 5)) /* I2C忙 */return 1;/** 设置寄存器I2CR* bit[5]: 1 主模式* bit[4]: 1 发送*/base->I2CR |= (1 << 5) | (1 << 4);/** 设置寄存器I2DR* bit[7:0] : 要发送的数据,这里写入从设备地址*            参考资料:IMX6UL参考手册P1249*/base->I2DR =((unsigned int)address << 1) | ((direction == kI2C_Read) ? 1 : 0);return 0;
}/** @description		: 检查并清除错误* @param - base 	: 要使用的IIC* @param - status	: 状态* @return 			: 状态结果*/
unsigned char i2c_check_and_clear_error(I2C_Type *base, unsigned int status) {/* 检查是否发生仲裁丢失错误 */if (status & (1 << 4)) {base->I2SR &= ~(1 << 4); /* 清除仲裁丢失错误位 			*/base->I2CR &= ~(1 << 7); /* 先关闭I2C 				*/base->I2CR |= (1 << 7);  /* 重新打开I2C 				*/return I2C_STATUS_ARBITRATIONLOST;} else if (status & (1 << 0)) /* 没有接收到从机的应答信号 */{return I2C_STATUS_NAK; /* 返回NAK(No acknowledge) */}return I2C_STATUS_OK;
}/** @description		: 停止信号* @param - base	: 要使用的IIC* @param			: 无* @return 			: 状态结果*/
unsigned char i2c_master_stop(I2C_Type *base) {unsigned short timeout = 0xffff;/** 清除I2CR的bit[5:3]这三位*/base->I2CR &= ~((1 << 5) | (1 << 4) | (1 << 3));/* 等待忙结束 */while ((base->I2SR & (1 << 5))) {timeout--;if (timeout == 0) /* 超时跳出 */return I2C_STATUS_TIMEOUT;}return I2C_STATUS_OK;
}/** @description		: 发送数据* @param - base 	: 要使用的IIC* @param - buf		: 要发送的数据* @param - size	: 要发送的数据大小* @param - flags	: 标志* @return 			: 无*/
void i2c_master_write(I2C_Type *base, const unsigned char *buf,unsigned int size) {/* 等待传输完成 */while (!(base->I2SR & (1 << 7)));base->I2SR &= ~(1 << 1); /* 清除标志位 */base->I2CR |= 1 << 4;    /* 发送数据 */while (size--) {base->I2DR = *buf++; /* 将buf中的数据写入到I2DR寄存器 */while (!(base->I2SR & (1 << 1)));                      /* 等待传输完成 */base->I2SR &= ~(1 << 1); /* 清除标志位 *//* 检查ACK */if (i2c_check_and_clear_error(base, base->I2SR))break;}base->I2SR &= ~(1 << 1);i2c_master_stop(base); /* 发送停止信号 */
}/** @description		: 读取数据* @param - base 	: 要使用的IIC* @param - buf		: 读取到数据* @param - size	: 要读取的数据大小* @return 			: 无*/
void i2c_master_read(I2C_Type *base, unsigned char *buf, unsigned int size) {volatile uint8_t dummy = 0;dummy++; /* 防止编译报错 *//* 等待传输完成 */while (!(base->I2SR & (1 << 7)));base->I2SR &= ~(1 << 1);              /* 清除中断挂起位 */base->I2CR &= ~((1 << 4) | (1 << 3)); /* 接收数据 *//* 如果只接收一个字节数据的话发送NACK信号 */if (size == 1)base->I2CR |= (1 << 3);dummy = base->I2DR; /* 假读 */while (size--) {while (!(base->I2SR & (1 << 1)));                      /* 等待传输完成 */base->I2SR &= ~(1 << 1); /* 清除标志位 */if (size == 0) {i2c_master_stop(base); /* 发送停止信号 */}if (size == 1) {base->I2CR |= (1 << 3);}*buf++ = base->I2DR;}
}/** @description	: I2C数据传输,包括读和写* @param - base: 要使用的IIC* @param - xfer: 传输结构体* @return 		: 传输结果,0 成功,其他值 失败;*/
unsigned char i2c_master_transfer(I2C_Type *base, struct i2c_transfer *xfer) {unsigned char ret = 0;enum i2c_direction direction = xfer->direction;base->I2SR &= ~((1 << 1) | (1 << 4)); /* 清除标志位 *//* 等待传输完成 */while (!((base->I2SR >> 7) & 0X1)) {};/* 如果是读的话,要先发送寄存器地址,所以要先将方向改为写 */if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read)) {direction = kI2C_Write;}ret =i2c_master_start(base, xfer->slaveAddress, direction); /* 发送开始信号 */if (ret) {return ret;}while (!(base->I2SR & (1 << 1))) {}; /* 等待传输完成 */ret = i2c_check_and_clear_error(base, base->I2SR); /* 检查是否出现传输错误 */if (ret) {i2c_master_stop(base); /* 发送出错,发送停止信号 */return ret;}/* 发送寄存器地址 */if (xfer->subaddressSize) {do {base->I2SR &= ~(1 << 1); /* 清除标志位 */xfer->subaddressSize--;  /* 地址长度减一 */base->I2DR = ((xfer->subaddress) >>(8 * xfer->subaddressSize)); // 向I2DR寄存器写入子地址while (!(base->I2SR & (1 << 1))); /* 等待传输完成 *//* 检查是否有错误发生 */ret = i2c_check_and_clear_error(base, base->I2SR);if (ret) {i2c_master_stop(base); /* 发送停止信号 */return ret;}} while ((xfer->subaddressSize > 0) && (ret == I2C_STATUS_OK));if (xfer->direction == kI2C_Read) /* 读取数据 */{base->I2SR &= ~(1 << 1); /* 清除中断挂起位 */i2c_master_repeated_start(base, xfer->slaveAddress,kI2C_Read); /* 发送重复开始信号和从机地址 */while (!(base->I2SR & (1 << 1))) {}; /* 等待传输完成 *//* 检查是否有错误发生 */ret = i2c_check_and_clear_error(base, base->I2SR);if (ret) {ret = I2C_STATUS_ADDRNAK;i2c_master_stop(base); /* 发送停止信号 */return ret;}}}/* 发送数据 */if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0)) {i2c_master_write(base, xfer->data, xfer->dataSize);}/* 读取数据 */if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0)) {i2c_master_read(base, xfer->data, xfer->dataSize);}return 0;
}

传感器及测试代码

#include "ap3216c.h"
#include "string.h"
#include <stdint.h>
#include <stdio.h>struct i2c_transfer ap3216;
uint8_t res;void AP3216_W_Data(uint8_t registerAddr, uint8_t val)
{ap3216.data = &val;ap3216.dataSize = 1;ap3216.subaddressSize = 1;ap3216.subaddress = registerAddr;ap3216.direction = kI2C_Write;ap3216.slaveAddress = AP3216_ADDRESS;res = i2c_master_transfer(I2C1, &ap3216);if (res){uart_printf("Write 失败 \r\n");}
}uint8_t AP3216_R_Data(uint8_t registerAddr)
{uint8_t data;ap3216.data = &data;ap3216.dataSize = 1;ap3216.subaddressSize = 1;ap3216.subaddress = registerAddr;ap3216.direction = kI2C_Read;ap3216.slaveAddress = AP3216_ADDRESS;res = i2c_master_transfer(I2C1, &ap3216);if (res){uart_printf("Read 失败 \r\n");}return data;
}// 配置ap3216传感器
void AP3216_Init()
{IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO28 &= ~(0xf << 0);IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO28 |= (0x2 << 0);// rx初始化 工作模式同上IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO29 &= ~(0xf << 0);IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO29 |= (0x2 << 0);// 打开时钟CCM->CCGR2 |= (0x3 << 6);// 复位i2c_init(I2C1);AP3216_W_Data(AP3216_SYSTEM_CONFIGRATION_ADDRESS, 0x04);// 2.激活 ALS + PS+IRAP3216_W_Data(AP3216_SYSTEM_CONFIGRATION_ADDRESS, 0x03);// IIC_DELAY_MS(10);// 3.读取uint8_t ret = AP3216_R_Data(AP3216_SYSTEM_CONFIGRATION_ADDRESS);if (ret == 0x03){uart_printf("  ap3216 communication success!\r\n");}
}// 读取ALS的数据 光
uint16_t AP3216_R_ALS()
{// 3.读取数据uint16_t data = 0;uint8_t data_low = AP3216_R_Data(AP3216_ALS_DATA_LOW_ADDRESS);uint8_t data_high = AP3216_R_Data(AP3216_ALS_DATA_HIGH_ADDRESS);data = data_high << 8 | data_low;return data;
}// 读取PS的数据 距离
uint16_t AP3216_R_PS()
{// 3.读取数据uint16_t data = 0;uint8_t data_low = AP3216_R_Data(AP3216_PS_DATA_LOW_ADDRESS);uint8_t data_high = AP3216_R_Data(AP3216_PS_DATA_HIGH_ADDRESS);data = data_high & (0x3f);data <<= 4;data |= ((data_low) & 0xf);return data;
}
void ap3216test()
{AP3216_Init();uint16_t res = 0;while (1){/* code */res = AP3216_R_ALS();uart_printf("ALS = %d \r\n", res);delay_ms(500);res = AP3216_R_PS();uart_printf("PS = %d \r\n", res);delay_ms(500);}
}

(效果通过串口延时打印可以看出)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/895559.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

书籍推荐:《书法课》林曦

记得樊登老师说过&#xff0c;如果你想了解一个事物&#xff0c;就去读5本相关的书&#xff0c;你会比大部分人都更了解它。这是我读的第4本和“书法”有关的书&#xff0c;作为一个零基础的成年人&#xff0c;林曦这本《书法课》非常值得一读。&#xff08;无论你是否写字&…

【大疆无人机地图测绘技术学习:高精度、高效率的全流程解决方案】

文章目录 大疆无人机地图测绘算法详解一、数据采集&#xff08;一&#xff09;飞行平台与传感器&#xff08;二&#xff09;航线规划&#xff08;三&#xff09;数据类型 二、数据处理与建模&#xff08;一&#xff09;数据导入与预处理&#xff08;二&#xff09;空三计算&…

工具资料+H3C 交换机常见故障分析排查+高危操作

当我们从客户那里接到一个故障时,我们根据现象让客户收集一堆信息,然后集成商、代理商、设备厂家一级一级的反复咨询与确认,天天经历这样的场景。几乎每个故障我们都要经过多个层级的人处理,信息的交流占据了每个人大部分的时间,反复的收集信息与确认问题现象也会让客户不厌其烦…

STM32:USB 虚拟串口以及使用usb->dfu进行iap

本文介绍stm32上usb的常用功能虚拟串口和DFU(Download Firmware Update) 文章目录 前言一、usb二、虚拟串口1.cubemx配置1.我们选用高速usb&#xff0c;然后选择内部低速的phy&#xff0c;这样使用的usb&#xff0c;最高速度为12Mbit每秒。2.USB_DEVICE cdc类配置3.时钟配置&am…

HCIA项目实践--静态路由的综合实验

八 静态路由综合实验 &#xff08;1&#xff09;划分网段 # 192.168.1.0 24#分析&#xff1a;每个路由器存在两个环回接口&#xff0c;可以把两个环回接口分配一个环回地址&#xff0c;所以是四个环回&#xff0c;一个骨干&#xff0c;这样分配&#xff0c;不会出现路由黑洞#19…

通过内网穿透ssh实现远程对家里的linux进行终端操作和编程

内网穿透就是将自己的地址当穿透到公网ip&#xff0c;这一就可以在外网访问了(因为大部分人ip都是动态分配的)&#xff0c;以适用ssh远程连接&#xff0c;我这里用的是极点云cpolar&#xff0c;反正也是黑框编程&#xff0c;免费就行了。我是ubuntu虚拟机&#xff0c;在虚拟机上…

Redis 数据类型 Zset 有序集合

有序集合相对于字符串、列表、哈希、集合来说会有⼀些陌⽣。它保留了集合不能有重复成员的特点&#xff0c;但与集合不同的是&#xff0c;有序集合中的每个元素都有⼀个唯⼀的浮点类型的分数&#xff08;score&#xff09;与之关 联&#xff0c;着使得有序集合中的元素是可以维…

PHP 中的除以零错误

除以零错误&#xff08;Division by zero&#xff09;是指数字除以零的情况&#xff0c; 这在数学上是未定义的。在 PHP 中&#xff0c;处理这种错误的方式取决于 PHP 版本&#xff1a; PHP 7&#xff1a; 使用 / 运算符会产生一个警告 (E_WARNING) 并返回 false。 使用 intd…

基于springboot轨道交通安全评估系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 时代在飞速进步&#xff0c;每个行业都在努力发展现在先进技术&#xff0c;通过这些先进的技术来提高自己的水平和优势&#xff0c;轨道交通安全评估管理当然不能排除在外。轨道交通安全评估系统是在实际应用和软件工程的开发原理之上&#xff0c;运用Java语言以及Spring…

UE5.2后 Bake Out Materials失效

这个问题出现在5.3&#xff0c;5.4&#xff0c;5.5没有测试 烘焙贴图后会找不到贴图位置&#xff0c; 这个是5.2的正常状态 默认是生成在模型当前目录里&#xff0c;包括新的材质 但是这个bug会让材质和贴图都消失&#xff0c;无法定位 暂时没有办法解决&#xff0c;等官方 …

【音视频】RTSP拉流: RTP负载AAC详解(三)

此文为系列文章&#xff0c;此系列主要讲解RTSP客户端的拉流及播放&#xff0c;文章持续更新&#xff0c;会从rtsp的基本协议讲起&#xff0c;如何一步步实现音视频的拉流过程&#xff0c;包括一系列涉及到的协议&#xff0c;rtsp&#xff0c;sdp&#xff0c; rtp&#xff08;本…

【ARM】JTAG接口介绍

1、 文档目标 对 JTAG 接口有更多的认识&#xff0c;在遇到关于 JTAG 接口问题时有一些排查的思路。 2、 问题场景 在使用调试器过程时&#xff0c;免不了要接触到 JTAG 接口&#xff0c;当出现连接不上时&#xff0c;就不知道从哪来进行排查。 3、软硬件环境 1 软件版本&am…

【电脑】u盘重装win7

u盘必须8GB以上 1. CPU型号 首先查看CPU的型号看看到底能不能装win7 2. 下载光盘映像文件 网址 看电脑是多少位的机器(32位下载x86 64位下载x64) 一共是这么多个版本按需下载对应的版本 电脑小白推荐无脑下载旗舰版 将链接复制到迅雷进行下载 3. 下载软碟通 网址 下…

C++-AVL树

一、AVL树的概念 1.二叉搜索树 二叉搜索树&#xff08;BST&#xff0c;Binary Search Tree&#xff09;&#xff0c;也称二叉排序树或二叉查找树。 二叉搜索树&#xff1a;一棵二叉树&#xff0c;可以为空&#xff1b;如果不为空&#xff0c;满足以下性质&#xff1a; 非空左子…

w208基于spring boot物流管理系统设计与实现

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

《刚刚问世》系列初窥篇-Java+Playwright自动化测试-22- 操作鼠标拖拽 - 下篇(详细教程)

1.简介 上一篇中&#xff0c;宏哥说的宏哥在最后提到网站的反爬虫机制&#xff0c;那么宏哥在自己本地做一个网页&#xff0c;没有那个反爬虫的机制&#xff0c;谷歌浏览器是不是就可以验证成功了&#xff0c;宏哥就想验证一下自己想法&#xff0c;其次有人私信宏哥说是有那种…

神经网络常见激活函数 8-SELU函数

SELU 缩放指数线性单元&#xff1a;SELU&#xff08;Scaled Exponential Linear Unit&#xff09; 函数导函数 SELU函数 S E L U ( x ) { λ x x > 0 λ α ( e x − 1 ) x ≤ 0 \rm SELU(x) \left\{ \begin{array}{} \lambda x \quad & x > 0 \\ \lambda \alph…

达梦:AWR 生成

目录标题 AWR 性能诊断与报告生成1. 检查 AWR 系统状态2. 查看数据库中的所有表空间3. 查看现有的 AWR 快照4. 设置 AWR 快照的时间间隔5. 创建 AWR 快照6. 查看最新的 AWR 快照7. 生成 AWR HTML 报告8. 将 AWR 报告保存到指定文件链接总结 自动工作集负载信息库 AWR 报告解析指…

【Map vs Set】:Java数据存储的“双子星”对决

个人主页&#xff1a;♡喜欢做梦 欢迎 &#x1f44d;点赞 ➕关注 ❤️收藏 &#x1f4ac;评论 目录 &#x1f370;一、搜索 &#x1f36e;1.概念 &#x1f36e;2.模型 &#x1f370;二、Map &#x1f368;1.什么是Map&#xff1f; &#x1f368;2.Map的实例化 &…

【C语言 】C语言 桌游开发数字竞拍(源码)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、测试技术。 【C语言 】C语言 桌游开发数字竞拍&#xff08;源码…