tm1640.lua 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. --[[
  2. @module tm1640
  3. @summary tm1640 数码管和LED驱动芯片
  4. @version 1.0
  5. @date 2023.08.29
  6. @author lulipro
  7. @usage
  8. --注意:
  9. --1、tm1640驱动的数码管应该选用共阴数码管
  10. --2、tm1640也可以驱动LED,如果是LED,则应该将LED连接成共阴数码管内部相同的电路
  11. --3、AIR101官方核心板,底层为LuatOS-SoC_V0017_AIR101.soc,经测试此脚本库的串行时钟频率为20KHz
  12. -- 用法实例:
  13. local tm1640 = require("tm1640")
  14. sys.taskInit(function ()
  15. --共阴段码表,0~9的数字
  16. local NUM_TABLE_AX = {
  17. [0]=0x3f,[1]=0x06,[2]=0x5b,[3]=0x4f,[4]=0x66,
  18. [5]=0x6d,[6]=0x7d,[7]=0x07,[8]=0x7f,[9]=0x6f
  19. };
  20. tm1640.init(pin.PB06,pin.PB07) --clk,dat
  21. while 1 do
  22. for i = 0, 9, 1 do
  23. tm1640.setBright(tm1640.BRIGHT1)
  24. for grid = tm1640.GRID1, tm1640.GRID16, 1 do
  25. tm1640.sendDisplayData(grid,NUM_TABLE_AX[i])
  26. end
  27. sys.wait(200)
  28. tm1640.setBright(tm1640.BRIGHT3)
  29. sys.wait(200)
  30. tm1640.setBright(tm1640.BRIGHT5)
  31. sys.wait(200)
  32. tm1640.setBright(tm1640.BRIGHT8)
  33. sys.wait(200)
  34. end
  35. sys.wait(1000)
  36. tm1640.setBright(tm1640.BRIGHT5)
  37. for i = 0, 9, 1 do
  38. tm1640.clear()
  39. for grid = tm1640.GRID1, tm1640.GRID16, 1 do
  40. tm1640.sendDisplayData(grid,NUM_TABLE_AX[i])
  41. sys.wait(100)
  42. end
  43. end
  44. end
  45. end)
  46. ]]
  47. local tm1640 = {}
  48. local sys = require "sys"
  49. --数码管位选常量定义
  50. tm1640.GRID1 = 0
  51. tm1640.GRID2 = 1
  52. tm1640.GRID3 = 2
  53. tm1640.GRID4 = 3
  54. tm1640.GRID5 = 4
  55. tm1640.GRID6 = 5
  56. tm1640.GRID7 = 6
  57. tm1640.GRID8 = 7
  58. tm1640.GRID9 = 8
  59. tm1640.GRID10 = 9
  60. tm1640.GRID11 = 10
  61. tm1640.GRID12 = 11
  62. tm1640.GRID13 = 12
  63. tm1640.GRID14 = 13
  64. tm1640.GRID15 = 14
  65. tm1640.GRID16 = 15
  66. --八级亮度常量定义
  67. tm1640.BRIGHT1 = 0
  68. tm1640.BRIGHT2 = 1
  69. tm1640.BRIGHT3 = 2
  70. tm1640.BRIGHT4 = 3
  71. tm1640.BRIGHT5 = 4
  72. tm1640.BRIGHT6 = 5
  73. tm1640.BRIGHT7 = 6
  74. tm1640.BRIGHT8 = 7
  75. local is_display_on = 1 --显示开关标志变量
  76. local bright = tm1640.BRIGHT5 --亮度级别变量
  77. local TM1640_CLK --驱动时钟线的引脚
  78. local TM1640_DAT --驱动数据线的引脚
  79. --串行通信起始条件
  80. local function tm1640_strat()
  81. TM1640_CLK(1)
  82. TM1640_DAT(1)
  83. TM1640_DAT(0)
  84. TM1640_CLK(0)
  85. end
  86. --串行通信结束条件
  87. local function tm1640_stop()
  88. TM1640_CLK(0)
  89. TM1640_DAT(0)
  90. TM1640_CLK(1)
  91. TM1640_DAT(1)
  92. end
  93. --串行发送一个字节,LSB First
  94. local function tm1640_writeByte(data)
  95. if data~=nil then--防止未接入数码管或者测试时接线不稳定,传来空数据导致程序运行异常
  96. for i = 0, 7, 1 do
  97. local mbit = (data&0x01~=0) and 1 or 0
  98. TM1640_DAT(mbit)
  99. TM1640_CLK(1)
  100. data = data>>1
  101. TM1640_CLK(0)
  102. --data = data>>1 将这句话放在上面是为了尽量让时钟接近50%占空比
  103. end
  104. end
  105. end
  106. --[[
  107. 向TM1640的一个指定的位(grid)对应的显存发送指定的段数据进行显示
  108. @api tm1640.sendDisplayData(grid,seg_data)
  109. @number grid,定义位选参数,取值为tm1640.GRID1~tm1640.GRID16
  110. @number seg_data,定义段数据参数
  111. @usage
  112. tm1640.sendDisplayData(tm1640.GRID1,0xff)
  113. ]]
  114. function tm1640.sendDisplayData(grid,seg_data)
  115. if (grid >= tm1640.GRID1) and (grid <= tm1640.GRID16) then
  116. tm1640_strat()
  117. tm1640_writeByte(0xc0|grid)
  118. tm1640_writeByte(seg_data)
  119. tm1640_stop()
  120. end
  121. end
  122. --[[
  123. 清除TM1640的所有位(grid)对应的显存数据,即全部刷写为0
  124. @api tm1640.clear()
  125. @usage
  126. tm1640.clear()
  127. ]]
  128. function tm1640.clear()
  129. for i = tm1640.GRID1, tm1640.GRID16, 1 do
  130. tm1640.sendDisplayData(i,0)
  131. end
  132. end
  133. --[[
  134. 打开TM1640的显示,此操作不影响显存中的数据
  135. @api tm1640.open()
  136. @usage
  137. tm1640.open()
  138. ]]
  139. function tm1640.open()
  140. is_display_on=1
  141. tm1640_strat()
  142. tm1640_writeByte(0x80|(is_display_on<<3)|(bright))
  143. tm1640_stop()
  144. end
  145. --[[
  146. 关闭TM1640的显示,此操作不影响显存中的数据
  147. @api tm1640.close()
  148. @usage
  149. tm1640.close()
  150. ]]
  151. function tm1640.close()
  152. is_display_on=0
  153. tm1640_strat()
  154. tm1640_writeByte(0x80|(is_display_on<<3)|(bright))
  155. tm1640_stop()
  156. end
  157. --[[
  158. 设置TM1640的显示亮度,此操作不影响显存中的数据
  159. @api tm1640.setBright(bri)
  160. @number 亮度参数,取值为tm1640.BRIGHT1~tm1640.BRIGHT8
  161. @usage
  162. tm1640.setBright(tm1640.BRIGHT8)
  163. ]]
  164. function tm1640.setBright(bri)
  165. if bri>tm1640.BRIGHT8 then bri = tm1640.BRIGHT8 end
  166. if bri<tm1640.BRIGHT1 then bri = tm1640.BRIGHT1 end
  167. bright = bri
  168. tm1640_strat()
  169. tm1640_writeByte(0x80|(is_display_on<<3)|(bright))
  170. tm1640_stop()
  171. end
  172. --[[
  173. TM1640的初始化
  174. @api tm1640.init(clk,dat,bri)
  175. @number clk,定义了时钟线驱动引脚
  176. @number dat,定义了数据线驱动引脚
  177. @number bri,初始亮度参数,可取的值为tm1640.BRIGHT1~tm1640.BRIGHT8。可选,默认值为tm1640.BRIGHT5。
  178. @usage
  179. tm1640.init(pin.PB06,pin.PB07)
  180. tm1640.init(pin.PB06,pin.PB07,tm1640.BRIGHT8)
  181. ]]
  182. function tm1640.init(clk,dat,bri)
  183. TM1640_CLK = gpio.setup(clk, 1)
  184. TM1640_DAT = gpio.setup(dat, 1)
  185. --设置为固定地址模式
  186. tm1640_strat()
  187. tm1640_writeByte(0x44)
  188. tm1640_stop()
  189. --如果设置了初始亮度
  190. if bri then
  191. if bri>tm1640.BRIGHT8 then bri = tm1640.BRIGHT8 end
  192. if bri<tm1640.BRIGHT1 then bri = tm1640.BRIGHT1 end
  193. bright = bri
  194. end
  195. tm1640.open() --打开显示
  196. tm1640.clear() --清除显存数据
  197. end
  198. return tm1640