tm1650.lua 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. --[[
  2. @module tm1650
  3. @summary tm1650 数码管和按键扫描芯片
  4. @version 1.0
  5. @date 2023.09.07
  6. @author lulipro
  7. @usage
  8. --注意:
  9. --1、tm1650驱动的数码管应该选用共阴数码管
  10. --2、tm1650也可以驱动LED,如果是LED,则应该将LED连接成共阴数码管内部相同的电路
  11. --3、支持按键扫描,此模式下tm1650的DP/KP引脚为中断输出引脚
  12. --=========按键扫描例子==========
  13. local function tm1650_kcb(key_code)
  14. log.info('tm1650 user cb,key code=',string.format("%02X",key_code))
  15. end
  16. sys.taskInit(function()
  17. tm1650.init(pin.PB06,pin.PB07,tm1650.MODE_KEY_INPUT,pin.PB08,tm1650_kcb)
  18. while 1 do
  19. sys.wait(2000)
  20. end
  21. end)
  22. --==========数码管显示例子===========
  23. sys.taskInit(function()
  24. --共阴段码表,0~9的数字
  25. local NUM_TABLE_AX = {
  26. [0]=0x3f,[1]=0x06,[2]=0x5b,[3]=0x4f,[4]=0x66,
  27. [5]=0x6d,[6]=0x7d,[7]=0x07,[8]=0x7f,[9]=0x6f
  28. };
  29. tm1650.init(pin.PB06,pin.PB07,tm1650.MODE_LED_OUTPUT)
  30. while 1 do
  31. for i = tm1650.DIG1, tm1650.DIG4, 1 do
  32. tm1650.print(i,NUM_TABLE_AX[6])
  33. sys.wait(500)
  34. end
  35. sys.wait(1000)
  36. for i = tm1650.BRIGHT1, tm1650.BRIGHT8, 1 do
  37. tm1650.setBright(i)
  38. sys.wait(500)
  39. end
  40. for i = 1, 8, 1 do
  41. sys.wait(500)
  42. tm1650.close()
  43. sys.wait(500)
  44. tm1650.open()
  45. end
  46. sys.wait(2000)
  47. tm1650.clear()
  48. end
  49. end)
  50. ]]
  51. local tm1650 = {}
  52. local sys = require "sys"
  53. --数码管位选定义
  54. tm1650.DIG1 = 0
  55. tm1650.DIG2 = 1
  56. tm1650.DIG3 = 2
  57. tm1650.DIG4 = 3
  58. --八级亮度常量定义
  59. tm1650.BRIGHT1 = 1
  60. tm1650.BRIGHT2 = 2
  61. tm1650.BRIGHT3 = 3
  62. tm1650.BRIGHT4 = 4
  63. tm1650.BRIGHT5 = 5
  64. tm1650.BRIGHT6 = 6
  65. tm1650.BRIGHT7 = 7
  66. tm1650.BRIGHT8 = 8 --第8级亮度时寄存器二进制位为000
  67. --工作模式定义
  68. tm1650.MODE_LED_OUTPUT = 0x71 --数码管LED驱动模式(7级亮度,8段模式,打开显示)
  69. tm1650.MODE_KEY_INPUT = 0x79 --按键扫描模式
  70. local TM1650_SCL
  71. local TM1650_SDA
  72. local TM1650_SDA_PIN --SDA引脚
  73. local TM1650_IRQ_PIN --按键检测使用的中断引脚号
  74. local TM1650_KEY_CALLBACK --按键回调函数
  75. local bright = tm1650.BRIGHT7 --亮度变量
  76. local is_display_on = 1 --显示开关标志变量
  77. local function tm1650_writeReg(reg,value)
  78. local dat
  79. local mbit
  80. --=====start========
  81. TM1650_SCL(1)
  82. TM1650_SDA(1)
  83. TM1650_SDA(0)
  84. TM1650_SCL(0)
  85. --======写寄存器地址==========
  86. dat = reg
  87. for i = 0, 7, 1 do
  88. TM1650_SCL(0)
  89. mbit = (((dat<<i)&0x80) ~= 0) and 1 or 0
  90. TM1650_SDA(mbit)
  91. TM1650_SCL(1)
  92. TM1650_SCL(0)
  93. end
  94. TM1650_SDA(1) --释放 SDA
  95. TM1650_SCL(0)
  96. TM1650_SCL(1)
  97. TM1650_SCL(0)
  98. --======写数据==========
  99. dat = value
  100. for i = 0, 7, 1 do
  101. TM1650_SCL(0)
  102. mbit = (((dat<<i)&0x80) ~= 0) and 1 or 0
  103. TM1650_SDA(mbit)
  104. TM1650_SCL(1)
  105. TM1650_SCL(0)
  106. end
  107. TM1650_SDA(1) --释放 SDA
  108. TM1650_SCL(0)
  109. TM1650_SCL(1)
  110. TM1650_SCL(0)
  111. --=======stop=======
  112. TM1650_SCL(0)
  113. TM1650_SDA(0)
  114. TM1650_SCL(1)
  115. TM1650_SDA(1)
  116. end
  117. local function tm1650_readReg(reg)
  118. local dat
  119. local mbit
  120. --=====start========
  121. TM1650_SCL(1)
  122. TM1650_SDA(1)
  123. TM1650_SDA(0)
  124. TM1650_SCL(0)
  125. --======写寄存器地址==========
  126. dat = reg
  127. for i = 0, 7, 1 do
  128. TM1650_SCL(0)
  129. mbit = (((dat<<i)&0x80) ~= 0) and 1 or 0
  130. TM1650_SDA(mbit)
  131. TM1650_SCL(1)
  132. TM1650_SCL(0)
  133. end
  134. TM1650_SDA(1) --释放 SDA
  135. TM1650_SCL(0)
  136. TM1650_SCL(1)
  137. TM1650_SCL(0)
  138. --=======读数据=========
  139. dat = 0
  140. gpio.setup(TM1650_SDA_PIN,nil,gpio.PULLUP) --SDA输入模式
  141. for i = 0, 7, 1 do
  142. TM1650_SCL(0)
  143. dat = (dat << 1)
  144. TM1650_SCL(1)
  145. if gpio.HIGH == gpio.get(TM1650_SDA_PIN) then
  146. dat = ( dat | 0x01)
  147. end
  148. TM1650_SCL(0)
  149. end
  150. TM1650_SCL(0)
  151. TM1650_SCL(1)
  152. TM1650_SCL(0)
  153. TM1650_SDA = gpio.setup(TM1650_SDA_PIN,1) --SDA重新设置为输出模式
  154. --=======stop=======
  155. TM1650_SCL(0)
  156. TM1650_SDA(0)
  157. TM1650_SCL(1)
  158. TM1650_SDA(1)
  159. return dat
  160. end
  161. --[[
  162. TM1650初始化,根据mode参数可以设置为数码管显示或者按键扫描模式
  163. @api tm1650.init(scl_pin,sda_pin,mode,irq_pin,key_cb)
  164. @number scl_pin,定义了时钟线驱动引脚
  165. @number sda_pin,定义了数据线驱动引脚
  166. @number mode,定义了工作模式,tm1650.MODE_LED_OUTPUT,数码管LED驱动模式;tm1650.MODE_KEY_INPUT,按键检测模式
  167. @number irq_pin,定义按键中断引脚
  168. @function key_cb,按键用户回调函数,此函数有一个number类型参数,为按下的按键的按键代码
  169. @usage
  170. tm1650.init(pin.PB06,pin.PB07,tm1650.MODE_LED_OUTPUT) --数码管显示模式
  171. tm1650.init(pin.PB06,pin.PB07,tm1650.MODE_KEY_INPUT,pin.PB08,tm1650_kcb) --按键扫描模式
  172. ]]
  173. function tm1650.init(scl_pin,sda_pin,mode,irq_pin,key_cb)
  174. TM1650_SCL = gpio.setup(scl_pin, 1)
  175. TM1650_SDA = gpio.setup(sda_pin, 1)
  176. TM1650_SDA_PIN = sda_pin
  177. if mode == tm1650.MODE_KEY_INPUT then
  178. TM1650_IRQ_PIN = irq_pin
  179. TM1650_KEY_CALLBACK = key_cb
  180. --配置为按键扫描模式
  181. tm1650_writeReg(0x48,tm1650.MODE_KEY_INPUT)
  182. gpio.setup(
  183. TM1650_IRQ_PIN, --中断gpio编号
  184. function (val) --中断处理函数,下降沿触发时
  185. local key_code = tm1650_readReg(0x49) --读按键代码
  186. if TM1650_KEY_CALLBACK then
  187. TM1650_KEY_CALLBACK(key_code)
  188. end
  189. --log.info('tm1650 key get',string.format("%02X",key_code)) --输出按键值
  190. end,
  191. gpio.PULLUP, --启用上拉
  192. gpio.FALLING --下降沿触发
  193. )
  194. else
  195. --配置为数码管LED驱动模式,7级亮度,打开显示
  196. tm1650_writeReg(0x48,tm1650.MODE_LED_OUTPUT)
  197. tm1650.clear()
  198. end
  199. end
  200. --[[
  201. 设置TM1650的显示亮度,此操作不影响显存中的数据
  202. @api tm1650.setBright(bri)
  203. @number 亮度参数,取值为tm1650.BRIGHT1~tm1650.BRIGHT8
  204. @usage
  205. tm1650.setBright(tm1650.BRIGHT8)
  206. ]]
  207. function tm1650.setBright(bri)
  208. if bri>tm1650.BRIGHT8 then bri = tm1650.BRIGHT8 end
  209. if bri<tm1650.BRIGHT1 then bri = tm1650.BRIGHT1 end
  210. bright = bri
  211. local bright_bits = bright
  212. if bright == tm1650.BRIGHT8 then bright_bits=0 end --亮度8的寄存器二进制为000
  213. tm1650_writeReg(0x48,((bright_bits<<4)|is_display_on))
  214. end
  215. --[[
  216. 打开TM1650的显示,此操作不影响显存中的数据
  217. @api tm1650.open()
  218. @usage
  219. tm1650.open()
  220. ]]
  221. function tm1650.open()
  222. local bright_bits = bright
  223. if bright == tm1650.BRIGHT8 then bright_bits=0 end --亮度8的寄存器二进制为000
  224. is_display_on=1
  225. tm1650_writeReg(0x48,((bright_bits<<4)|is_display_on))
  226. end
  227. --[[
  228. 关闭TM1650的显示,此操作不影响显存中的数据
  229. @api tm1650.close()
  230. @usage
  231. tm1650.close()
  232. ]]
  233. function tm1650.close()
  234. local bright_bits = bright
  235. if bright == tm1650.BRIGHT8 then bright_bits=0 end --亮度8的寄存器二进制为000
  236. is_display_on=0
  237. tm1650_writeReg(0x48,((bright_bits<<4)|is_display_on))
  238. end
  239. --[[
  240. 向TM1650的一个指定的位对应的显存发送指定的段数据进行显示
  241. @api tm1650.print(dig,seg_data)
  242. @number dig,定义位选参数,取值为tm1650.DIG1~tm1650.DIG4
  243. @number seg_data,定义段数据参数
  244. @usage
  245. tm1650.print(tm1650.DIG1,0x3f)
  246. ]]
  247. function tm1650.print(dig,seg_data)
  248. if (dig>=tm1650.DIG1) and (dig<=tm1650.DIG4) then
  249. tm1650_writeReg(dig*2+0x68,seg_data)
  250. end
  251. end
  252. --[[
  253. 清除TM1650的所有位对应的显存数据,即全部刷写为0
  254. @api tm1650.clear()
  255. @usage
  256. tm1650.clear()
  257. ]]
  258. function tm1650.clear()
  259. for i = tm1650.DIG1, tm1650.DIG4, 1 do
  260. tm1650.print(i,0)
  261. end
  262. end
  263. return tm1650