【北京迅为】i.MX6ULL终结者I2C操作程序设计

本实验的源码工程在开发板光盘资料的:i.MX6UL终结者光盘资料\04_裸机例程源码\16_i2c 目录下。我们在Ubuntu系统下使用命令“mkdir 16_i2c”建立“16_i2c”文件夹,如图 1所示:
在这里插入图片描述

图 1

然后使用“cd 16_i2c”命令进入到16_i2c文件夹,如图 2所示:
在这里插入图片描述

图 2

然后使用命令“cp -r …/15_rtc/* ./”将上一章试验中的所有内容拷贝到刚刚新建的“16_i2c”里面,如图 3所示:
在这里插入图片描述

图 3

然后在drivers目录下建立i2c和ap3216c文件夹,用来保存i2c和ap3216c的驱动文件,然后在“drivers/i2c”目录中新建i2c.h和i2c.c两个文件,然后在“drivers/ap3216c”文件夹里面新建ap3216c.h和ap3216c.c两个文件。然后在“drivers/i2c/i2c.h”文件输入下面的代码:

  1 #ifndef _BSP_I2C_H
  2 #define _BSP_I2C_H
  3 
  4 #include "imx6ul.h"
  5 
  6 /* 相关宏定义 */
  7 #define I2C_STATUS_OK                           (0)
  8 #define I2C_STATUS_BUSY                         (1)
  9 #define I2C_STATUS_IDLE                         (2)
 10 #define I2C_STATUS_NAK                          (3)
 11 #define I2C_STATUS_ARBITRATIONLOST      (4)
 12 #define I2C_STATUS_TIMEOUT                      (5)
 13 #define I2C_STATUS_ADDRNAK                      (6)
 14 
 15 
 16 /*
 17  * I2C方向枚举类型
 18  */
 19 enum i2c_direction
 20 {
 21     kI2C_Write = 0x0,           /* 主机向从机写数据 */
 22     kI2C_Read = 0x1,            /* 主机从从机读数据 */
 23 } ;
 24 
 25 /*
 26  * 主机传输结构体
 27  */
 28 struct i2c_transfer
 29 {
 30     unsigned char slaveAddress;         /* 7位从机地址          */
 31     enum i2c_direction direction;       /* 传输方向             */
 32     unsigned int subaddress;            /* 寄存器地址           */
 33     unsigned char subaddressSize;       /* 寄存器地址长度       */
 34     unsigned char *volatile data;       /* 数据缓冲区           */
 35     volatile unsigned int dataSize;     /* 数据缓冲区长度       */
 36 };
 37 
 38 
 39 /*
 40  *函数声明
 41  */
 42 void i2c_init(I2C_Type *base);
 43 unsigned char i2c_master_start(I2C_Type *base,
 44                                         unsigned char address,
 45                                         enum i2c_direction direction);
 46 unsigned char i2c_master_repeated_start(I2C_Type *base,
 47                                                 unsigned char address,
 48                                                 enum i2c_direction direction);
 49 unsigned char i2c_check_and_clear_error(I2C_Type *base,
 50                                                 unsigned int status);
 51 unsigned char i2c_master_stop(I2C_Type *base);
 52 void i2c_master_write(I2C_Type *base,
 53                                 const unsigned char *buf,
 54                                 unsigned int size);
 55 void i2c_master_read(I2C_Type *base,
 56                         unsigned char *buf,
 57                         unsigned int size);
 58 unsigned char i2c_master_transfer(I2C_Type *base,
 59                         struct i2c_transfer *xfer);
 60 
 61 #endif

第7行到第13行定义了一些I2C状态相关的宏。第19行到第23行定义了一个类型表示I2C主机对从设备的读写操作。第28行到第36行定义了一个结构体用于I2C数据的传输。第42行到第59行声明了一些I2C的操作函数。
然后打开“drivers/i2c/i2c.c”文件,在里面输入下面的内容:

