pins.lua 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. --- 模块功能:GPIO 功能配置,包括输入输出IO和上升下降沿中断IO
  2. -- @module pins
  3. -- @author openLuat
  4. -- @license MIT
  5. -- @copyright openLuat
  6. -- @release 2017.09.23 11:34
  7. require "sys"
  8. module(..., package.seeall)
  9. local interruptCallbacks = {}
  10. local dirs = {}
  11. --- 配置GPIO模式
  12. -- @number pin,GPIO ID
  13. -- GPIO 0到GPIO 31表示为pio.P0_0到pio.P0_31
  14. -- GPIO 32到GPIO XX表示为pio.P1_0到pio.P1_(XX-32),例如GPIO33 表示为pio.P1_1
  15. -- @param val,number、nil或者function类型
  16. -- 配置为输出模式时,为number类型,表示默认电平,0是低电平,1是高电平
  17. -- 配置为输入模式时,为nil
  18. -- 配置为中断模式时,为function类型,表示中断处理函数
  19. -- @param pull, number, pio.PULLUP:上拉模式 。pio.PULLDOWN:下拉模式。pio.NOPULL:高阻态
  20. -- 如果没有设置此参数,默认的上下拉参考模块的硬件设计说明书
  21. -- @return function
  22. -- 配置为输出模式时,返回的函数,可以设置IO的电平
  23. -- 配置为输入或者中断模式时,返回的函数,可以实时获取IO的电平
  24. -- @usage setOutputFnc = pins.setup(pio.P1_1,0),配置GPIO 33,输出模式,默认输出低电平;
  25. --执行setOutputFnc(0)可输出低电平,执行setOutputFnc(1)可输出高电平
  26. -- @usage getInputFnc = pins.setup(pio.P1_1,intFnc),配置GPIO33,中断模式
  27. -- 产生中断时自动调用intFnc(msg)函数:上升沿中断时:msg为cpu.INT_GPIO_POSEDGE;下降沿中断时:msg为cpu.INT_GPIO_NEGEDGE
  28. -- 执行getInputFnc()即可获得当前电平;如果是低电平,getInputFnc()返回0;如果是高电平,getInputFnc()返回1
  29. -- @usage getInputFnc = pins.setup(pio.P1_1),配置GPIO33,输入模式
  30. --执行getInputFnc()即可获得当前电平;如果是低电平,getInputFnc()返回0;如果是高电平,getInputFnc()返回1
  31. function setup(pin, val, pull)
  32. -- 关闭该IO
  33. pio.pin.close(pin)
  34. -- 中断模式配置
  35. if type(val) == "function" then
  36. pio.pin.setdir(pio.INT, pin)
  37. if pull then pio.pin.setpull(pull or pio.PULLUP, pin) end
  38. --注册引脚中断的处理函数
  39. interruptCallbacks[pin] = val
  40. dirs[pin] = false
  41. return function()
  42. return pio.pin.getval(pin)
  43. end
  44. end
  45. -- 输出模式初始化默认配置
  46. if val ~= nil then
  47. dirs[pin] = true
  48. pio.pin.setdir(val == 1 and pio.OUTPUT1 or pio.OUTPUT, pin)
  49. else
  50. -- 输入模式初始化默认配置
  51. dirs[pin] = false
  52. pio.pin.setdir(pio.INPUT, pin)
  53. if pull then pio.pin.setpull(pull or pio.PULLUP, pin) end
  54. end
  55. -- 返回一个自动切换输入输出模式的函数
  56. return function(val, changeDir)
  57. val = tonumber(val)
  58. if (not val and dirs[pin]) or (val and not dirs[pin]) then
  59. pio.pin.close(pin)
  60. pio.pin.setdir(val and (val == 1 and pio.OUTPUT1 or pio.OUTPUT) or pio.INPUT, pin)
  61. if not val and pull then pio.pin.setpull(pull or pio.PULLUP, pin) end
  62. dirs[pin] = val and true or false
  63. return val or pio.pin.getval(pin)
  64. end
  65. if val then
  66. pio.pin.setval(val, pin)
  67. return val
  68. else
  69. return pio.pin.getval(pin)
  70. end
  71. end
  72. end
  73. --- 关闭GPIO模式
  74. -- @number pin,GPIO ID
  75. --
  76. -- GPIO 0到GPIO 31表示为pio.P0_0到pio.P0_31
  77. --
  78. -- GPIO 32到GPIO XX表示为pio.P1_0到pio.P1_(XX-32),例如GPIO33 表示为pio.P1_1
  79. -- @usage pins.close(pio.P1_1),关闭GPIO33
  80. function close(pin)
  81. pio.pin.close(pin)
  82. end
  83. rtos.on(rtos.MSG_INT, function(msg)
  84. if interruptCallbacks[msg.int_resnum] == nil then
  85. log.warn('pins.rtos.on', 'warning:rtos.MSG_INT callback nil', msg.int_resnum)
  86. end
  87. interruptCallbacks[msg.int_resnum](msg.int_id)
  88. end)