1
0

mlx90614.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include "mlx90614.h"
  2. #include "smbus.h"
  3. #include "iot_gpio.h"
  4. #include "iot_gpio_ex.h"
  5. #define WIFI_IOT_IO_NAME_GPIO_7 7
  6. #define WIFI_IOT_IO_NAME_GPIO_14 14
  7. #define WIFI_IOT_IO_NAME_GPIO_10 10
  8. #define WIFI_IOT_IO_NAME_GPIO_12 12
  9. #define WIFI_IOT_I2C_IDX_1 1
  10. uint8_t RxBuffer[3];
  11. #define BEEP_GPIO 8
  12. void MLX90614_Init(void)
  13. {
  14. IoTGpioInit(BEEP_GPIO);
  15. IoTGpioSetFunc(BEEP_GPIO, IOT_GPIO_FUNC_GPIO_8_GPIO);
  16. IoTGpioSetDir(BEEP_GPIO, IOT_GPIO_DIR_OUT); //设置为输出模式
  17. IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_10);
  18. IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_10, IOT_GPIO_FUNC_GPIO_10_GPIO);
  19. IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_10, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
  20. IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_12);
  21. IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_12, IOT_GPIO_FUNC_GPIO_12_GPIO);
  22. IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_12, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
  23. IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_14);
  24. IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_FUNC_GPIO_14_GPIO);
  25. IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_14, IOT_GPIO_DIR_OUT); // 设置GPIO_14为输出模式
  26. IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_7);
  27. IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_7, IOT_GPIO_FUNC_GPIO_7_GPIO);
  28. IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_7, IOT_GPIO_DIR_OUT); // 设置GPIO_7为输出模式
  29. }
  30. /*******************************************************************************
  31. * 函数名: PEC_calculation
  32. * 功能 : 数据校验
  33. * Input : pec[]
  34. * Output : None
  35. * Return : pec[0]-this byte contains calculated crc value
  36. *******************************************************************************/
  37. uint8_t PEC_Calculation(uint8_t pec[])
  38. {
  39. uint8_t crc[6];
  40. uint8_t BitPosition=47;
  41. uint8_t shift;
  42. uint8_t i;
  43. uint8_t j;
  44. uint8_t temp;
  45. do
  46. {
  47. /*Load pattern value 0x000000000107*/
  48. crc[5]=0;
  49. crc[4]=0;
  50. crc[3]=0;
  51. crc[2]=0;
  52. crc[1]=0x01;
  53. crc[0]=0x07;
  54. /*Set maximum bit position at 47 ( six bytes byte5...byte0,MSbit=47)*/
  55. BitPosition=47;
  56. /*Set shift position at 0*/
  57. shift=0;
  58. /*Find first "1" in the transmited message beginning from the MSByte byte5*/
  59. i=5;
  60. j=0;
  61. while((pec[i]&(0x80>>j))==0 && i>0)
  62. {
  63. BitPosition--;
  64. if(j<7)
  65. {
  66. j++;
  67. }
  68. else
  69. {
  70. j=0x00;
  71. i--;
  72. }
  73. }/*End of while */
  74. /*Get shift value for pattern value*/
  75. shift=BitPosition-8;
  76. /*Shift pattern value */
  77. while(shift)
  78. {
  79. for(i=5; i<0xFF; i--)
  80. {
  81. if((crc[i-1]&0x80) && (i>0))
  82. {
  83. temp=1;
  84. }
  85. else
  86. {
  87. temp=0;
  88. }
  89. crc[i]<<=1;
  90. crc[i]+=temp;
  91. }/*End of for*/
  92. shift--;
  93. }/*End of while*/
  94. /*Exclusive OR between pec and crc*/
  95. for(i=0; i<=5; i++)
  96. {
  97. pec[i] ^=crc[i];
  98. }/*End of for*/
  99. }
  100. while(BitPosition>8); /*End of do-while*/
  101. return pec[0];
  102. }
  103. /*******************************************************************************
  104. * 函数名: SMBus_ReadMemory
  105. * 功能: READ DATA FROM RAM/EEPROM
  106. * Input : slaveAddress, command
  107. * Return : Data
  108. *******************************************************************************/
  109. uint16_t SMBus_ReadMemory(uint8_t slaveAddress, uint8_t command)
  110. {
  111. uint16_t data; // Data storage (DataH:DataL)
  112. uint8_t Pec; // PEC byte storage
  113. uint8_t DataL=0; // Low data byte storage
  114. uint8_t DataH=0; // High data byte storage
  115. uint8_t arr[6]; // Buffer for the sent bytes
  116. uint8_t PecReg; // Calculated PEC byte storage
  117. uint8_t ErrorCounter; // Defines the number of the attempts for communication with MLX90614
  118. ErrorCounter=0x00; // Initialising of ErrorCounter
  119. slaveAddress <<= 1; //2-7位表示从机地址
  120. do
  121. {
  122. repeat:
  123. SMBus_Stop(); //If slave send NACK stop comunication
  124. --ErrorCounter; //Pre-decrement ErrorCounter
  125. if(!ErrorCounter) //ErrorCounter=0?
  126. {
  127. break; //Yes,go out from do-while{}
  128. }
  129. SMBus_Start(); //Start condition
  130. if(SMBus_SendByte(slaveAddress))//Send SlaveAddress 最低位Wr=0表示接下来写命令
  131. {
  132. goto repeat; //Repeat comunication again
  133. }
  134. if(SMBus_SendByte(command)) //Send command
  135. {
  136. goto repeat; //Repeat comunication again
  137. }
  138. SMBus_Start(); //Repeated Start condition
  139. if(SMBus_SendByte(slaveAddress+1)) //Send SlaveAddress 最低位Rd=1表示接下来读数据
  140. {
  141. goto repeat; //Repeat comunication again
  142. }
  143. DataL = SMBus_ReceiveByte(ACK); //Read low data,master must send ACK
  144. DataH = SMBus_ReceiveByte(ACK); //Read high data,master must send ACK
  145. Pec = SMBus_ReceiveByte(NACK); //Read PEC byte, master must send NACK
  146. SMBus_Stop(); //Stop condition
  147. arr[5] = slaveAddress; //
  148. arr[4] = command; //
  149. arr[3] = slaveAddress+1; //Load array arr
  150. arr[2] = DataL; //
  151. arr[1] = DataH; //
  152. arr[0] = 0; //
  153. PecReg=PEC_Calculation(arr);//Calculate CRC
  154. }
  155. while(PecReg != Pec); //If received and calculated CRC are equal go out from do-while{}
  156. data = (DataH<<8) | DataL; //data=DataH:DataL
  157. return data;
  158. }
  159. /***************************************************************************
  160. * @brief Read object temperature(Tobj) from RAM registers of MLX90614
  161. * @param ambient_or_object : Which temperature you want to get
  162. * @retval Object temperature
  163. ****************************************************************************/
  164. float MLX90614_Read_TempData(uint8_t ambient_or_object)
  165. {
  166. return SMBus_ReadMemory(MLX90614_ADDR_WRITE, ambient_or_object)*0.02-273.15;
  167. }
  168. /***************************************************************
  169. * 函数名称: LedSafeStatusSet
  170. * 说 明: LED_Safe状态设置
  171. * 参 数: status,ENUM枚举的数据
  172. * OFF,关
  173. * ON,开
  174. * 返 回 值: 无
  175. ***************************************************************/
  176. void LedSafeStatusSet(SwitchStatus status)
  177. {
  178. if (status == ON) {
  179. IoTGpioSetOutputVal(7, 1); // 设置GPIO_7输出高电平点亮灯
  180. }
  181. if (status == OFF) {
  182. IoTGpioSetOutputVal(7, 0); // 设置GPIO_7输出低电平关闭灯
  183. }
  184. }
  185. /***************************************************************
  186. * 函数名称: LedWarnStatusSet
  187. * 说 明: LED_Warn状态设置
  188. * 参 数: status,ENUM枚举的数据
  189. * OFF,关
  190. * ON,开
  191. * 返 回 值: 无
  192. ***************************************************************/
  193. void LedWarnStatusSet(SwitchStatus status)
  194. {
  195. if (status == ON) {
  196. IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 1); // 设置GPIO_14输出高电平点亮灯
  197. }
  198. if (status == OFF) {
  199. IoTGpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 0); // 设置GPIO_14输出低电平关闭灯
  200. }
  201. }
  202. /***************************************************************
  203. * 函数名称: BeepStatusSet
  204. * 说 明: Beep状态设置
  205. * 参 数: status,ENUM枚举的数据
  206. * OFF,关
  207. * ON,开
  208. * 返 回 值: 无
  209. ***************************************************************/
  210. void BeepStatusSet(SwitchStatus status)
  211. {
  212. if (status == ON) {
  213. IoTGpioSetOutputVal(BEEP_GPIO, 1); // 设置GPIO_7输出高电平点亮灯
  214. }
  215. if (status == OFF) {
  216. IoTGpioSetOutputVal(BEEP_GPIO, 0); // 设置GPIO_7输出低电平关闭灯
  217. }
  218. }