1 #include "i2c.h"
  2 #include "delay.h"
  3 #include "stdio.h"
  4 
  5 /*
  6  * @description         : 初始化I2C,波特率100KHZ
  7  * @param - base        : 要初始化的IIC设置
  8  * @return                      : 无
  9  */
 10 void i2c_init(I2C_Type *base)
 11 {
 12         /* 1、配置I2C */
 13         base->I2CR &= ~(1 << 7); /* 要访问I2C的寄存器,首先需要先关闭I2C */
 14 
 15     /* 设置波特率为100K
 16      * I2C的时钟源来源于IPG_CLK_ROOT=66Mhz
 17          * IC2 时钟 = PERCLK_ROOT/dividison(IFDR寄存器)
 18          * 设置寄存器IFDR,IFDR寄存器参考IMX6UL参考手册P1260页,表29-3,
 19          * 根据表29-3里面的值,挑选出一个合适的分频数,比如本例程我们
 20          * 设置I2C的波特率为100K, 因此当分频值=66000000/100000=660.
 21          * 在表29-3里面查找,没有660这个值,但是有640,因此就用640,
 22          * 即寄存器IFDR的IC位设置为0X15
 23          */
 24         base->IFDR = 0X15 << 0;
 25 
 26         /*
 27      * 设置寄存器I2CR,开启I2C
 28      * bit[7] : 1 使能I2C,I2CR寄存器其他位其作用之前,此位必须最先置1
 29          */
 30         base->I2CR |= (1<<7);
 31 }
 32 
 33 /*
 34  * @description                 : 发送重新开始信号
 35  * @param - base                : 要使用的IIC
 36  * @param - addrss              : 设备地址
 37  * @param - direction   : 方向
 38  * @return                              : 0 正常 其他值 出错
 39  */
 40 unsigned char i2c_master_repeated_start(I2C_Type *base,
 41                                         unsigned char address,
 42                                         enum i2c_direction direction)
 43 {
 44         /* I2C忙并且工作在从模式,跳出 */
 45         if(base->I2SR & (1 << 5) && (((base->I2CR) & (1 << 5)) == 0))
 46                 return 1;
 47 
 48         /*
 49      * 设置寄存器I2CR
 50      * bit[4]: 1 发送
 51      * bit[2]: 1 产生重新开始信号
 52          */
 53         base->I2CR |=  (1 << 4) | (1 << 2);
 54 
 55         /*
 56      * 设置寄存器I2DR
 57      * bit[7:0] : 要发送的数据,这里写入从设备地址
 58      *            参考资料:IMX6UL参考手册P1249
 59          */
 60         base->I2DR = ((unsigned int)address << 1)
 61                         | ((direction == kI2C_Read)? 1 : 0);
 62 
 63         return 0;
 64 }
 65 
 66 /*
 67  * @description         : 发送开始信号
 68  * @param - base        : 要使用的IIC
 69  * @param - addrss      : 设备地址
 70  * @param - direction   : 方向
 71  * @return              : 0 正常 其他值 出错
 72  */
 73 unsigned char i2c_master_start(I2C_Type *base,
 74                                 unsigned char address,
 75                                 enum i2c_direction direction)
 76 {
 77         if(base->I2SR & (1 << 5))/* I2C忙 */
 78                 return 1;
 79 
 80         /*
 81      * 设置寄存器I2CR
 82      * bit[5]: 1 主模式
 83      * bit[4]: 1 发送
 84          */
 85         base->I2CR |=  (1 << 5) | (1 << 4);
 86 
 87         /*
 88      * 设置寄存器I2DR
 89      * bit[7:0] : 要发送的数据,这里写入从设备地址
 90      *            参考资料:IMX6UL参考手册P1249
 91          */
 92         base->I2DR = ((unsigned int)address << 1)
 93                         | ((direction == kI2C_Read)? 1 : 0);
 94         return 0;
 95 }
 96 
 97 /*
 98  * @description         : 检查并清除错误
 99  * @param - base        : 要使用的IIC
100  * @param - status      : 状态
101  * @return              : 状态结果
102  */
103 unsigned char i2c_check_and_clear_error(I2C_Type *base,
104                                         unsigned int status)
105 {
106         /* 检查是否发生仲裁丢失错误 */
107         if(status & (1<<4))
108         {
109                 base->I2SR &= ~(1<<4);  /* 清除仲裁丢失错误位                   */
110 
111                 base->I2CR &= ~(1 << 7);/* 先关闭I2C                            */
112                 base->I2CR |= (1 << 7); /* 重新打开I2C                          */
113                 return I2C_STATUS_ARBITRATIONLOST;
114         }
115         else if(status & (1 << 0))/* 没有接收到从机的应答信号 */
116         {
117                 return I2C_STATUS_NAK;  /* 返回NAK(No acknowledge) */
118         }
119         return I2C_STATUS_OK;
120 }
121 
122 /*
123  * @description         : 停止信号
124  * @param - base        : 要使用的IIC
125  * @param               : 无
126  * @return              : 状态结果
127  */
128 unsigned char i2c_master_stop(I2C_Type *base)
129 {
130         unsigned short timeout = 0xffff;
131 
132         /*
133          * 清除I2CR的bit[5:3]这三位
134          */
135         base->I2CR &= ~((1 << 5) | (1 << 4) | (1 << 3));
136 
137         /* 等待忙结束 */
138         while((base->I2SR & (1 << 5)))
139         {
140                 timeout--;
141                 if(timeout == 0)/* 超时跳出 */
142                         return I2C_STATUS_TIMEOUT;
143         }
144         return I2C_STATUS_OK;
145 }
146 
147 /*
148  * @description         : 发送数据
149  * @param - base        : 要使用的IIC
150  * @param - buf         : 要发送的数据
151  * @param - size        : 要发送的数据大小
152  * @param - flags       : 标志
153  * @return                      : 无
154  */
155 void i2c_master_write(I2C_Type *base,
156                         const unsigned char *buf,
157                         unsigned int size)
158 {
159         /* 等待传输完成 */
160         while(!(base->I2SR & (1 << 7)));
161 
162         base->I2SR &= ~(1 << 1); /* 清除标志位 */
163         base->I2CR |= 1 << 4;   /* 发送数据 */
164 
165         while(size--)
166         {
167                 base->I2DR = *buf++; /* 将buf中的数据写入到I2DR寄存器 */
168 
169                 while(!(base->I2SR & (1 << 1))); /* 等待传输完成 */
170                 base->I2SR &= ~(1 << 1);        /* 清除标志位 */
171 
172                 /* 检查ACK */
173                 if(i2c_check_and_clear_error(base, base->I2SR))
174                         break;
175         }
176 
177         base->I2SR &= ~(1 << 1);
178         i2c_master_stop(base);  /* 发送停止信号 */
179 }
180 
181 /*
182  * @description         : 读取数据
183  * @param - base        : 要使用的IIC
184  * @param - buf         : 读取到数据
185  * @param - size        : 要读取的数据大小
186  * @return                      : 无
187  */
188 void i2c_master_read(I2C_Type *base,
189                         unsigned char *buf, unsigned int size)
190 {
191         volatile uint8_t dummy = 0;
192 
193         dummy++;        /* 防止编译报错 */
194 
195         /* 等待传输完成 */
196         while(!(base->I2SR & (1 << 7)));
197 
198         base->I2SR &= ~(1 << 1);        /* 清除中断挂起位 */
199         base->I2CR &= ~((1 << 4) | (1 << 3));   /* 接收数据 */
200 
201         /* 如果只接收一个字节数据的话发送NACK信号 */
202         if(size == 1)
203         base->I2CR |= (1 << 3);
204 
205         dummy = base->I2DR; /* 假读 */
206 
207         while(size--)
208         {
209                 while(!(base->I2SR & (1 << 1))); /* 等待传输完成 */
210                 base->I2SR &= ~(1 << 1);        /* 清除标志位 */
211 
212                 if(size == 0)
213         {
214                 i2c_master_stop(base);  /* 发送停止信号 */
215         }
216 
217         if(size == 1)
218         {
219             base->I2CR |= (1 << 3);
220         }
221                 *buf++ = base->I2DR;
222         }
223 }
224 
225 /*
226  * @description : I2C数据传输,包括读和写
227  * @param - base: 要使用的IIC
228  * @param - xfer: 传输结构体
229  * @return      : 传输结果,0 成功,其他值 失败;
230  */
231 unsigned char i2c_master_transfer(I2C_Type *base, struct i2c_transfer *xfer)
232 {
233         unsigned char ret = 0;
234          enum i2c_direction direction = xfer->direction;
235 
236         base->I2SR &= ~((1 << 1) | (1 << 4));/* 清除标志位 */
237 
238         /* 等待传输完成 */
239         while(!((base->I2SR >> 7) & 0X1)){};
240 
241         /* 如果是读的话,要先发送寄存器地址,所以要先将方向改为写 */
242     if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))
243     {
244         direction = kI2C_Write;
245     }
246 
247         ret = i2c_master_start(base, xfer->slaveAddress, direction); /* 发送开始信号 */
248         if(ret)
249         {
250                 return ret;
251         }
252 
253         while(!(base->I2SR & (1 << 1))){};/* 等待传输完成 */
254 
255     ret = i2c_check_and_clear_error(base, base->I2SR);/* 检查是否出现传输错误 */
256     if(ret)
257     {
258         i2c_master_stop(base); /* 发送出错,发送停止信号 */
259         return ret;
260     }
261 
262     /* 发送寄存器地址 */
263     if(xfer->subaddressSize)
264     {
265         do
266         {
267                         base->I2SR &= ~(1 << 1);/* 清除标志位 */
268             xfer->subaddressSize--;     /* 地址长度减一 */
269 
270             base->I2DR =  ((xfer->subaddress) >> (8 * xfer->subaddressSize));
271 
272                         while(!(base->I2SR & (1 << 1))); /* 等待传输完成 */
273 
274             /* 检查是否有错误发生 */
275             ret = i2c_check_and_clear_error(base, base->I2SR);
276             if(ret)
277             {
278                 i2c_master_stop(base);  /* 发送停止信号 */
279                 return ret;
280             }
281         } while ((xfer->subaddressSize > 0) && (ret == I2C_STATUS_OK));
282 
283         if(xfer->direction == kI2C_Read) /* 读取数据 */
284         {
285             base->I2SR &= ~(1 << 1);    /* 清除中断挂起位 */
286             i2c_master_repeated_start(base,
287                                         xfer->slaveAddress,
288                                         kI2C_Read); /* 发送重复开始信号和从机地址 */
289                 while(!(base->I2SR & (1 << 1))){};/* 等待传输完成 */
290 
291             /* 检查是否有错误发生 */
292                 ret = i2c_check_and_clear_error(base, base->I2SR);
293             if(ret)
294             {
295                 ret = I2C_STATUS_ADDRNAK;
296                 i2c_master_stop(base);  /* 发送停止信号 */
297                 return ret;
298             }
299 
300         }
301     }
302 
303 
304     /* 发送数据 */
305     if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0))
306     {
307         i2c_master_write(base, xfer->data, xfer->dataSize);
308         }
309 
310     /* 读取数据 */
311     if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0))
312     {
313         i2c_master_read(base, xfer->data, xfer->dataSize);
314         }
315         return 0;
316 }

