瀏覽代碼

Merge pull request #68 from SummerGGift/add_machine_lcd

【添加】machine.LCD 模块
朱天龙 (Armink) 6 年之前
父節點
當前提交
abe0404c0e
共有 6 個文件被更改,包括 373 次插入2 次删除
  1. 71 0
      docs/04-Hardware_Control_Module/06-machine-LCD.md
  2. 29 0
      port/genhdr/qstrdefs.generated.h
  3. 233 0
      port/machine_lcd.c
  4. 31 0
      port/machine_lcd.h
  5. 5 2
      port/modmachine.c
  6. 4 0
      port/mpconfigport.h

+ 71 - 0
docs/04-Hardware_Control_Module/06-machine-LCD.md

@@ -0,0 +1,71 @@
+## machine.LCD
+
+**machine.LCD** 类是 machine 模块下面的一个硬件类,用于对 LCD 的配置和控制,提供对 LCD 设备的操作方法。
+
+IoT board 板载一块 1.3 寸,分辨率为 `240*240` 的 LCD 显示屏,因此对该屏幕操作时,(x, y)  坐标的范围是 `0 - 239`。
+
+### 构造函数
+
+在 RT-Thread MicroPython 中 `LCD` 对象的构造函数如下:
+
+#### **class machine.LCD**()
+在给定总线上构造一个 `LCD` 对象,无入参,初始化的对象取决于特定硬件,初始化方式可参考 [示例](#_3)。
+
+### 方法
+
+#### **LCD.light**(value)
+
+控制是否开启 LCD 背光,入参为 True 则打开 LCD 背光,入参为 False 则关闭 LCD 背光。
+
+#### **LCD.fill**(color)
+
+根据给定的颜色填充整个屏幕,支持多种颜色,可以传入的参数有:
+
+```
+WHITE BLACK BLUE BRED GRED GBLUE RED MAGENTA GREEN CYAN YELLOW BROWN BRRED GRAY GRAY175 GRAY151 GRAY240
+```
+
+详细的使用方法可参考[示例](#_3)。
+
+#### **LCD.pixel**(x, y, color)
+
+向指定的位置(x, y)画点,点的颜色为 color 指定的颜色,可指定的颜色和上一个功能相同。
+
+注意:(x, y)  坐标的范围是 0 - 239,使用下面的方法对坐标进行操作时同样需要遵循此限制。
+
+#### **LCD.text**(str, x, y, size)
+
+在指定的位置(x,y)写入字符串,字符串由 str 指定,字体的大小由 size 指定,size 的大小可为 16,24,32。
+
+#### **LCD.line**(x1, y1, x2, y2)
+
+在 LCD 上画一条直线,起始地址为 (x1, y1),终点为(x2, y2)。
+
+#### **LCD.rectangle**(x1, y1, x2, y2)
+
+在 LCD 上画一个矩形,左上角的位置为(x1, y1),右下角的位置为(x2, y2)。
+
+#### **LCD.circle**(x1, y1, r)
+
+在 LCD 上画一个圆形,圆心的位置为(x1, y1),半径长度为 r。
+
+### 示例
+
+```python
+from machine import LCD     # 从 machine 导入 LCD 类
+lcd = LCD()                 # 创建一个 lcd 对象
+lcd.light(False)            # 关闭背光
+lcd.light(True)             # 打开背光
+lcd.fill(lcd.BLACK)         # 将整个 LCD 填充为黑色
+lcd.fill(lcd.RED)           # 将整个 LCD 填充为红色
+lcd.fill(lcd.GRAY)          # 将整个 LCD 填充为灰色
+lcd.fill(lcd.WHITE)         # 将整个 LCD 填充为白色
+lcd.pixel(50, 50, lcd.BLUE) # 将(50,50)位置的像素填充为蓝色
+lcd.text("hello RT-Thread", 0, 0, 16)   # 在(0, 0) 位置以 16 字号打印字符串
+lcd.text("hello RT-Thread", 0, 16, 24)  # 在(0, 16)位置以 24 字号打印字符串
+lcd.text("hello RT-Thread", 0, 48, 32)  # 在(0, 48)位置以 32 字号打印字符串
+lcd.line(0, 50, 239, 50)    # 以起点(0,50),终点(239,50)画一条线
+lcd.line(0, 50, 239, 50)    # 以起点(0,50),终点(239,50)画一条线
+lcd.rectangle(100, 100, 200, 200) # 以左上角为(100,100),右下角(200,200)画矩形
+lcd.circle(150, 150, 80)    # 以圆心位置(150,150),半径为 80 画圆
+```

+ 29 - 0
port/genhdr/qstrdefs.generated.h

@@ -723,4 +723,33 @@ QDEF(MP_QSTR_STAT_CONNECTING, (const byte*)"\xf6\x0f" "STAT_CONNECTING")
 QDEF(MP_QSTR_STAT_IDLE, (const byte*)"\x0c\x09" "STAT_IDLE")
 QDEF(MP_QSTR_now, (const byte*)"\xb3\x03" "now")
 QDEF(MP_QSTR_RTC, (const byte*)"\xa0\x03" "RTC")
+QDEF(MP_QSTR_command, (const byte*)"\x02\x07" "command")
+QDEF(MP_QSTR_contrast, (const byte*)"\x07\x08" "contrast")
+QDEF(MP_QSTR_light, (const byte*)"\xfb\x05" "light")
+QDEF(MP_QSTR_fill, (const byte*)"\xca\x04" "fill")
+QDEF(MP_QSTR_pixel, (const byte*)"\x4d\x05" "pixel")
+QDEF(MP_QSTR_show, (const byte*)"\x86\x04" "show")
+QDEF(MP_QSTR_LCD, (const byte*)"\xce\x03" "LCD")
+QDEF(MP_QSTR_text, (const byte*)"\x98\x04" "text")
+QDEF(MP_QSTR_WHITE, (const byte*)"\xa2\x05" "WHITE")
+QDEF(MP_QSTR_BLACK, (const byte*)"\x82\x05" "BLACK")
+QDEF(MP_QSTR_BLUE, (const byte*)"\x3b\x04" "BLUE")
+QDEF(MP_QSTR_BRED, (const byte*)"\x34\x04" "BRED")
+QDEF(MP_QSTR_GRED, (const byte*)"\x91\x04" "GRED")
+QDEF(MP_QSTR_GBLUE, (const byte*)"\x5c\x05" "GBLUE")
+QDEF(MP_QSTR_RED, (const byte*)"\x96\x03" "RED")
+QDEF(MP_QSTR_MAGENTA, (const byte*)"\xf0\x07" "MAGENTA")
+QDEF(MP_QSTR_GREEN, (const byte*)"\xde\x05" "GREEN")
+QDEF(MP_QSTR_CYAN, (const byte*)"\x10\x04" "CYAN")
+QDEF(MP_QSTR_YELLOW, (const byte*)"\x41\x06" "YELLOW")
+QDEF(MP_QSTR_BROWN, (const byte*)"\xc3\x05" "BROWN")
+QDEF(MP_QSTR_BRRED, (const byte*)"\x06\x05" "BRRED")
+QDEF(MP_QSTR_GRAY, (const byte*)"\x08\x04" "GRAY")
+QDEF(MP_QSTR_GRAY175, (const byte*)"\x1b\x07" "GRAY175")
+QDEF(MP_QSTR_GRAY151, (const byte*)"\xdd\x07" "GRAY151")
+QDEF(MP_QSTR_GRAY187, (const byte*)"\xb6\x07" "GRAY187")
+QDEF(MP_QSTR_GRAY240, (const byte*)"\x3e\x07" "GRAY240")
+QDEF(MP_QSTR_line, (const byte*)"\xcb\x04" "line")
+QDEF(MP_QSTR_rectangle, (const byte*)"\xa4\x09" "rectangle")
+QDEF(MP_QSTR_circle, (const byte*)"\xb7\x06" "circle")
 // This file was automatically generated by makeqstrdata.py

+ 233 - 0
port/machine_lcd.c

@@ -0,0 +1,233 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 SummerGift <SummerGift@qq.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "py/mphal.h"
+#include "py/runtime.h"
+
+#if MICROPY_PY_MACHINE_LCD
+
+#include "machine_lcd.h"
+#include <drv_lcd.h>
+
+#define MAX_CO (240 - 1)
+
+typedef struct _machine_lcd_obj_t {
+    mp_obj_base_t base;
+} machine_lcd_obj_t;
+
+STATIC void error_check(bool status, const char *msg) {
+    if (!status) {
+        nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, msg));
+    }
+}
+
+/// \classmethod \constructor(skin_position)
+///
+/// Construct an LCD object.  
+STATIC mp_obj_t machine_lcd_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+
+    // check arguments
+    mp_arg_check_num(n_args, n_kw, 0, 0, false);
+    
+    // create lcd object
+    machine_lcd_obj_t *lcd = m_new_obj(machine_lcd_obj_t);
+    lcd->base.type = &machine_lcd_type;
+
+    return MP_OBJ_FROM_PTR(lcd);
+}
+
+/// \method light(value)
+///
+/// Turn the backlight on/off.  True or 1 turns it on, False or 0 turns it off.
+STATIC mp_obj_t machine_lcd_light(mp_obj_t self_in, mp_obj_t value) {
+    machine_lcd_obj_t *self = MP_OBJ_TO_PTR(self_in);
+    if (mp_obj_is_true(value)) {
+        lcd_display_on(); // set pin high to turn backlight on
+    } else {
+        lcd_display_off();// set pin low to turn backlight off
+    }
+    return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_lcd_light_obj, machine_lcd_light);
+
+/// \method fill(colour)
+///
+/// Fill the screen with the given colour.
+///
+STATIC mp_obj_t machine_lcd_fill(mp_obj_t self_in, mp_obj_t col_in) {
+    machine_lcd_obj_t *self = MP_OBJ_TO_PTR(self_in);
+    
+    int col = mp_obj_get_int(col_in);
+    lcd_clear(col);
+    
+    return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_lcd_fill_obj, machine_lcd_fill);
+
+/// \method pixel(x, y, colour)
+///
+/// Set the pixel at `(x, y)` to the given colour.
+///
+STATIC mp_obj_t machine_lcd_pixel(size_t n_args, const mp_obj_t *args) {
+    machine_lcd_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+    int x = mp_obj_get_int(args[1]);
+    int y = mp_obj_get_int(args[2]);
+    
+    error_check((x >= 0 && x <= MAX_CO) && (y >= 0 && y <= MAX_CO) , "The min/max X/Y coordinates is 0/239");
+
+    int col = mp_obj_get_int(args[3]);
+    lcd_draw_point_color(x, y, col);
+
+    return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_lcd_pixel_obj, 4, 4, machine_lcd_pixel);
+
+/// \method text(str, x, y, size)
+///
+/// Draw the given text to the position `(x, y)` using the given size (16 24 32).
+///
+STATIC mp_obj_t machine_lcd_text(size_t n_args, const mp_obj_t *args) {
+    // extract arguments
+    machine_lcd_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+    size_t len;
+    const char *data = mp_obj_str_get_data(args[1], &len);
+    int x = mp_obj_get_int(args[2]);
+    int y = mp_obj_get_int(args[3]);
+    int size = mp_obj_get_int(args[4]);
+    
+    error_check((x >= 0 && x <= MAX_CO) && (y >= 0 && y <= MAX_CO) , "The min/max X/Y coordinates is 0/239");
+    
+    error_check(size == 16 || size == 24 || size == 32, "lcd only support font size 16 24 32");
+    
+    lcd_show_string(x, y, size, data);
+
+    return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_lcd_text_obj, 5, 5, machine_lcd_text);
+
+/// \method line(x1, y1, x2, y2)
+///
+/// display a line on the lcd, from (x1, y1) to (x2, y2).
+///
+STATIC mp_obj_t machine_lcd_line(size_t n_args, const mp_obj_t *args) {
+    // extract arguments
+    machine_lcd_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+
+    int x1 = mp_obj_get_int(args[1]);
+    int y1 = mp_obj_get_int(args[2]);
+    int x2 = mp_obj_get_int(args[3]);
+    int y2 = mp_obj_get_int(args[4]);
+    
+    error_check((x1 >= 0 && x1 <= MAX_CO) && (y1 >= 0 && y1 <= MAX_CO) , "The min/max X/Y coordinates is 0/239");
+    error_check((x2 >= 0 && x2 <= MAX_CO) && (y2 >= 0 && y2 <= MAX_CO) , "The min/max X/Y coordinates is 0/239");
+
+    lcd_draw_line(x1, y1, x2, y2);
+    return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_lcd_line_obj, 5, 5, machine_lcd_line);
+
+/// \method rectangle(x1, y1, x2, y2)
+///
+/// display a rectangle on the lcd, from (x1, y1) to (x2, y2).
+///
+STATIC mp_obj_t machine_lcd_rectangle(size_t n_args, const mp_obj_t *args) {
+    // extract arguments
+    machine_lcd_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+
+    int x1 = mp_obj_get_int(args[1]);
+    int y1 = mp_obj_get_int(args[2]);
+    int x2 = mp_obj_get_int(args[3]);
+    int y2 = mp_obj_get_int(args[4]);
+
+    error_check((x1 >= 0 && x1 <= MAX_CO) && (y1 >= 0 && y1 <= MAX_CO) , "The min/max X/Y coordinates is 0/239");
+    error_check((x2 >= 0 && x2 <= MAX_CO) && (y2 >= 0 && y2 <= MAX_CO) , "The min/max X/Y coordinates is 0/239");
+
+    lcd_draw_rectangle(x1, y1, x2, y2);
+    return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_lcd_rectangle_obj, 5, 5, machine_lcd_rectangle);
+
+/// \method circle(x1, y1, r)
+///
+/// display a circle on the lcd, center(x1, y1) R = r.
+///
+STATIC mp_obj_t machine_lcd_circle(size_t n_args, const mp_obj_t *args) {
+    // extract arguments
+    machine_lcd_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+
+    int x1 = mp_obj_get_int(args[1]);
+    int y1 = mp_obj_get_int(args[2]);
+    int r  = mp_obj_get_int(args[3]);
+
+    error_check((x1 >= 0 && x1 <= MAX_CO) && (y1 >= 0 && y1 <= MAX_CO) , "The min/max X/Y coordinates is 0/239");
+
+    lcd_draw_circle(x1, y1, r);
+    return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_lcd_circle_obj, 4, 4, machine_lcd_circle);
+
+STATIC const mp_rom_map_elem_t machine_lcd_locals_dict_table[] = {
+    // instance methods
+    { MP_ROM_QSTR(MP_QSTR_light), MP_ROM_PTR(&machine_lcd_light_obj) },
+    { MP_ROM_QSTR(MP_QSTR_fill),  MP_ROM_PTR(&machine_lcd_fill_obj)  },
+    { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&machine_lcd_pixel_obj) },
+    { MP_ROM_QSTR(MP_QSTR_text),  MP_ROM_PTR(&machine_lcd_text_obj)  },
+    { MP_ROM_QSTR(MP_QSTR_line),  MP_ROM_PTR(&machine_lcd_line_obj)  },
+    { MP_ROM_QSTR(MP_QSTR_rectangle), MP_ROM_PTR(&machine_lcd_rectangle_obj) },
+    { MP_ROM_QSTR(MP_QSTR_circle), MP_ROM_PTR(&machine_lcd_circle_obj) }, 
+    // color
+    { MP_ROM_QSTR(MP_QSTR_WHITE), MP_ROM_INT(WHITE) },
+    { MP_ROM_QSTR(MP_QSTR_BLACK), MP_ROM_INT(BLACK) },
+    { MP_ROM_QSTR(MP_QSTR_BLUE), MP_ROM_INT(BLUE) },
+    { MP_ROM_QSTR(MP_QSTR_BRED), MP_ROM_INT(BRED) },
+    { MP_ROM_QSTR(MP_QSTR_GRED), MP_ROM_INT(GRED) },
+    { MP_ROM_QSTR(MP_QSTR_GBLUE), MP_ROM_INT(GBLUE) },
+    { MP_ROM_QSTR(MP_QSTR_RED), MP_ROM_INT(RED) },
+    { MP_ROM_QSTR(MP_QSTR_MAGENTA), MP_ROM_INT(MAGENTA) },
+    { MP_ROM_QSTR(MP_QSTR_GREEN), MP_ROM_INT(GREEN) },
+    { MP_ROM_QSTR(MP_QSTR_CYAN), MP_ROM_INT(CYAN) },
+    { MP_ROM_QSTR(MP_QSTR_YELLOW), MP_ROM_INT(YELLOW) },
+    { MP_ROM_QSTR(MP_QSTR_BROWN), MP_ROM_INT(BROWN) },
+    { MP_ROM_QSTR(MP_QSTR_BRRED), MP_ROM_INT(BRRED) },
+    { MP_ROM_QSTR(MP_QSTR_GRAY), MP_ROM_INT(GRAY) },
+    { MP_ROM_QSTR(MP_QSTR_GRAY175), MP_ROM_INT(GRAY175) },
+    { MP_ROM_QSTR(MP_QSTR_GRAY151), MP_ROM_INT(GRAY151) },
+    { MP_ROM_QSTR(MP_QSTR_GRAY187), MP_ROM_INT(GRAY187) },
+    { MP_ROM_QSTR(MP_QSTR_GRAY240), MP_ROM_INT(GRAY240) },
+};
+STATIC MP_DEFINE_CONST_DICT(machine_lcd_locals_dict, machine_lcd_locals_dict_table);
+
+const mp_obj_type_t machine_lcd_type = {
+    { &mp_type_type },
+    .name = MP_QSTR_LCD,
+    .make_new = machine_lcd_make_new,
+    .locals_dict = (mp_obj_dict_t*)&machine_lcd_locals_dict,
+};
+
+#endif // MICROPY_PY_MACHINE_LCD

