exlcd.lua 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. -- exlcd.lua
  2. --[[
  3. @module exlcd
  4. @summary LCD显示拓展库
  5. @version 1.0.4
  6. @date 2025.11.11
  7. @author 江访
  8. @usage
  9. 核心业务逻辑为:
  10. 1、初始化LCD显示屏,支持多种显示芯片
  11. 2、管理屏幕背光亮度及开关状态
  12. 3、提供屏幕状态管理功能
  13. 4、支持根据lcd_model自动配置参数
  14. 本文件的对外接口有3个:
  15. 1、exlcd.init(param) -- LCD初始化函数
  16. 2、exlcd.set_bl(level) -- 设置背光亮度接口,level 亮度级别(0-100)
  17. 3、exlcd.get_bl() -- 当前设置背光亮度级别查询
  18. 4、exlcd.sleep() -- 屏幕休眠
  19. 5、exlcd.wakeup() -- 屏幕唤醒
  20. 6、exlcd.get_sleep() -- 休眠状态查询
  21. ]]
  22. local exlcd = {}
  23. -- 屏幕状态管理表
  24. local screen_state = {
  25. last_brightness = 100, -- 默认亮度100%
  26. backlight_on = true, -- 背光默认开启
  27. lcd_config = nil -- 存储LCD配置
  28. }
  29. -- 预定义屏幕配置表
  30. local predefined_configs = {
  31. Air780EHM_LCD_4 = {
  32. lcd_model = "Air780EHM_LCD_4",
  33. pin_vcc = 24,
  34. pin_rst = 36,
  35. pin_pwr = 25,
  36. pin_pwm = 2,
  37. port = lcd.HWID_0,
  38. direction = 3,
  39. w = 480,
  40. h = 320,
  41. xoffset = 0,
  42. yoffset = 0,
  43. sleepcmd = 0X10,
  44. wakecmd = 0X11,
  45. },
  46. AirLCD_1000 = {
  47. lcd_model = "AirLCD_1000",
  48. pin_vcc = 29,
  49. pin_rst = 36,
  50. pin_pwr = 30,
  51. pin_pwm = 1,
  52. port = lcd.HWID_0,
  53. direction = 0,
  54. w = 320,
  55. h = 480,
  56. xoffset = 0,
  57. yoffset = 0,
  58. sleepcmd = 0X10,
  59. wakecmd = 0X11,
  60. },
  61. AirLCD_1010 = {
  62. lcd_model = "AirLCD_1010",
  63. pin_vcc = 141,
  64. pin_rst = 36,
  65. pin_pwr = 1,
  66. pin_pwm = 0,
  67. port = lcd.HWID_0,
  68. direction = 0,
  69. w = 320,
  70. h = 480,
  71. xoffset = 0,
  72. yoffset = 0,
  73. sleepcmd = 0X10,
  74. wakecmd = 0X11,
  75. },
  76. AirLCD_1020 = {
  77. lcd_model = "AirLCD_1020",
  78. pin_pwr = 8,
  79. pin_pwm = 0,
  80. port = lcd.RGB,
  81. direction = 0,
  82. w = 800,
  83. h = 480,
  84. xoffset = 0,
  85. yoffset = 0,
  86. bus_speed = 30 * 1000 * 1000,
  87. hbp = 8,
  88. hspw = 4,
  89. hfp = 8,
  90. vbp = 16,
  91. vspw = 4,
  92. vfp = 16,
  93. }
  94. }
  95. -- LCD初始化函数
  96. -- @param param LCD参数配置表
  97. -- @return 初始化成功状态
  98. function exlcd.init(param)
  99. if type(param) ~= "table" then
  100. log.error("exlcd", "参数必须为表")
  101. return false
  102. end
  103. -- 检查必要参数
  104. if not param.lcd_model then
  105. log.error("exlcd", "缺少必要参数: lcd_model")
  106. return false
  107. end
  108. local config = {}
  109. -- 根据lcd_model选择配置策略
  110. if param.lcd_model == "Air780EHM_LCD_4" then
  111. -- Air780EHM_LCD_4: 只使用lcd_model,其他参数固定
  112. config = predefined_configs.Air780EHM_LCD_4
  113. log.info("exlcd", "使用Air780EHM_LCD_4固定配置")
  114. elseif predefined_configs[param.lcd_model] then
  115. -- 其他预定义型号: 使用预定义配置作为基础,传入参数覆盖预定义配置
  116. config = {}
  117. -- 复制预定义配置
  118. for k, v in pairs(predefined_configs[param.lcd_model]) do
  119. config[k] = v
  120. end
  121. -- 用传入参数覆盖预定义配置
  122. for k, v in pairs(param) do
  123. if k ~= "lcd_model" or v ~= param.lcd_model then -- 避免重复设置lcd_model
  124. config[k] = v
  125. end
  126. end
  127. log.info("exlcd", "使用" .. param.lcd_model .. "基础配置,传入参数已覆盖")
  128. else
  129. -- 未知型号: 直接使用传入参数
  130. config = param
  131. log.info("exlcd", "使用传入参数配置")
  132. end
  133. -- LCD型号映射表
  134. local lcd_models = {
  135. AirLCD_1000 = "st7796",
  136. Air780EHM_LCD_4 = "st7796",
  137. AirLCD_1010 = "st7796",
  138. AirLCD_1020 = "nv3052c"
  139. }
  140. -- 确定LCD型号
  141. local lcd_model = lcd_models[config.lcd_model] or config.lcd_model
  142. -- 存储LCD配置供其他函数使用
  143. screen_state.lcd_config = {
  144. pin_pwr = config.pin_pwr,
  145. pin_pwm = config.pin_pwm,
  146. model = lcd_model,
  147. lcd_model = config.lcd_model
  148. }
  149. -- 设置电源引脚 (可选)
  150. if config.pin_vcc then
  151. gpio.setup(config.pin_vcc, 1, gpio.PULLUP)
  152. gpio.set(config.pin_vcc, 1)
  153. end
  154. -- 设置背光电源引脚 (可选)
  155. if config.pin_pwr then
  156. gpio.setup(config.pin_pwr, 1, gpio.PULLUP)
  157. gpio.set(config.pin_pwr, 1) -- 默认开启背光
  158. end
  159. -- 设置PWM背光引脚 (可选)
  160. if config.pin_pwm then
  161. pwm.setup(config.pin_pwm, 1000, screen_state.last_brightness)
  162. pwm.open(config.pin_pwm, 1000, screen_state.last_brightness)
  163. end
  164. -- 屏幕初始化 (spi_dev和init_in_service为可选参数)
  165. local lcd_init = lcd.init(
  166. lcd_model,
  167. config,
  168. config.spi_dev and config.spi_dev or nil,
  169. config.init_in_service and config.init_in_service or nil
  170. )
  171. log.info("exlcd", "LCD初始化", lcd_init)
  172. -- 自定义初始化完成确认
  173. if lcd_model == "custom" then
  174. lcd.user_done()
  175. end
  176. return lcd_init
  177. end
  178. -- 设置背光亮度接口
  179. -- 使用背光PWM模式控制亮度
  180. -- @param level 亮度级别(0-100)
  181. function exlcd.set_bl(level)
  182. -- 检查PWM配置
  183. if not screen_state.lcd_config.pin_pwm then
  184. log.error("exlcd", "PWM配置不存在,无法调节背光")
  185. return false
  186. end
  187. -- 确保GPIO已关闭
  188. if screen_state.lcd_config.pin_pwr then
  189. gpio.close(screen_state.lcd_config.pin_pwr)
  190. end
  191. -- 设置并开启PWM
  192. pwm.stop(screen_state.lcd_config.pin_pwm)
  193. pwm.close(screen_state.lcd_config.pin_pwm)
  194. pwm.setup(screen_state.lcd_config.pin_pwm, 1000, 100)
  195. pwm.open(screen_state.lcd_config.pin_pwm, 1000, level)
  196. screen_state.last_brightness = level
  197. screen_state.backlight_on = (level > 0)
  198. log.info("exlcd", "背光设置为", level, "%")
  199. return true
  200. end
  201. function exlcd.get_bl()
  202. return screen_state.last_brightness
  203. end
  204. -- 屏幕休眠
  205. function exlcd.sleep()
  206. if not screen_state.is_sleeping then
  207. -- 关闭PWM背光 (如果配置了)
  208. if screen_state.lcd_config and screen_state.lcd_config.pin_pwm then
  209. pwm.close(screen_state.lcd_config.pin_pwm)
  210. end
  211. -- 关闭背光电源 (如果配置了)
  212. if screen_state.lcd_config and screen_state.lcd_config.pin_pwr then
  213. gpio.setup(screen_state.lcd_config.pin_pwr, 1, gpio.PULLUP)
  214. gpio.set(screen_state.lcd_config.pin_pwr, 0)
  215. end
  216. -- 执行LCD睡眠
  217. lcd.sleep()
  218. screen_state.is_sleeping = true
  219. log.info("exlcd", "LCD进入休眠状态")
  220. end
  221. end
  222. -- 屏幕唤醒
  223. function exlcd.wakeup()
  224. if screen_state.is_sleeping then
  225. -- 开启背光电源 (如果配置了)
  226. if screen_state.lcd_config and screen_state.lcd_config.pin_pwr then
  227. gpio.set(screen_state.lcd_config.pin_pwr, 1)
  228. end
  229. -- 唤醒LCD
  230. lcd.wakeup()
  231. sys.wait(100) -- 等待100ms稳定
  232. -- 恢复背光设置 (如果配置了PWM引脚)
  233. if screen_state.lcd_config and screen_state.lcd_config.pin_pwm then
  234. pwm.setup(screen_state.lcd_config.pin_pwm, 1000, screen_state.last_brightness)
  235. pwm.open(screen_state.lcd_config.pin_pwm, 1000, screen_state.last_brightness)
  236. end
  237. screen_state.is_sleeping = false
  238. log.info("exlcd", "LCD唤醒")
  239. end
  240. end
  241. -- 获取当前休眠状态
  242. function exlcd.get_sleep()
  243. return screen_state.is_sleeping
  244. end
  245. return exlcd