i2c_init函数用来初始化I2C,设置I2C的时钟,开启I2C。
i2c_master_repeated_start函数用来发送一个重复开始信号。
i2c_master_start函数用来发送一个开始信号。
i2c_check_and_clear_error函数用于检查并清除错误。
i2c_master_stop函数用于产生一个停止信号。
i2c_master_write函数用于向从设备发送数据。
i2c_master_read函数用于从从设备读取数据。
i2c_master_transfer函数工用户使用,用户完成I2C数据的通信。

然后我们打开“drivers/ap3216c/ap3216c.h”文件,输入下面的内容:

  1 #ifndef _BSP_AP3216C_H
  2 #define _BSP_AP3216C_H
  3 
  4 #include "imx6ul.h"
  5 
  6 #define AP3216C_ADDR            0X1E    /* AP3216C器件地址 */
  7 
  8 /* AP3316C寄存器 */
  9 #define AP3216C_SYSTEMCONG      0x00    /* 配置寄存器           */
 10 #define AP3216C_INTSTATUS       0X01    /* 中断状态寄存器       */
 11 #define AP3216C_INTCLEAR        0X02    /* 中断清除寄存器       */
 12 #define AP3216C_IRDATALOW       0x0A    /* IR数据低字节         */
 13 #define AP3216C_IRDATAHIGH      0x0B    /* IR数据高字节         */
 14 #define AP3216C_ALSDATALOW      0x0C    /* ALS数据低字节        */
 15 #define AP3216C_ALSDATAHIGH     0X0D    /* ALS数据高字节        */
 16 #define AP3216C_PSDATALOW       0X0E    /* PS数据低字节         */
 17 #define AP3216C_PSDATAHIGH      0X0F    /* PS数据高字节         */
 18 
 19 /* 函数声明 */
 20 unsigned char ap3216c_init(void);
 21 unsigned char ap3216c_readonebyte(unsigned char addr,
 22                                         unsigned char reg);
 23 unsigned char ap3216c_writeonebyte(unsigned char addr,
 24                                         unsigned char reg,
 25                                         unsigned char data);
 26 void ap3216c_readdata(unsigned short *ir,
 27                         unsigned short *ps,
 28                         unsigned short *als);
 29 
 30 #endif