+ 31 - 0
port/machine_lcd.h

@@ -0,0 +1,31 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 SummerGift <SummerGift@qq.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef MICROPY_INCLUDED_MACHINE_LCD_H
+#define MICROPY_INCLUDED_MACHINE_LCD_H
+
+extern const mp_obj_type_t machine_lcd_type;
+
+#endif // MICROPY_INCLUDED_MACHINE_LCD_H

+ 5 - 2
port/modmachine.c

@@ -38,6 +38,7 @@
 #include "extmod/machine_spi.h"
 #include "modmachine.h"
 #include "machine_uart.h"
+#include "machine_lcd.h"
 #include "machine_rtc.h"
 
 #include <rthw.h>
@@ -177,9 +178,8 @@ STATIC mp_obj_t machine_reset_cause(void) {
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause);
 
-
 STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
-    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) },
+    { MP_ROM_QSTR(MP_QSTR___name__),            MP_ROM_QSTR(MP_QSTR_umachine) },
     { MP_ROM_QSTR(MP_QSTR_info),                MP_ROM_PTR(&machine_info_obj) },
     { MP_ROM_QSTR(MP_QSTR_unique_id),           MP_ROM_PTR(&machine_unique_id_obj) },
     { MP_ROM_QSTR(MP_QSTR_reset),               MP_ROM_PTR(&machine_reset_obj) },
@@ -208,6 +208,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
 #if MICROPY_PY_MACHINE_RTC
     { MP_ROM_QSTR(MP_QSTR_RTC),                MP_ROM_PTR(&machine_rtc_type) },
 #endif
+#if MICROPY_PY_MACHINE_LCD
+    { MP_ROM_QSTR(MP_QSTR_LCD),                 MP_ROM_PTR(&machine_lcd_type ) },
+#endif
 };
 
 STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);

+ 4 - 0
port/mpconfigport.h

@@ -143,6 +143,10 @@
 #define MICROPY_PY_MACHINE_UART      (1)
 #endif
 
+#ifdef MICROPYTHON_USING_MACHINE_LCD
+#define MICROPY_PY_MACHINE_LCD       (1)
+#endif
+
 #ifdef MICROPYTHON_USING_MACHINE_RTC
 #define MICROPY_PY_MACHINE_RTC       (1)
 #endif