MLX90620红外矩阵传感器驱动(基于传感器管理组件)

传感器简介

MLX90620是全校准16X4像素的IR阵列,集成于工业标准四引脚TO-39封装里。同一封装里包含两个芯片MLX90670(集成信号处理的IR阵列)和24AA02(256x8EEPROM)芯片。MLX90620包含64个IR像素点,每个像素都对应有低噪声斩波放大器和高速ADC。芯片中的PTAT(与绝对温度成正比)传感器用来测量环境温度。IR和PTAT的输出都存在内部的RAM,并可以通过IIC通信获取。

MLX_90620.c

  1 /**
  2  * @file MLX_90620.c
  3  * @brief
  4  * @version 0.1
  5  * @date 2019-06-28
  6  *
  7  * @copyright Copyright (c) 2019  Chipintelli Technology Co., Ltd.
  8  *
  9  */
 10 /*-----------------------------------------------------------------------------
 11                             include
 12 --------------------------- --------------------------------------------------*/
 13 #include <math.h>
 14 #include "string.h"
 15 #include "ci_sensor.h"
 16 #include "MLX_90620.h"
 17 #include "ci110x_i2c.h"
 18 #include "ci_log.h"
 19 #include "ci110x_scu.h"
 20 #include "ci_misc.h"
 21 
 22 /*-----------------------------------------------------------------------------
 23                             define
 24 -----------------------------------------------------------------------------*/
 25 #define MLX90620_RESULT(x,y) (x + y * 4)
 26 
 27 #define MLX620_EE_SIZE_BYTES          256      //def MLX620_EE_SIZE_BYTES Device EEPROM memory size expressed in bytes.
 28 #define MLX620_EE_IROffsetAi00        0x00     //def MLX620_EE_IROffsetAi00 IR pixels individual offset coefficients - Ai.
 29 #define MLX620_EE_IROffsetBi00        0x40     //def MLX620_EE_IROffsetBi00 Individual Ta dependence (slope) of IR pixels offset - Bi.
 30 #define MLX620_EE_IRSens00            0x80     //def MLX620_EE_IRSens00 Individual sensitivity coefficients.
 31 #define MLX620_EE_MLX_Reserved1       0xC0     //def MLX620_EE_MLX_Reserved1 Melexis reserved part 1.
 32 #define MLX620_EE_CyclopsA            0xD4     //def MLX620_EE_CyclopsA Compensation pixel (Cyclop)individual offset.
 33 #define MLX620_EE_CyclopsB            0xD5     //def MLX620_EE_CyclopsB Individual Ta dependence (slope) of compensation pixel (Cyclop) offset.
 34 #define MLX620_EE_CyclopsAlpha        0xD6     //def MLX620_EE_CyclopsAlpha Sensitivity coefficient of the compensation pixel (16-bit).
 35 #define MLX620_EE_TGC                 0xD8     //def MLX620_EE_TGC Thermal Gradient Coefficient.
 36 #define MLX620_EE_IROffsetBScale      0xD9     //def MLX620_EE_IROffsetBScale Scaling coefficient for slope of IR pixels offset.
 37 #define MLX620_EE_PtatVtho            0xDA     //def MLX620_EE_PtatVtho VTH0 of absolute temperature sensor (16-bit).
 38 #define MLX620_EE_PtatKT1             0xDC     //def MLX620_EE_PtatKT1 KT1 of absolute temperature sensor (16-bit).
 39 #define MLX620_EE_PtatKT2             0xDE     //def MLX620_EE_PtatKT2 KT2 of absolute temperature sensor (16-bit).
 40 #define MLX620_EE_IRCommonSens        0xE0     //def MLX620_EE_IRCommonSens Common sensitivity coefficient of IR pixels (16-bit).
 41 #define MLX620_EE_IRCommonSensScale   0xE2     //def MLX620_EE_IRCommonSensScale Scaling coefficient for common sensitivity.
 42 #define MLX620_EE_IRSensScale         0xE3     //def MLX620_EE_IRSensScale Scaling coefficient for individual sensitivity.
 43 #define MLX620_EE_Ke                  0xE4     //def MLX620_EE_Ke Emissivity  (16-bit).
 44 #define MLX620_EE_KsTa                0xE6     //def MLX620_EE_KsTa KsTa  (16-bit).
 45 #define MLX620_EE_MLX_Reserved2       0xE8     //def MLX620_EE_MLX_Reserved2 Melexis reserved part 2.
 46 #define MLX620_EE_ConfReg             0xF5     //def MLX620_EE_ConfReg Configuration register  (16-bit).
 47 #define MLX620_EE_OscTrim             0xF7     //def MLX620_EE_OscTrim Oscillator trim register (16-bit).
 48 #define MLX620_EE_ChipID              0xF8     //def MLX620_EE_ChipID Chip ID (64-bit).
 49 //---------------------------------------------------------------------------------------------------------------------------
 50 #define MLX620_IR_ROWS                4
 51 #define MLX620_IR_COLUMNS             16
 52 #define MLX620_IR_SENSORS             (MLX620_IR_ROWS * MLX620_IR_COLUMNS)
 53 #define MLX620_IR_SENSOR_IDX(row, col)((col) * MLX620_IR_COLUMNS + (row))
 54 //---------------------------------------------------------------------------------------------------------------------------
 55 #define MLX620_RAM_SIZE_WORDS         0xFF
 56 #define MLX620_RAM_SIZE_BYTES         (MLX620_RAM_SIZE_WORDS * 2)
 57 #define    MLX620_RAM_IR_BEG         0x0U
 58 #define    MLX620_RAM_IR_END         0x3F
 59 #define MLX620_RAM_PTAT             0x90
 60 #define MLX620_RAM_TGC             0x91
 61 #define MLX620_RAM_CONFIG         0x92
 62 #define    MLX620_RAM_TRIM             0x93
 63 //----------------------------------------------------------------------------------------------------------------------------
 64 #define MLX620_ADDR                     0x60
 65 #define MLX620_EEPROM_ADDR             0x50
 66 #define MLX620_CMD_START              0x801
 67 #define MLX620_CMD_READ               2
 68 #define MLX620_CMD_WRITE_CONFIG       3
 69 #define MLX620_CMD_WRITE_TRIM         4
 70 #define MLX620_CONFIG_FPS_IR_MASK(fps)       (((fps) & 0x0F) << 0)
 71 #define MLX620_CONFIG_MEAS_STEP_CONT_MASK     (1 << 6)
 72 #define MLX620_CONFIG_SLEEP_REQUEST_MASK     (1 << 7)
 73 #define MLX620_CONFIG_TA_MEAS_RUNNING_MASK     (1 << 8)
 74 #define MLX620_CONFIG_IR_MEAS_RUNNING_MASK     (1 << 9)
 75 #define MLX620_CONFIG_POR_BROUT_BIT_MASK     (1 << 10)
 76 #define MLX620_CONFIG_FMPLUS_ENABLE_MASK     (1 << 11)
 77 #define MLX620_CONFIG_FPS_PTAT_MASK(fps)    (((fps) & 0x03) << 12)
 78 #define MLX620_CONFIG_ADC_REFERENCE_MASK     (1 << 14)
 79 
 80 /*-----------------------------------------------------------------------------
 81                             extern
 82 -----------------------------------------------------------------------------*/
 83 
 84 /*-----------------------------------------------------------------------------
 85                         struct / enum / union
 86 -----------------------------------------------------------------------------*/
 87 
 88 /*-----------------------------------------------------------------------------
 89                             global
 90 -----------------------------------------------------------------------------*/
 91 uint8_t mlx620_rom_buff[MLX620_EE_SIZE_BYTES];
 92 uint16_t mlx620_ram_buff[MLX620_RAM_SIZE_WORDS];
 93 int8_t mlx620_ai[MLX620_IR_SENSORS];
 94 double mlx620_bi[MLX620_IR_SENSORS];
 95 double mlx620_alphai[MLX620_IR_SENSORS];
 96 double mlx620_dvtho;
 97 double mlx620_dkt1;
 98 double mlx620_dkt2;
 99 double mlx620_dlastta;
