max31856.lua 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. --[[
  2. @module max31856
  3. @summary max31856 热电偶温度检测
  4. @version 1.0
  5. @date 2024.06.17
  6. @author Dozingfiretruck
  7. @usage
  8. --注意:因使用了sys.wait()所有api需要在协程中使用
  9. --注意:ads1115的配置需按照项目需求配置,您需要按照配置寄存器说明重新配置 ADS1115_CONF_HCMD 和 ADS1115_CONF_LCMD !!!
  10. -- 用法实例
  11. max31856 = require("max31856")
  12. sys.taskInit(function()
  13. max31856_spi_device = spi.deviceSetup(1,pin.PB11,1,1,8,5*1000*1000,spi.MSB,1,0)
  14. max31856.init(max31856_spi_device)
  15. while 1 do
  16. local cj_temp = max31856.read_cj_temp()
  17. if cj_temp then
  18. log.info("max31856 cj_temp: ", cj_temp)
  19. end
  20. local tc_temp = max31856.read_tc_temp()
  21. if tc_temp then
  22. log.info("max31856 tc_temp: ", tc_temp)
  23. end
  24. log.info("max31856 fault: ", max31856.read_fault())
  25. sys.wait(1000)
  26. end
  27. end)
  28. ]]
  29. --[[
  30. Register Memory Map
  31. ADDRESS READ/WRITE NAME FACTORY FUNCTION
  32. DEFAULT
  33. 00h/80h Read/Write CR0 00h Configuration 0 Register
  34. 01h/81h Read/Write CR1 03h Configuration 1 Register
  35. 02h/82h Read/Write MASK FFh Fault Mask Register
  36. 03h/83h Read/Write CJHF 7Fh Cold-Junction High Fault Threshold
  37. 04h/84h Read/Write CJLF C0h Cold-Junction Low Fault Threshold
  38. 05h/85h Read/Write LTHFTH 7Fh Linearized Temperature High Fault Threshold MSB
  39. 06h/86h Read/Write LTHFTL FFh Linearized Temperature High Fault Threshold LSB
  40. 07h/87h Read/Write LTLFTH 80h Linearized Temperature Low Fault Threshold MSB
  41. 08h/88h Read/Write LTLFTL 00h Linearized Temperature Low Fault Threshold LSB
  42. 09h/89h Read/Write CJTO 00h Cold-Junction Temperature Offset Register
  43. 0Ah/8Ah Read/Write CJTH 00h Cold-Junction Temperature Register, MSB
  44. 0Bh/8Bh Read/Write CJTL 00h Cold-Junction Temperature Register, LSB
  45. 0Ch Read Only LTCBH 00h Linearized TC Temperature, Byte 2
  46. 0Dh Read Only LTCBM 00h Linearized TC Temperature, Byte 1
  47. 0Eh Read Only LTCBL 00h Linearized TC Temperature, Byte 0
  48. 0Fh Read Only SR 00h Fault Status Register
  49. ]]
  50. local max31856 = {}
  51. local sys = require "sys"
  52. max31856.TCTYPE_B = 0x00 -- 类型B
  53. max31856.TCTYPE_E = 0x01 -- 类型E
  54. max31856.TCTYPE_J = 0x02 -- 类型J
  55. max31856.TCTYPE_K = 0x03 -- 类型K
  56. max31856.TCTYPE_N = 0x04 -- 类型N
  57. max31856.TCTYPE_R = 0x05 -- 类型R
  58. max31856.TCTYPE_S = 0x06 -- 类型S
  59. max31856.TCTYPE_T = 0x07 -- 类型T
  60. max31856.ONESHOT = 0x00 -- 单次转换模式
  61. max31856.CONTINUOUS = 0x01 -- 自动转换模式
  62. max31856.SAMPLE1 = 0x00 -- 1个样品
  63. max31856.SAMPLE2 = 0x01 -- 2个样品
  64. max31856.SAMPLE4 = 0x02 -- 4个样品
  65. max31856.SAMPLE8 = 0x03 -- 8个样品
  66. max31856.SAMPLE16 = 0x04 -- 16个样品
  67. local MAX31856_CR0_REG = 0x00 -- 配置寄存器0
  68. local MAX31856_CR1_REG = 0x01 -- 配置寄存器1
  69. local MAX31856_MASK_REG = 0x02 -- 故障屏蔽寄存器
  70. local MAX31856_CJHF_REG = 0x03 -- 冷端上限故障
  71. local MAX31856_CJLF_REG = 0x04 -- 冷接下限故障
  72. local MAX31856_LTHFTH_REG = 0x05 -- 线性化温度上限故障 MSB
  73. local MAX31856_LTHFTL_REG = 0x06 -- 线性化温度上限故障 LSB
  74. local MAX31856_LTLFTH_REG = 0x07 -- 线性化温度下限故障 MSB
  75. local MAX31856_LTLFTL_REG = 0x08 -- 线性化温度下限故障 LSB
  76. local MAX31856_CJTO_REG = 0x09 -- 冷端温度偏移寄存器
  77. local MAX31856_CJTH_REG = 0x0A -- 冷端温度寄存器 MSB
  78. local MAX31856_CJTL_REG = 0x0B -- 冷端温度寄存器 LSB
  79. local MAX31856_LTCBH_REG = 0x0C -- 线性化TC温度,字节2
  80. local MAX31856_LTCBM_REG = 0x0D -- 线性化TC温度,字节1
  81. local MAX31856_LTCBL_REG = 0x0E -- 线性化TC温度,字节0
  82. local MAX31856_SR_REG = 0x0F -- 故障状态寄存器
  83. local max31856_spi_device
  84. local max31856_conversion_mode
  85. local max31856_sample_mode
  86. local function max31856_write_cmd(reg, data)
  87. -- log.info("max31856_write_cmd "..(reg|0x80).." "..data)
  88. max31856_spi_device:send({reg|0x80, data})
  89. end
  90. local function max31856_read_cmd(reg)
  91. local data = max31856_spi_device:transfer(string.char(reg))
  92. -- log.info("max31856_read_cmd "..reg.." "..data:byte())
  93. return data:byte()
  94. end
  95. local function trigger_oneshot()
  96. local cr0 = max31856_read_cmd(MAX31856_CR0_REG)
  97. cr0 = cr0&(~0x80)
  98. cr0 = cr0|0x40
  99. max31856_write_cmd(MAX31856_CR0_REG, cr0)
  100. end
  101. local function oneshot_conversion_complete()
  102. return (max31856_read_cmd(MAX31856_CR0_REG) & 0x40) == 0
  103. end
  104. --[[
  105. 设置热电偶类型
  106. @api max31856.set_tc_type(type)
  107. @number type max31856.TCTYPE_B max31856.TCTYPE_E max31856.TCTYPE_J max31856.TCTYPE_K max31856.TCTYPE_N max31856.TCTYPE_R max31856.TCTYPE_S max31856.TCTYPE_T
  108. @usage
  109. max31856.set_tc_type(max31856.TCTYPE_K) -- 设置类型为K
  110. ]]
  111. function max31856.set_tc_type(type)
  112. local cr1 = max31856_read_cmd(MAX31856_CR1_REG)
  113. cr1 = cr1&0xF0
  114. max31856_write_cmd(MAX31856_CR1_REG, cr1|type)
  115. end
  116. --[[
  117. 设置热电偶电压转换平均模式
  118. @api max31856.set_avgsel(sample_count)
  119. @number sample_count max31856.SAMPLE1 max31856.SAMPLE2 max31856.SAMPLE4 max31856.SAMPLE8 max31856.SAMPLE16
  120. @usage
  121. max31856.set_avgsel(max31856.SAMPLE1) -- 设置平均模式为1个样品
  122. ]]
  123. function max31856.set_avgsel(sample_count)
  124. max31856_sample_mode = sample_count
  125. local cr1 = max31856_read_cmd(MAX31856_CR1_REG)
  126. max31856_write_cmd(MAX31856_CR1_REG, cr1|(sample_count<<4))
  127. end
  128. --[[
  129. 设置转化模式
  130. @api max31856.set_cmode(type)
  131. @number type max31856.ONESHOT max31856.CONTINUOUS
  132. @usage
  133. max31856.set_cmode(max31856.ONESHOT) -- 设置转化模式为单次转换
  134. ]]
  135. function max31856.set_cmode(type)
  136. max31856_conversion_mode = type
  137. local cr0 = max31856_read_cmd(MAX31856_CR0_REG)
  138. if type == max31856.ONESHOT then
  139. cr0 = cr0&(~0x80)
  140. cr0 = cr0|0x40
  141. else
  142. cr0 = cr0|0x80
  143. cr0 = cr0&(~0x40)
  144. end
  145. max31856_write_cmd(MAX31856_CR0_REG, cr0)
  146. end
  147. --[[
  148. 读取错误码
  149. @api max31856.read_fault()
  150. @return number 错误码
  151. @usage
  152. local fault = max31856.read_fault()
  153. ]]
  154. function max31856.read_fault()
  155. return max31856_read_cmd(MAX31856_SR_REG)
  156. end
  157. --[[
  158. 读取冷端温度
  159. @api max31856.read_cj_temp()
  160. @return number 冷端温度
  161. @usage
  162. local cj_temp = max31856.read_cj_temp()
  163. ]]
  164. function max31856.read_cj_temp()
  165. if max31856_conversion_mode == max31856.ONESHOT then
  166. trigger_oneshot()
  167. sys.wait(145+(max31856_sample_mode-1)*33)
  168. local wait = 20
  169. while oneshot_conversion_complete() == false do
  170. sys.wait(10)
  171. wait = wait - 1
  172. if wait == 0 then return end
  173. end
  174. end
  175. local CJTH = max31856_read_cmd(MAX31856_CJTH_REG)
  176. local CJTL = max31856_read_cmd(MAX31856_CJTL_REG)
  177. return ((CJTH<<8)|CJTL) / 256.0
  178. end
  179. --[[
  180. 读取tc温度
  181. @api max31856.read_tc_temp()
  182. @return number tc温度
  183. @usage
  184. local tc_temp = max31856.read_tc_temp()
  185. ]]
  186. function max31856.read_tc_temp()
  187. if max31856_conversion_mode == max31856.ONESHOT then
  188. trigger_oneshot()
  189. sys.wait(145+(max31856_sample_mode-1)*33)
  190. local wait = 20
  191. while oneshot_conversion_complete() == false do
  192. sys.wait(10)
  193. wait = wait - 1
  194. if wait == 0 then return end
  195. end
  196. end
  197. local LTCBH = max31856_read_cmd(MAX31856_LTCBH_REG)
  198. local LTCBM = max31856_read_cmd(MAX31856_LTCBM_REG)
  199. local LTCBL = max31856_read_cmd(MAX31856_LTCBL_REG)
  200. local temp24 = (LTCBH<<16)|(LTCBM<<8)|LTCBL
  201. if temp24 & 0x800000 ~= 0 then
  202. temp24 = temp24 | 0xFF000000
  203. end
  204. temp24 = temp24 >> 5
  205. return temp24 * 0.0078125
  206. end
  207. --[[
  208. max31856 初始化
  209. @api max31856.init(spi_device)
  210. @userdata spi_device spi设备句柄
  211. @return boolean 初始化成功返回true
  212. @usage
  213. max31856.init(spi_device)
  214. ]]
  215. function max31856.init(spi_device)
  216. if type(spi_device) ~= "userdata" then
  217. return
  218. end
  219. max31856_spi_device = spi_device
  220. max31856_write_cmd(MAX31856_MASK_REG, 0x00) -- 断言所有错误
  221. max31856_write_cmd(MAX31856_CR0_REG, 0x10) -- 开启开路故障检测
  222. max31856_write_cmd(MAX31856_CJTO_REG, 0x00) -- 冷端温度偏移设置为零
  223. max31856.set_tc_type(max31856.TCTYPE_K) -- 设置类型为K
  224. max31856.set_cmode(max31856.ONESHOT) -- 设置转化模式为单次转换
  225. max31856.set_avgsel(max31856.SAMPLE1) -- 设置平均模式为1个样品
  226. return true
  227. end
  228. return max31856