zoukankan      html  css  js  c++  java
  • 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 -----------------------------------------------------------------------------*/
  • 相关阅读:
    两个栈实现一个队列
    DacningLinks实现
    boost::implicit_cast
    hibernate查询之Criteria实现分页方法(GROOVY语法)
    VS2015 android 设计器不能可视化问题解决。
    当Eclipse爱上SVN
    你不知道的getComputedStyle
    推荐的软件
    React之表单
    理解javascript中的Function.prototype.bind
  • 原文地址:https://www.cnblogs.com/wangyanwen/p/11451586.html
Copyright © 2011-2022 走看看