100 double mlx620_tgc;
101 double mlx620_cyclops_alpha;
102 double mlx620_cyclopsA;
103 double mlx620_cyclopsB;
104 double mlx620_ke;
105 double mlx620_cyclops_data;
106 double ir_tempK[MLX620_IR_SENSORS];
107 double ir_tempK_reference[MLX620_IR_SENSORS];
108 double ir_tempK_err[MLX620_IR_SENSORS] = {0};
109 
110 /*-----------------------------------------------------------------------------
111                             declare
112 -----------------------------------------------------------------------------*/
113 
114 /*-----------------------------------------------------------------------------
115                             function
116 -----------------------------------------------------------------------------*/
117 
118 /**
119  * @brief 延时 毫秒
120  *
121  * @param ms
122  */
123 static void delay_ms(int ms)
124 {
125     int i=0;
126     while(ms--)
127     {
128         for(i=0;i<0x1A80;i++);
129     }
130 }
131 
132 /**
133  * @brief IIC读取一个字节
134  *
135  * @param slave_addr
136  * @param reg
137  * @param val
138  * @return int8_t
139  */
140 int8_t mlx90620_read_byte(uint8_t slave_addr,uint8_t reg,uint8_t *val)
141 {
142     char buf[256] = {0};
143     struct i2c_client client = {0};
144     client.flags = 1;
145     client.addr = slave_addr;
146     strcpy(client.name,"mlx90620");
147     buf[0] = reg;
148     i2c_master_recv(IIC1,&client,buf,1);
149     *val = buf[0];
150     delay_ms(5);
151     return RETURN_OK;
152 }
153 
154 /**
155  * @brief IIC写一个字节
156  *
157  * @param slave_addr
158  * @param reg
159  * @param val
160  * @return int8_t
161  */
162 int8_t mlx90620_write_byte(uint8_t slave_addr,uint8_t reg,uint8_t val)
163 {
164     char buf[256] = {0};
165     struct i2c_client client = {0};
166     client.flags = 0;
167     client.addr = slave_addr;
168     strcpy(client.name,"mlx90620");
169     buf[0] = reg;
170     buf[1] = val;
171     i2c_master_send(IIC1,&client,buf,2);
172     delay_ms(5);
173     return RETURN_OK;
174 }
175 
176 /**
177  * @brief IIC读多个数据
178  *
179  * @param slave_addr
180  * @param reg
181  * @param data
182  * @param send_len
183  * @param rev_len
184  * @return int8_t
185  */
186 int8_t mlx90620_read_block(uint8_t slave_addr,uint8_t reg,uint8_t *data,
187                            uint32_t send_len,uint32_t rev_len)
188 {
189     char buf[300] = {0};
190     struct i2c_client client = {0};
191     client.flags = 1;
192     client.addr = slave_addr;
193     strcpy(client.name,"mlx90620");
194     buf[0] = reg;
195     memcpy(&buf[1],data,send_len);
196     i2c_master_recv_mlx(IIC1,&client,buf,send_len + 1,rev_len);
197     memcpy(data,buf,rev_len);
198     delay_ms(5);
199     return RETURN_OK;
200 }
201 
202 /**
203  * @brief IIC写多个数据
204  *
205  * @param slave_addr
206  * @param reg
207  * @param data
208  * @param len
209  * @return int8_t
210  */
211 int8_t mlx90620_write_block(uint8_t slave_addr,uint8_t reg,uint8_t *data,uint32_t len)
212 {
213     char buf[256] = {0};
214     struct i2c_client client = {0};
215     client.flags = 0;
216     client.addr = slave_addr;
217     strcpy(client.name,"mlx90620");
218     buf[0] = reg;
219     strncpy(&buf[1],(char const*)data,len);
220     i2c_master_send(IIC1,&client,buf,len + 1);
221     delay_ms(5);
222     return RETURN_OK;
223 }
224 
225 /**
226  * @brief 读取Trim
227  *
228  * @param data
229  * @return int8_t
230  */
231 int8_t mlx90620_read_trim(uint8_t *data)
232 {
233     data[0] = MLX620_RAM_TRIM;
234     data[1] = 0x00;
235     data[2] = 0x01;
236     mlx90620_read_block(MLX620_ADDR,MLX620_CMD_READ,data,3,2);
237     return RETURN_OK;
238 }
239 
240 /**
241  * @brief 配置Trim
242  *
243  * @param data
244  * @return int8_t
245  */
246 int8_t mlx90620_write_trim(uint16_t data)
247 {
248     uint8_t buf[] = {
249         (uint8_t)((data & 0xFF) - 0xAA),
250         (uint8_t)(data & 0xFF),
251         (uint8_t)((data >> 8) - 0xAA),
252         (uint8_t)(data >> 8)
253     };
254     mlx90620_write_block(MLX620_ADDR,MLX620_CMD_WRITE_TRIM,
255                          buf,sizeof(buf));
256     return RETURN_OK;
257 }
258 
259 /**
260  * @brief 读取config
261  *
262  * @param data
263  * @return int8_t
264  */
265 int8_t mlx90620_read_config(uint8_t *data)
266 {
267     data[0] = MLX620_RAM_CONFIG;
268     data[1] = 0x00;
269     data[2] = 0x01;
270     mlx90620_read_block(MLX620_ADDR,MLX620_CMD_READ,data,3,2);
271     return RETURN_OK;
272 }
273 
274 /**
275  * @brief 配置config
276  *
277  * @param data
278  * @return int8_t
279  */
280 int8_t mlx90620_write_config(uint16_t data)
281 {
282     uint8_t buf[] = {
283         (uint8_t)((data & 0xFF) - 0x55),
284         (uint8_t)(data & 0xFF),
285         (uint8_t)((data >> 8) - 0x55),
286         (uint8_t)(data >> 8)
287     };
288     mlx90620_write_block(MLX620_ADDR,MLX620_CMD_WRITE_CONFIG,
289                          buf,sizeof(buf));
290     return RETURN_OK;
291 }
292 
293 /**
294  * @brief 读取EEPROM数据
295  *
296  * @param addr
297  * @param len
298  * @param data
299  * @return int8_t
300  */
301 int8_t mlx90620_read_eeprom(uint8_t addr,uint8_t len,uint8_t* data)
302 {
303     return mlx90620_read_block(MLX620_EEPROM_ADDR,addr,data,0,len);
304 }
305 
306 /**
307  * @brief 读取RAM数据
308  *
309  * @param addr
310  * @param step
311  * @param len
312  * @param buf
313  * @return int8_t
314  */
315 int8_t mlx90620_read_ram(uint8_t addr,uint8_t step,uint32_t len,uint8_t *buf)
316 {
317     uint8_t data[300] = {0};
318     data[0] = addr;
319     data[1] = step;
320     data[2] = len;
321     mlx90620_read_block(MLX620_ADDR,MLX620_CMD_READ,data,3,2 * len);
322     memcpy(buf,data,2* len);
323     return RETURN_OK;
324 }
325 
326 /**
327  * @brief 计算TO
328  *
329  * @param idxIr
330  * @param data
331  * @return double
332  */
333 double mlx620_calc_tokelvin(int idxIr, int16_t data)
334 {
335     if (fabs(mlx620_alphai[idxIr]) < 1e-10)
336     {
337         return 0;
338     }
339     double dt = mlx620_dlastta + 273.15;    //convert to Kelvin
340     dt *= dt;
341     dt *= dt;   //power of 4
342     double d = (data - (mlx620_ai[idxIr] + mlx620_bi[idxIr] * (mlx620_dlastta - 25))
343                 - mlx620_cyclops_data) /(mlx620_ke * mlx620_alphai[idxIr]) + dt;
344     if (d < 0)
345     {
346         return 0;
347     }
348     double dTo = pow(d, 0.25) - 273.15;    //4th square
349     return dTo;
350 }
351 
352 /**
353  * @brief 偏移量抵消计算
354  *
355  * @param pFrame
356  * @param start
357  * @param step
358  * @param count
359  * @param pIR
360  */
361 void mlx620_compensate_ir(int16_t* pFrame, int start, int step, int count, double *pIR)
362 {
363     //compensates full RAM buffer
364 
365     if (step == 0)
366     {
367         step = 1;
368     }
369     int end = start + count * step;
370     // check which part of the the IR array is read -> compensate To
371     if (start < MLX620_RAM_IR_BEG + MLX620_IR_SENSORS && end > MLX620_RAM_IR_BEG)
372     {
373         int irStart = (MLX620_RAM_IR_BEG - start) / step;
374         if (irStart < 0)
375         {
376             irStart = 0;
377         }
378         int irEnd = (MLX620_RAM_IR_BEG + MLX620_IR_SENSORS - start) / step;
379         if (irEnd > count)
380         {
381             irEnd = count;
382         }
383         int caddr = start + irStart * step;
384         irEnd -= irStart;
385         for (int i = 0; i < irEnd; ++i)
386         {
387             pIR[i] = mlx620_calc_tokelvin(caddr - MLX620_RAM_IR_BEG, pFrame[i]);
388             caddr += step;
389         }
390     }
391 }
392 
393 /**
394  * @brief 计算ta摄氏温度
395  *
396  * @param ptat
397  * @return uint32_t
398  */
399 uint32_t mlx620_calc_ta(int16_t ptat)
400 {
401     if (fabs(mlx620_dkt2) < 1e-10 || fabs(mlx620_dvtho) < 1e-10)
402     {
403         return 1;
404     }
405     double d = (mlx620_dkt1*mlx620_dkt1 - 4 * mlx620_dkt2 * (1 - ptat / mlx620_dvtho));
406     if (d < 0)
407     {
408         return 1;
409     }
410     mlx620_dlastta = ((-mlx620_dkt1 +  sqrt(d)) / (2 * mlx620_dkt2)) + 25;
411     return 0;
412 }
413 
414 /**
415  * @brief 得到绝对温度TA
416  *
417  * @param ptat
418  * @return double
419  */
420 double mlx620_get_takelvin (int16_t ptat)
421 {
422     mlx620_calc_ta(ptat);
423     return mlx620_dlastta;
424 }
425 
426 /**
427  * @brief 计算一些参数
428  *
429  */
430 void mlx620_calc_common_params(void)
431 {
432     uint16_t   val16;
433     uint8_t   val8;
434     int8_t   s_val8;
435     uint8_t   *ptr8;
436     double dOffsetBScale;
437     double dScaleComAlpha = 1;
438     double dScaleAlpha = 1;
439     double dCommonAlpha;
440 
441     ptr8 = mlx620_rom_buff;
442 
443     //  Vth(25) 16 signed
444     memcpy(&val16, ptr8 + MLX620_EE_PtatVtho, sizeof(val16));
445     mlx620_dvtho = (double)((int16_t)val16);
446 
447     //  kT1 16 bit signed * 2^10
448     memcpy(&val16, ptr8 + MLX620_EE_PtatKT1, sizeof(val16));
449     mlx620_dkt1 = (double)((int16_t)val16) / (1 << 10);
450 
451     //  kT2 16 bit signed * 2^20
452     memcpy(&val16, ptr8 + MLX620_EE_PtatKT2, sizeof(val16));
453     mlx620_dkt2 = (double)((int16_t)val16) / (1 << 20);
454 
455     // Thermal Gradient Gompensation coefficient - mlx620_tgc
456     memcpy(&s_val8, ptr8 + MLX620_EE_TGC, sizeof(s_val8));
457     mlx620_tgc = s_val8 / 32.0;
458 
459     // Cyclops alpha
460     memcpy(&val16, ptr8 + MLX620_EE_CyclopsAlpha, sizeof(val16));
461     mlx620_cyclops_alpha = val16;
462 
463     memcpy(&val8, ptr8 + MLX620_EE_IROffsetBScale, sizeof(val8));
464     dOffsetBScale = pow(2, val8);
465 
466     // cyclops A & B
467     memcpy(&s_val8, ptr8 + MLX620_EE_CyclopsA, sizeof(s_val8));
468     mlx620_cyclopsA = s_val8;
469 
470     memcpy(&s_val8, ptr8 + MLX620_EE_CyclopsB, sizeof(s_val8));
471     mlx620_cyclopsB = s_val8 / dOffsetBScale;
472 
473     memcpy(&val8, ptr8 + MLX620_EE_IRCommonSensScale, sizeof(val8));
474     dScaleComAlpha = pow(2, val8);
475 
476     memcpy(&val8, ptr8 + MLX620_EE_IRSensScale, sizeof(val8));
477     dScaleAlpha = pow(2, val8);
478 
479     memcpy(&val16, ptr8 + MLX620_EE_Ke, sizeof(val16));
480     mlx620_ke = (double)val16 / 32768.0;
481 
482     memcpy(&val16, ptr8 + MLX620_EE_IRCommonSens, sizeof(val16));
483     dCommonAlpha = (double)val16 / dScaleComAlpha;
484 
485     // Ai, Bi and mlx620_alphai
486     for (int i = 0; i < MLX620_IR_SENSORS; ++i)
487     {
488         memcpy(&val8, ptr8 + (MLX620_EE_IROffsetAi00 + i), sizeof(val8));
489         mlx620_ai[i] = (int8_t)val8;
490 
491         memcpy(&val8, ptr8 + (MLX620_EE_IROffsetBi00 + i), sizeof(val8));
492         mlx620_bi[i] = (double)((int8_t)val8) / dOffsetBScale;
493 
494         memcpy(&val8, ptr8 + (MLX620_EE_IRSens00 + i), sizeof(val8));
495         mlx620_alphai[i] = (double)val8 / dScaleAlpha + dCommonAlpha;
496     }
497 }
498 
499 /**
500  * @brief 计算TGC
501  *
502  * @param tgc
503  */
504 void mlx620_calc_tgc(int16_t tgc)
505 {
506   mlx620_cyclops_data = mlx620_tgc * (tgc - (mlx620_cyclopsA + mlx620_cyclopsB * (mlx620_dlastta - 25)));
507 }
508 
509 /**
510  * @brief 计算温度
511  *
512  * @param pIRtempK
513  * @param Ta
514  * @return uint8_t
515  */
516 uint8_t mlx90620_measure_temperature(double *pIRtempK, double *Ta)
517 {
518     int16_t ptat, tgc;
519     mlx90620_read_ram(MLX620_RAM_PTAT, 0, 1, (uint8_t*)&ptat);
520     *Ta = mlx620_get_takelvin (ptat);
521     mlx90620_read_ram(MLX620_RAM_TGC, 0, 1, (uint8_t*)&tgc);
522     mlx620_calc_tgc(tgc);
523     mlx90620_read_ram(MLX620_RAM_IR_BEG, 1, MLX620_IR_SENSORS, (uint8_t*)mlx620_ram_buff);
524     mlx620_compensate_ir((int16_t*)mlx620_ram_buff, MLX620_RAM_IR_BEG, 1, MLX620_IR_SENSORS, pIRtempK);
525     return RETURN_OK;
526 }
527 
528 /**
529  * @brief 初始化
530  *
531  */
532 void mlx90620_init(void)
533 {
534     uint16_t trimReg = 0;
535     uint16_t confReg = 0;
536 
537     mlx90620_read_eeprom(0x00,0xFF,mlx620_rom_buff);
538     trimReg = mlx620_rom_buff[0xF7];
539     confReg = (mlx620_rom_buff[0xF6] << 8) | (mlx620_rom_buff[0xF5]);
540     mprintf("trimReg = 0x%x
confReg = 0x%x
",trimReg,confReg);
541     if((0 == trimReg) || (0xFF == trimReg))
542     {
543         mlx90620_write_trim(85);
544     }
545     else
546     {
547         mlx90620_write_trim(trimReg);
548     }
549     if((0 == confReg) || (0xFF == confReg))
550     {
551         mlx90620_write_config(0x745E);
552     }
553     else
554     {
555         mlx90620_write_config(confReg);
556     }
557     while(!((confReg >> 10) & 0x1))
558     {
559         mlx90620_read_trim((uint8_t*)&trimReg);
560         mlx90620_read_config((uint8_t*)&confReg);
561         mprintf("trimReg = 0x%x
confReg = 0x%x
",trimReg,confReg);
562     }
563     mprintf("MLX90620 init success
");
564     mlx620_calc_common_params();
565 }
566 
567 /**
568  * @brief 打开 mlx90620
569  *
570  * @param APDS-9960 init
571  * @retval RETURN_OK
572  * @retval RETURN_ERR
573  */
574 int32_t mlx90620_open(void)
575 {
576     NVIC_EnableIRQ(IIC1_IRQn);
577     Scu_SetDeviceGate((unsigned int)IIC1,ENABLE);
578     Scu_Setdevice_Reset((unsigned int)IIC1);
579     Scu_Setdevice_ResetRelease((unsigned int)IIC1);
580     Scu_SetIOReuse(I2C1_SCL_PAD,FIRST_FUNCTION);
581     Scu_SetIOReuse(I2C1_SDA_PAD,FIRST_FUNCTION);
582 
583     I2C_InitStruct InitStruct = {0};
584     InitStruct.I2C_IO_BASE = (unsigned int)IIC1;
585     InitStruct.I2C_CLOCK_SPEED = 100;
586     InitStruct.I2C_INPUT_CLK = 50000000;
587     InitStruct.TIMEOUT = 0X5FFFFF;
588     i2c_init(IIC1,&InitStruct);
589     double Ta = 0;
590     mlx90620_init();
591     mlx90620_measure_temperature(ir_tempK_reference, &Ta);
592     return RETURN_OK;
593 }
594 
595 /**
596  * @brief 读测量数据
597  *
598  * @param data
599  * @return int32_t
600  */
601 int32_t mlx90620_read(sensor_data_t *data)
602 {
603     uint16_t confReg = 0;
604     double Ta = 0;
605     while(!((confReg >> 10) & 0x1))
606     {
607         mlx90620_read_config((uint8_t*)&confReg);;
608     }
609     mlx90620_measure_temperature(ir_tempK, &Ta);
610     sensor_data_inform(SENSOR_TYPE_INFRARED_ARRAY);
611     for(int i = 0;i < MLX620_IR_SENSORS;i++)
612     {
613         data->infrared_array[i] = (ir_tempK[i] - ir_tempK_reference[i]) + Ta;
614     }
615     return RETURN_OK;
616 }
617 
618 /**
619  * @brief mlx90620 ops
620  *
621  */
622 sensor_ops_t mlx90620_ops =
623 {
624     mlx90620_open,
625     mlx90620_read,
626 };
627 
628 /*-----------------------------------------------------------------------------
629                             end of the file
630 -----------------------------------------------------------------------------*/

MLX_90620.h

 1 /**
 2  * @file MLX_90620.h
 3  * @brief MLX_90620传感器的头文件
 4  * @version 0.1
 5  * @date 2019-07-02
 6  *
 7  * @copyright Copyright (c) 2019  Chipintelli Technology Co., Ltd.
 8  *
 9  */
10 
11 #ifndef __MLX_90620_H__
12 #define __MLX_90620_H__
13 
14 /**
15  * @ingroup third_device_driver
16  * @defgroup MLX90620
17  * @brief MLX90620传感器驱动
18  * @{
19  */
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /*-----------------------------------------------------------------------------
26                             include
27 -----------------------------------------------------------------------------*/
28 
29 /*-----------------------------------------------------------------------------
30                             define
31 -----------------------------------------------------------------------------*/
32 
33 /*-----------------------------------------------------------------------------
34                             extern
35 -----------------------------------------------------------------------------*/
36 extern sensor_ops_t mlx90620_ops;
37 
38 /*-----------------------------------------------------------------------------
39                         struct / enum / union
40 -----------------------------------------------------------------------------*/
41 
42 /*-----------------------------------------------------------------------------
43                             global
44 -----------------------------------------------------------------------------*/
45 
46 /*-----------------------------------------------------------------------------
47                         function declare
48 -----------------------------------------------------------------------------*/
49 
50 #ifdef __cplusplus
51 }
52 #endif
53 
54 /**
55  * @}
56  */
57 
58 #endif
59 
60 /*-----------------------------------------------------------------------------
61                             end of the file
62 -----------------------------------------------------------------------------*/
原文地址:https://www.cnblogs.com/wangyanwen/p/11451586.html