pcf8574.lua 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. --[[
  2. @module pcf8574
  3. @summary pcf8574 IO扩展
  4. @version 1.0
  5. @date 2022.07.29
  6. @author Dozingfiretruck
  7. @usage
  8. --注意:因使用了sys.wait()所有api需要在协程中使用
  9. -- 用法实例
  10. local pcf8574 = require "pcf8574"
  11. i2cid = 0
  12. i2c_speed = i2c.FAST
  13. sys.taskInit(function()
  14. i2c.setup(i2cid,i2c_speed)
  15. pcf8574.init(i2cid)--初始化,传入i2c_id
  16. for i=0,7 do
  17. print(pcf8574.pin(i))
  18. end
  19. pcf8574.pin(0,1)
  20. for i=0,7 do
  21. print(pcf8574.pin(i))
  22. end
  23. end)
  24. ]]
  25. local pcf8574 = {}
  26. local sys = require "sys"
  27. local i2cid
  28. local PCF8574_ADDRESS
  29. local PCF8574_ADDRESS_ADR = 0x20 -- 0x20-0x27
  30. local PCF8574A_ADDRESS_ADR = 0x38 -- 0x38-0x3F
  31. local PCF8574_DATA
  32. --器件ID检测
  33. local function chip_check()
  34. for i=0,7 do
  35. local revData = i2c.recv(i2cid, PCF8574_ADDRESS_ADR+i, 1)
  36. if revData:byte() ~= nil then
  37. PCF8574_ADDRESS = PCF8574_ADDRESS_ADR+i
  38. PCF8574_DATA = revData:byte()
  39. break
  40. end
  41. end
  42. if PCF8574_ADDRESS==nil then
  43. for i=0,7 do
  44. local revData = i2c.recv(i2cid, PCF8574A_ADDRESS_ADR+i, 1)
  45. if revData:byte() ~= nil then
  46. PCF8574_ADDRESS = PCF8574A_ADDRESS_ADR+i
  47. PCF8574_DATA = revData:byte()
  48. break
  49. end
  50. end
  51. end
  52. if PCF8574_ADDRESS then
  53. log.info("i2c", "Device is: pcf8574")
  54. else
  55. log.info("i2c", "Can't find pcf8574 device")
  56. return false
  57. end
  58. return true
  59. end
  60. --[[
  61. pcf8574初始化
  62. @api pcf8574.init(i2c_id)
  63. @number 所在的i2c总线id
  64. @return bool 成功返回true
  65. @usage
  66. pcf8574.init(0)
  67. ]]
  68. function pcf8574.init(i2c_id)
  69. i2cid = i2c_id
  70. sys.wait(40)--40 毫秒等待设备稳定
  71. chip_check()
  72. log.info("pcf8574 init_ok")
  73. return true
  74. end
  75. --[[
  76. pcf8574 pin控制
  77. @api pcf8574.pin(pin,val)
  78. @number pin 0-7
  79. @number val 0/1 可选,不填则读取电平
  80. @return number 如val未填则返回读取电平
  81. @usage
  82. pcf8574.pin(0,1)
  83. print(pcf8574.pin(0))
  84. ]]
  85. function pcf8574.pin(pin,val)
  86. if val then
  87. if val==0 then
  88. PCF8574_DATA = PCF8574_DATA&~(1<<pin)
  89. else
  90. PCF8574_DATA = PCF8574_DATA|val<<pin
  91. end
  92. i2c.send(i2cid, PCF8574_ADDRESS,string.char(PCF8574_DATA))
  93. else
  94. local revData = i2c.recv(i2cid, PCF8574_ADDRESS, 1)
  95. PCF8574_DATA = revData:byte()
  96. return (PCF8574_DATA&(1<<pin))>>pin
  97. end
  98. end
  99. return pcf8574