第6行顶一个ap3216c的I2C设备地址的宏。
第9行到第17行定义了一些宏,分别对应ap3216c的寄存器地址。
第20行到第29行声明了一些ap3216c的操作函数。

然后我们打开“drivers/ap3216c/ap3216c.c”,在里面输入下面的内容:

  1 #include "ap3216c.h"
  2 #include "i2c.h"
  3 #include "delay.h"
  4 #include "cc.h"
  5 #include "stdio.h"
  6 
  7 /*
  8  * @description : 初始化AP3216C
  9  * @param               : 无
 10  * @return              : 0 成功,其他值 错误代码
 11  */
 12 unsigned char ap3216c_init(void)
 13 {
 14         unsigned char data = 0;
 15 
 16         /* 1、IO初始化,配置I2C IO属性  
 17          * I2C1_SCL -> UART4_TXD
 18          * I2C1_SDA -> UART4_RXD
 19          */
 20         IOMUXC_SetPinMux(IOMUXC_UART4_TX_DATA_I2C1_SCL, 1);
 21         IOMUXC_SetPinMux(IOMUXC_UART4_RX_DATA_I2C1_SDA, 1);
 22 
 23         /* 
 24          *bit 16:0 HYS关闭
 25          *bit [15:14]: 1 默认47K上拉
 26          *bit [13]: 1 pull功能
 27          *bit [12]: 1 pull/keeper使能 
 28          *bit [11]: 0 关闭开路输出
 29          *bit [7:6]: 10 速度100Mhz
 30          *bit [5:3]: 110 驱动能力为R0/6
 31          *bit [0]: 1 高转换率
 32          */
 33         IOMUXC_SetPinConfig(IOMUXC_UART4_TX_DATA_I2C1_SCL, 0x70B0);
 34         IOMUXC_SetPinConfig(IOMUXC_UART4_RX_DATA_I2C1_SDA, 0X70B0);
 35 
 36         i2c_init(I2C1);         /* 初始化I2C1 */
 37 
 38         /* 2、初始化AP3216C */
 39         ap3216c_writeonebyte(AP3216C_ADDR,
 40                                 AP3216C_SYSTEMCONG, 0X04);/* 复位AP3216C*/
 41         delayms(50);/* AP33216C复位至少10ms */
 42         ap3216c_writeonebyte(AP3216C_ADDR,
 43                               AP3216C_SYSTEMCONG, 0X03);/* 开启ALS、PS+IR*/
 44         data = ap3216c_readonebyte(AP3216C_ADDR,
 45                               AP3216C_SYSTEMCONG);/* 读取写进去的0X03 */
 46         if(data == 0X03)
 47                 return 0;       /* AP3216C正常  */
 48         else
 49                 return 1;       /* AP3216C失败  */
 50 }
 51 
 52 /*
 53  * @description : 向AP3216C写入数据
 54  * @param - addr: 设备地址
 55  * @param - reg : 要写入的寄存器
 56  * @param - data: 要写入的数据
 57  * @return              : 操作结果
 58  */
 59 unsigned char ap3216c_writeonebyte(unsigned char addr,
 60                                         unsigned char reg,
 61                                         unsigned char data)
 62 {
 63     unsigned char status=0;
 64     unsigned char writedata=data;
 65     struct i2c_transfer masterXfer;
 66 
 67     /* 配置I2C xfer结构体 */
 68         masterXfer.slaveAddress = addr; /* 设备地址 */
 69     masterXfer.direction = kI2C_Write;  /* 写入数据 */
 70     masterXfer.subaddress = reg;/* 要写入的寄存器地址   */
 71     masterXfer.subaddressSize = 1;/* 地址长度一个字节   */
 72     masterXfer.data = &writedata;/* 要写入的数据        */
 73     masterXfer.dataSize = 1;    /* 写入数据长度1个字节  */
 74 
 75     if(i2c_master_transfer(I2C1, &masterXfer))
 76         status=1;
 77 
 78     return status;
 79 }
 80 
 81 /*
 82  * @description : 从AP3216C读取一个字节的数据
 83  * @param - addr: 设备地址
 84  * @param - reg : 要读取的寄存器
 85  * @return              : 读取到的数据。
 86  */
 87 unsigned char ap3216c_readonebyte(unsigned char addr,unsigned char reg)
 88 {
 89     unsigned char val=0;
 90 
 91     struct i2c_transfer masterXfer;
 92     masterXfer.slaveAddress = addr; /* 设备地址 */
 93     masterXfer.direction = kI2C_Read;   /* 读取数据 */
 94     masterXfer.subaddress = reg;/* 要读取的寄存器地址 */
 95     masterXfer.subaddressSize = 1;/* 地址长度一个字节 */
 96     masterXfer.data = &val;     /* 接收数据缓冲区 */
 97     masterXfer.dataSize = 1;    /* 读取数据长度1个字节  */
 98     i2c_master_transfer(I2C1, &masterXfer);
 99 
100     return val;
101 }
102 
103 /*
104  * @description : 读取AP3216C的数据,读取原始数据,
105                         包括ALS,PS和IR, 注意!
106  *      : 如果同时打开ALS,IR+PS的话两次数据读取的时间间隔要大于112.5ms
107  * @param - ir  : ir数据
108  * @param - ps  : ps数据
109  * @param - ps  : als数据 
110  * @return              : 无。
111  */
112 void ap3216c_readdata(unsigned short *ir,
113                         unsigned short *ps,
114                         unsigned short *als)
115 {
116     unsigned char buf[6];
117     unsigned char i;
118 
119     /* 循环读取所有传感器数据 */
120     for(i = 0; i < 6; i++)
121     {
122         buf[i] = ap3216c_readonebyte(AP3216C_ADDR, AP3216C_IRDATALOW + i);
123     }
124 
125     if(buf[0] & 0X80)   /* IR_OF位为1,则数据无效 */
126                 *ir = 0;
127      else    /* 读取IR传感器的数据*/
128                 *ir = ((unsigned short)buf[1] << 2) | (buf[0] & 0X03);
129 
130      *als = ((unsigned short)buf[3] << 8) | buf[2];  /* 读取ALS传数据*/
131 
132      if(buf[4] & 0x40)   /* IR_OF位为1,则数据无效 */
133                 *ps = 0;                                                                                              
134      else    /* 读取PS传感器的数据    */
135                 *ps = ((unsigned short)(buf[5] & 0X3F) << 4) | (buf[4] & 0X0F);
136 }

ap3216c_init函数用于完成ap3216c的初始化,初始化成功返回0,否则返回1。
ap3216c_writeonebyte函数用于向ap3216c写入一个字节的数据。
ap3216c_readonebyte函数用从ap3216c读取一个字节的数据。
ap3216c_readdata函数用于从ap3216c读取ALS,PS,IR的一组数据。

然后打开main.c文件,在里面输入下面的内容:

1 #include "clk.h"
  2 #include "delay.h"
  3 #include "led.h"
  4 #include "beep.h"
  5 #include "key.h"
  6 #include "int.h"
  7 #include "uart.h"
  8 #include "lcd.h"
  9 #include "rtc.h"
 10 #include "ap3216c.h"
 11 #include "stdio.h"
 12 
 13 /*
 14  * @description : main函数
 15  * @param               : 无
 16  * @return              : 无
 17  */
 18 int main(void)
 19 {
 20         unsigned short ir, als, ps;
 21         unsigned char state = OFF;
 22 
 23         int_init();             /* 初始化中断(一定要最先调用!) */
 24         imx6u_clkinit();        /* 初始化系统时钟               */
 25         delay_init();           /* 初始化延时                   */
 26         clk_enable();           /* 使能所有的时钟               */
 27         led_init();             /* 初始化led                    */
 28         beep_init();            /* 初始化beep                   */
 29         uart_init();            /* 初始化串口,波特率115200     */
 30         lcd_init();             /* 初始化LCD                    */
 31 
 32         tftlcd_dev.forecolor = LCD_RED;
 33         lcd_show_string(30, 50, 200, 16, 16,
 34                         (char*)"i.MX6ULL I2C TEST");
 35         lcd_show_string(30, 70, 200, 16, 16,
 36                         (char*)"AP3216C TEST");
 37 
 38         while(ap3216c_init())   /* 检测不到AP3216C */
 39         {
 40                 lcd_show_string(30, 130, 200, 16, 16,
 41                                 (char*)"AP3216C Check Failed!");
 42                 delayms(500);
 43                 lcd_show_string(30, 130, 200, 16, 16,
 44                                 (char*)"Please Check!        ");
 45                 delayms(500);
 46         }
 47 
 48         lcd_show_string(30, 130, 200, 16, 16, (char*)"AP3216C Ready!");
 49         lcd_show_string(30, 160, 200, 16, 16, (char*)" IR:");
 50         lcd_show_string(30, 180, 200, 16, 16, (char*)" PS:");
 51         lcd_show_string(30, 200, 200, 16, 16, (char*)"ALS:");
 52         tftlcd_dev.forecolor = LCD_BLUE;
 53         while(1)
 54         {
 55                 ap3216c_readdata(&ir, &ps, &als);/* 读取数据    */
 56                 lcd_shownum(30 + 32, 160, ir, 5, 16);/* 显示IR数据 */
 57                 lcd_shownum(30 + 32, 180, ps, 5, 16);   /* 显示PS数据   */
 58                 lcd_shownum(30 + 32, 200, als, 5, 16);  /* 显示ALS数据  */
 59                 delayms(120);
 60                 state = !state;
 61                 led_switch(LED0,state);
 62         }
 63         return 0;
 64 }

第38行进入while循环调用ap3216c_init()初始化函数检测ap3216c是否存在,如果ap3216c不存在,则会在屏幕显示ap3216c不存在的信息,程序会一直在while循环中,直到检测到ap3216c才会跳出while循环,继续往下执行。
当检测到ap3216c存在,程序进入第53行的主循环里面,然后每隔120毫秒回去一次ALS,PS,IR的数值,并在屏幕上显示出来,同时led的状态也会按照120毫秒的状态来回切换。在这里插入图片描述

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页