├── 00.MFRC522 --- 射频卡 ├── main.py └── mfrc522.py ├── 01.LCD1602 --- LCD1602液晶屏 ├── LCD1602.py ├── main.py └── tpyb_lcd1602.py ├── 02.LCD5110 --- LCD5110液晶屏 ├── font_5110.py ├── lcd5110.py └── main.py ├── 03.LCD12864 --- LCD12864液晶屏 ├── lcd12864_lib.py └── main.py ├── 04.TFTLCD --- TFT液晶屏 ├── 44.bmp ├── 55.bmp ├── font1.py ├── main.py └── tftlcd.py ├── 05.DS18X20 --- DS18X20温度传感器 ├── ds18b20.py ├── main.py └── onewire_lib.py ├── 06.AM2320 --- 高精度温湿度传感器 ├── am2320.py └── main.py ├── 07.GY-30 --- 光照强度传感器 ├── gy30.py └── main.py ├── 08.GY39 --- 气象监测模块 ├── GY39_V1.exe ├── gy39.py ├── gy39_i2c.py └── main.py ├── 09.GY68_BMP180 -- 大气压传感器 ├── bmp180.py └── main.py ├── 10.DS3231 --- 时钟模块 ├── ds3231.py └── main.py ├── 11.VS1838B --- 红外接收模块 ├── bm.py ├── main.py └── necir.py ├── 12.NRF24L01 --- 2.4G无线收发模块 ├── main.py ├── nrf24l01.py └── nrf24l01use.py ├── 13.NRF905 --- 2.4G无线收发模块 ├── main.py └── nrf905.py ├── 14.SYN6288 --- SYN6288语音合成模块 ├── main.py └── syn6288.py ├── 15.AT24C0X --- AT24C0X存储器 ├── at24c0x.py └── main.py ├── 16.NixieTube --- 数码管 ├── digital.py └── main.py ├── 17.SteperMotor --- 四相步进电机 ├── main.py └── stepermotor.py ├── 18.PS2 --- PS2无线手柄 ├── main.py └── ps2.py ├── 19.AS608 --- AS608指纹识别 ├── as608.py ├── main.py └── 指纹指令.txt └── README.md /00.MFRC522 --- 射频卡/main.py: -------------------------------------------------------------------------------- 1 | import pyb 2 | import mfrc522 3 | from machine import SPI,Pin 4 | 5 | def main(): 6 | SPI=pyb.SPI(1) 7 | RC522_SDA='X4' 8 | RC522_RST='X2' 9 | rc52=mfrc522.MFRC522() 10 | rc52.init_spi(SPI,RC522_RST,RC522_SDA) 11 | while True: 12 | (status,backBits)=rc52.SeekCard(0x52) 13 | if(status==0): 14 | (status,id,)=rc52.Anticoll() 15 | print("card_id=",id) 16 | else : 17 | print("NO_CARD") 18 | pyb.delay(1000) 19 | main() -------------------------------------------------------------------------------- /00.MFRC522 --- 射频卡/mfrc522.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TPYBoard/TPYBoard_lib/6071a30bcf438c44f834e99e5209c182a2fc287d/00.MFRC522 --- 射频卡/mfrc522.py -------------------------------------------------------------------------------- /01.LCD1602 --- LCD1602液晶屏/LCD1602.py: -------------------------------------------------------------------------------- 1 | """Implements a character based lcd connected via PCF8574 on i2c.""" 2 | 3 | from tpyb_lcd1602 import TPYBoardLcd1602Api 4 | from pyb import Pin 5 | from pyb import delay, udelay 6 | 7 | 8 | class TPYBoardGpioLcd1602(TPYBoardLcd1602Api): 9 | """Implements a character based lcd connected via GPIO pins.""" 10 | 11 | def __init__(self, rs_pin, enable_pin, d0_pin=None, d1_pin=None, 12 | d2_pin=None, d3_pin=None, d4_pin=None, d5_pin=None, 13 | d6_pin=None, d7_pin=None, rw_pin=None, backlight_pin=None, 14 | num_lines=2, num_columns=16): 15 | """Constructs the TPYBoardGpioLcd1602 object. All of the arguments must pyb.Pin 16 | objects which ddescribe which pin the given line from the LCD is 17 | connected to. 18 | 19 | When used in 4-bit mode, only D4, D5, D6, and D7 are physically 20 | connected to the LCD panel. This function allows you call it like 21 | TPYBoardGpioLcd1602(rs, enable, D4, D5, D6, D7) and it will interpret that as 22 | if you had actually called: 23 | TPYBoardGpioLcd1602(rs, enable, d4=D4, d5=D5, d6=D6, d7=D7) 24 | 25 | The enable 8-bit mode, you need pass d0 thru d7. 26 | 27 | The rw pin isn't used by this library, but if you specify it, then 28 | it will be set low. 29 | """ 30 | self.rs_pin = rs_pin 31 | self.enable_pin = enable_pin 32 | self.rw_pin = rw_pin 33 | self.backlight_pin = backlight_pin 34 | self._4bit = True 35 | if d4_pin and d5_pin and d6_pin and d7_pin: 36 | self.d0_pin = d0_pin 37 | self.d1_pin = d1_pin 38 | self.d2_pin = d2_pin 39 | self.d3_pin = d3_pin 40 | self.d4_pin = d4_pin 41 | self.d5_pin = d5_pin 42 | self.d6_pin = d6_pin 43 | self.d7_pin = d7_pin 44 | if self.d0_pin and self.d1_pin and self.d2_pin and self.d3_pin: 45 | self._4bit = False 46 | else: 47 | # This is really 4-bit mode, and the 4 data pins were just 48 | # passed as the first 4 arguments, so we switch things around. 49 | self.d0_pin = None 50 | self.d1_pin = None 51 | self.d2_pin = None 52 | self.d3_pin = None 53 | self.d4_pin = d0_pin 54 | self.d5_pin = d1_pin 55 | self.d6_pin = d2_pin 56 | self.d7_pin = d3_pin 57 | self.rs_pin.init(Pin.OUT_PP) 58 | self.rs_pin.low() 59 | if self.rw_pin: 60 | self.rw_pin.init(Pin.OUT_PP) 61 | self.rw_pin.low() 62 | self.enable_pin.init(Pin.OUT_PP) 63 | self.enable_pin.low() 64 | self.d4_pin.init(Pin.OUT_PP) 65 | self.d5_pin.init(Pin.OUT_PP) 66 | self.d6_pin.init(Pin.OUT_PP) 67 | self.d7_pin.init(Pin.OUT_PP) 68 | self.d4_pin.low() 69 | self.d5_pin.low() 70 | self.d6_pin.low() 71 | self.d7_pin.low() 72 | if not self._4bit: 73 | self.d0_pin.init(Pin.OUT_PP) 74 | self.d1_pin.init(Pin.OUT_PP) 75 | self.d2_pin.init(Pin.OUT_PP) 76 | self.d3_pin.init(Pin.OUT_PP) 77 | self.d0_pin.low() 78 | self.d1_pin.low() 79 | self.d2_pin.low() 80 | self.d3_pin.low() 81 | if self.backlight_pin is not None: 82 | self.backlight_pin.init(Pin.OUT_PP) 83 | self.backlight_pin.low() 84 | 85 | # See about splitting this into begin 86 | 87 | delay(20) # Allow LCD time to powerup 88 | # Send reset 3 times 89 | self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) 90 | delay(5) # need to delay at least 4.1 msec 91 | self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) 92 | delay(1) 93 | self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) 94 | delay(1) 95 | cmd = self.LCD_FUNCTION 96 | if not self._4bit: 97 | cmd |= self.LCD_FUNCTION_8BIT 98 | self.hal_write_init_nibble(cmd) 99 | delay(1) 100 | TPYBoardLcd1602Api.__init__(self, num_lines, num_columns) 101 | if num_lines > 1: 102 | cmd |= self.LCD_FUNCTION_2LINES 103 | self.hal_write_command(cmd) 104 | 105 | def hal_pulse_enable(self): 106 | """Pulse the enable line high, and then low again.""" 107 | self.enable_pin.low() 108 | udelay(1) 109 | self.enable_pin.high() 110 | udelay(1) # Enable pulse needs to be > 450 nsec 111 | self.enable_pin.low() 112 | udelay(100) # Commands need > 37us to settle 113 | 114 | def hal_write_init_nibble(self, nibble): 115 | """Writes an initialization nibble to the LCD. 116 | 117 | This particular function is only used during intiialization. 118 | """ 119 | self.hal_write_4bits(nibble >> 4) 120 | 121 | def hal_backlight_on(self): 122 | """Allows the hal layer to turn the backlight on.""" 123 | if self.backlight_pin: 124 | self.backlight_pin.high() 125 | 126 | def hal_backlight_off(self): 127 | """Allows the hal layer to turn the backlight off.""" 128 | if self.backlight_pin: 129 | self.backlight_pin.low() 130 | 131 | def hal_write_command(self, cmd): 132 | """Writes a command to the LCD. 133 | 134 | Data is latched on the falling edge of E. 135 | """ 136 | self.rs_pin.low() 137 | self.hal_write_8bits(cmd) 138 | if cmd <= 3: 139 | # The home and clear commands require a worst 140 | # case delay of 4.1 msec 141 | delay(5) 142 | 143 | def hal_write_data(self, data): 144 | """Write data to the LCD.""" 145 | self.rs_pin.high() 146 | self.hal_write_8bits(data) 147 | 148 | def hal_write_8bits(self, value): 149 | """Writes 8 bits of data to the LCD.""" 150 | if self.rw_pin: 151 | self.rw_pin.low() 152 | if self._4bit: 153 | self.hal_write_4bits(value >> 4) 154 | self.hal_write_4bits(value) 155 | else: 156 | self.d3_pin.value(value & 0x08) 157 | self.d2_pin.value(value & 0x04) 158 | self.d1_pin.value(value & 0x02) 159 | self.d0_pin.value(value & 0x01) 160 | self.hal_write_4bits(value >> 4) 161 | 162 | def hal_write_4bits(self, nibble): 163 | """Writes 4 bits of data to the LCD.""" 164 | self.d7_pin.value(nibble & 0x08) 165 | self.d6_pin.value(nibble & 0x04) 166 | self.d5_pin.value(nibble & 0x02) 167 | self.d4_pin.value(nibble & 0x01) 168 | self.hal_pulse_enable() 169 | -------------------------------------------------------------------------------- /01.LCD1602 --- LCD1602液晶屏/main.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TPYBoard/TPYBoard_lib/6071a30bcf438c44f834e99e5209c182a2fc287d/01.LCD1602 --- LCD1602液晶屏/main.py -------------------------------------------------------------------------------- /01.LCD1602 --- LCD1602液晶屏/tpyb_lcd1602.py: -------------------------------------------------------------------------------- 1 | """Provides an API for talking to HD44780 style character LCDs.""" 2 | 3 | 4 | class TPYBoardLcd1602Api(object): 5 | """Implements the API for talking with n LCD. This class only knows what 6 | commands to send to the LCD, and not how t get them to the LCD. 7 | 8 | It is expected that a derived class will implement the hal_xxx functions. 9 | """ 10 | 11 | # The following constant names were lifted from the avrlib lcd.h 12 | # header file, however, I changed the definitions from bit numbers 13 | # to bit masks. 14 | # 15 | # HD44780 LCD controller command set 16 | 17 | LCD_CLR = 0x01 # DB0: clear display 18 | LCD_HOME = 0x02 # DB1: return to home position 19 | 20 | LCD_ENTRY_MODE = 0x04 # DB2: set entry mode 21 | LCD_ENTRY_INC = 0x02 # --DB1: increment 22 | LCD_ENTRY_SHIFT = 0x01 # --DB0: shift 23 | 24 | LCD_ON_CTRL = 0x08 # DB3: turn lcd/cursor on 25 | LCD_ON_DISPLAY = 0x04 # --DB2: turn display on 26 | LCD_ON_CURSOR = 0x02 # --DB1: turn cursor on 27 | LCD_ON_BLINK = 0x01 # --DB0: blinking cursor 28 | 29 | LCD_MOVE = 0x10 # DB4: move cursor/display 30 | LCD_MOVE_DISP = 0x08 # --DB3: move display (0-> move cursor) 31 | LCD_MOVE_RIGHT = 0x04 # --DB2: move right (0-> left) 32 | 33 | LCD_FUNCTION = 0x20 # DB5: function set 34 | LCD_FUNCTION_8BIT = 0x10 # --DB4: set 8BIT mode (0->4BIT mode) 35 | LCD_FUNCTION_2LINES = 0x08 # --DB3: two lines (0->one line) 36 | LCD_FUNCTION_10DOTS = 0x04 # --DB2: 5x10 font (0->5x7 font) 37 | LCD_FUNCTION_RESET = 0x30 # See "Initializing by Instruction" section 38 | 39 | LCD_CGRAM = 0x40 # DB6: set CG RAM address 40 | LCD_DDRAM = 0x80 # DB7: set DD RAM address 41 | 42 | LCD_RS_CMD = 0 43 | LCD_RS_DATA = 1 44 | 45 | LCD_RW_WRITE = 0 46 | LCD_RW_READ = 1 47 | 48 | def __init__(self, num_lines, num_columns): 49 | self.num_lines = num_lines 50 | if self.num_lines > 4: 51 | self.num_lines = 4 52 | self.num_columns = num_columns 53 | if self.num_columns > 40: 54 | self.num_columns = 40 55 | self.cursor_x = 0 56 | self.cursor_y = 0 57 | self.backlight = True 58 | self.display_off() 59 | self.backlight_on() 60 | self.clear() 61 | self.hal_write_command(self.LCD_ENTRY_MODE | self.LCD_ENTRY_INC) 62 | self.hide_cursor() 63 | self.display_on() 64 | 65 | def clear(self): 66 | """Clears the LCD display and moves the cursor to the top left 67 | corner. 68 | 69 | """ 70 | self.hal_write_command(self.LCD_CLR) 71 | self.hal_write_command(self.LCD_HOME) 72 | self.cursor_x = 0 73 | self.cursor_y = 0 74 | 75 | def show_cursor(self): 76 | """Causes the cursor to be made visible.""" 77 | self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY | 78 | self.LCD_ON_CURSOR) 79 | 80 | def hide_cursor(self): 81 | """Causes the cursor to be hidden.""" 82 | self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY) 83 | 84 | def blink_cursor_on(self): 85 | """Turns on the cursor, and makes it blink.""" 86 | self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY | 87 | self.LCD_ON_CURSOR | self.LCD_ON_BLINK) 88 | 89 | def blink_cursor_off(self): 90 | """Turns on the cursor, and makes it no blink (i.e. be solid).""" 91 | self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY | 92 | self.LCD_ON_CURSOR) 93 | 94 | def display_on(self): 95 | """Turns on (i.e. unblanks) the LCD.""" 96 | self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY) 97 | 98 | def display_off(self): 99 | """Turns off (i.e. blanks) the LCD.""" 100 | self.hal_write_command(self.LCD_ON_CTRL) 101 | 102 | def backlight_on(self): 103 | """Turns the backlight on. 104 | 105 | This isn't really an LCD command, but some modules have backlight 106 | controls, so this allows the hal to pass through the command. 107 | """ 108 | self.backlight = True 109 | self.hal_backlight_on() 110 | 111 | def backlight_off(self): 112 | """Turns the backlight off. 113 | 114 | This isn't really an LCD command, but some modules have backlight 115 | controls, so this allows the hal to pass through the command. 116 | """ 117 | self.backlight = False 118 | self.hal_backlight_off() 119 | 120 | def move_to(self, cursor_x, cursor_y): 121 | """Moves the cursor position to the indicated position. The cursor 122 | position is zero based (i.e. cursor_x == 0 indicates first column). 123 | """ 124 | self.cursor_x = cursor_x 125 | self.cursor_y = cursor_y 126 | addr = cursor_x & 0x3f 127 | if cursor_y & 1: 128 | addr += 0x40 # Lines 1 & 3 add 0x40 129 | if cursor_y & 2: 130 | addr += 0x14 # Lines 2 & 3 add 0x14 131 | self.hal_write_command(self.LCD_DDRAM | addr) 132 | 133 | def lcd1602_write_char(self, char): 134 | """Writes the indicated charcter to the LCD at the current cursor 135 | position, and advances the cursor by one position. 136 | """ 137 | if self.cursor_x >= self.num_columns or char == '\n': 138 | self.cursor_x = 0 139 | self.cursor_y += 1 140 | if self.cursor_y >= self.num_lines: 141 | self.cursor_y = 0 142 | self.move_to(self.cursor_x, self.cursor_y) 143 | if char != '\n': 144 | self.hal_write_data(ord(char)) 145 | self.cursor_x += 1 146 | 147 | def lcd1602_write_string(self, string): 148 | """Write the indicated string to the LCD at the current cursor 149 | position and advances the cursor position appropriately. 150 | """ 151 | for char in string: 152 | self.lcd1602_write_char(char) 153 | 154 | def hal_backlight_on(self): 155 | """Allows the hal layer to turn the backlight on. 156 | 157 | If desired, a derived HAL class will implement this function. 158 | """ 159 | pass 160 | 161 | def hal_backlight_off(self): 162 | """Allows the hal layer to turn the backlight off. 163 | 164 | If desired, a derived HAL class will implement this function. 165 | """ 166 | 167 | pass 168 | 169 | def hal_write_command(self, cmd): 170 | """Write a command to the LCD. 171 | 172 | It is expected that a derived HAL class will implement this 173 | function. 174 | """ 175 | raise NotImplementedError 176 | 177 | def hal_write_data(self, data): 178 | """Write data to the LCD. 179 | 180 | It is expected that a derived HAL class will implement this 181 | function. 182 | """ 183 | raise NotImplementedError 184 | -------------------------------------------------------------------------------- /02.LCD5110 --- LCD5110液晶屏/font_5110.py: -------------------------------------------------------------------------------- 1 | class FONT6_8: 2 | """docstring for FONT6_8""" 3 | FONTTYPE6_8 = [ 4 | [0x00, 0x00, 0x00, 0x00, 0x00, 0x00] # 20 5 | ,[0x00, 0x00, 0x00, 0x5f, 0x00, 0x00] # 21 ! 6 | ,[0x00, 0x00, 0x07, 0x00, 0x07, 0x00] # 22 " 7 | ,[0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14] # 23 # 8 | ,[0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12] # 24 $ 9 | ,[0x00, 0x23, 0x13, 0x08, 0x64, 0x62] # 25 % 10 | ,[0x00, 0x36, 0x49, 0x55, 0x22, 0x50] # 26 & 11 | ,[0x00, 0x00, 0x05, 0x03, 0x00, 0x00] # 27 ' 12 | ,[0x00, 0x00, 0x1c, 0x22, 0x41, 0x00] # 28 ( 13 | ,[0x00, 0x00, 0x41, 0x22, 0x1c, 0x00] # 29 ) 14 | ,[0x00, 0x14, 0x08, 0x3e, 0x08, 0x14] # 2a * 15 | ,[0x00, 0x08, 0x08, 0x3e, 0x08, 0x08] # 2b + 16 | ,[0x00, 0x00, 0x50, 0x30, 0x00, 0x00] # 2c , 17 | ,[0x00, 0x08, 0x08, 0x08, 0x08, 0x08] # 2d - 18 | ,[0x00, 0x00, 0x60, 0x60, 0x00, 0x00] # 2e . 19 | ,[0x00, 0x20, 0x10, 0x08, 0x04, 0x02] # 2f / 20 | ,[0x00, 0x3e, 0x51, 0x49, 0x45, 0x3e] # 30 0 21 | ,[0x00, 0x00, 0x42, 0x7f, 0x40, 0x00] # 31 1 22 | ,[0x00, 0x42, 0x61, 0x51, 0x49, 0x46] # 32 2 23 | ,[0x00, 0x21, 0x41, 0x45, 0x4b, 0x31] # 33 3 24 | ,[0x00, 0x18, 0x14, 0x12, 0x7f, 0x10] # 34 4 25 | ,[0x00, 0x27, 0x45, 0x45, 0x45, 0x39] # 35 5 26 | ,[0x00, 0x3c, 0x4a, 0x49, 0x49, 0x30] # 36 6 27 | ,[0x00, 0x01, 0x71, 0x09, 0x05, 0x03] # 37 7 28 | ,[0x00, 0x36, 0x49, 0x49, 0x49, 0x36] # 38 8 29 | ,[0x00, 0x06, 0x49, 0x49, 0x29, 0x1e] # 39 9 30 | ,[0x00, 0x00, 0x36, 0x36, 0x00, 0x00] # 3a : 31 | ,[0x00, 0x00, 0x56, 0x36, 0x00, 0x00] # 3b ; 32 | ,[0x00, 0x08, 0x14, 0x22, 0x41, 0x00] # 3c < 33 | ,[0x00, 0x14, 0x14, 0x14, 0x14, 0x14] # 3d = 34 | ,[0x00, 0x00, 0x41, 0x22, 0x14, 0x08] # 3e > 35 | ,[0x00, 0x02, 0x01, 0x51, 0x09, 0x06] # 3f ? 36 | ,[0x00, 0x32, 0x49, 0x79, 0x41, 0x3e] # 40 @ 37 | ,[0x00, 0x7e, 0x11, 0x11, 0x11, 0x7e] # 41 A 38 | ,[0x00, 0x7f, 0x49, 0x49, 0x49, 0x36] # 42 B 39 | ,[0x00, 0x3e, 0x41, 0x41, 0x41, 0x22] # 43 C 40 | ,[0x00, 0x7f, 0x41, 0x41, 0x22, 0x1c] # 44 D 41 | ,[0x00, 0x7f, 0x49, 0x49, 0x49, 0x41] # 45 E 42 | ,[0x00, 0x7f, 0x09, 0x09, 0x09, 0x01] # 46 F 43 | ,[0x00, 0x3e, 0x41, 0x49, 0x49, 0x7a] # 47 G 44 | ,[0x00, 0x7f, 0x08, 0x08, 0x08, 0x7f] # 48 H 45 | ,[0x00, 0x00, 0x41, 0x7f, 0x41, 0x00] # 49 I 46 | ,[0x00, 0x20, 0x40, 0x41, 0x3f, 0x01] # 4a J 47 | ,[0x00, 0x7f, 0x08, 0x14, 0x22, 0x41] # 4b K 48 | ,[0x00, 0x7f, 0x40, 0x40, 0x40, 0x40] # 4c L 49 | ,[0x00, 0x7f, 0x02, 0x0c, 0x02, 0x7f] # 4d M 50 | ,[0x00, 0x7f, 0x04, 0x08, 0x10, 0x7f] # 4e N 51 | ,[0x00, 0x3e, 0x41, 0x41, 0x41, 0x3e] # 4f O 52 | ,[0x00, 0x7f, 0x09, 0x09, 0x09, 0x06] # 50 P 53 | ,[0x00, 0x3e, 0x41, 0x51, 0x21, 0x5e] # 51 Q 54 | ,[0x00, 0x7f, 0x09, 0x19, 0x29, 0x46] # 52 R 55 | ,[0x00, 0x46, 0x49, 0x49, 0x49, 0x31] # 53 S 56 | ,[0x00, 0x01, 0x01, 0x7f, 0x01, 0x01] # 54 T 57 | ,[0x00, 0x3f, 0x40, 0x40, 0x40, 0x3f] # 55 U 58 | ,[0x00, 0x1f, 0x20, 0x40, 0x20, 0x1f] # 56 V 59 | ,[0x00, 0x3f, 0x40, 0x38, 0x40, 0x3f] # 57 W 60 | ,[0x00, 0x63, 0x14, 0x08, 0x14, 0x63] # 58 X 61 | ,[0x00, 0x07, 0x08, 0x70, 0x08, 0x07] # 59 Y 62 | ,[0x00, 0x61, 0x51, 0x49, 0x45, 0x43] # 5a Z 63 | ,[0x00, 0x00, 0x7f, 0x41, 0x41, 0x00] # 5b [ 64 | ,[0x00, 0x02, 0x04, 0x08, 0x10, 0x20] # 5c \ # 65 | ,[0x00, 0x00, 0x41, 0x41, 0x7f, 0x00] # 5d ] 66 | ,[0x00, 0x04, 0x02, 0x01, 0x02, 0x04] # 5e ^ 67 | ,[0x00, 0x40, 0x40, 0x40, 0x40, 0x40] # 5f _ 68 | ,[0x00, 0x00, 0x01, 0x02, 0x04, 0x00] # 60 ` 69 | ,[0x00, 0x20, 0x54, 0x54, 0x54, 0x78] # 61 a 70 | ,[0x00, 0x7f, 0x48, 0x44, 0x44, 0x38] # 62 b 71 | ,[0x00, 0x38, 0x44, 0x44, 0x44, 0x20] # 63 c 72 | ,[0x00, 0x38, 0x44, 0x44, 0x48, 0x7f] # 64 d 73 | ,[0x00, 0x38, 0x54, 0x54, 0x54, 0x18] # 65 e 74 | ,[0x00, 0x08, 0x7e, 0x09, 0x01, 0x02] # 66 f 75 | ,[0x00, 0x0c, 0x52, 0x52, 0x52, 0x3e] # 67 g 76 | ,[0x00, 0x7f, 0x08, 0x04, 0x04, 0x78] # 68 h 77 | ,[0x00, 0x00, 0x44, 0x7d, 0x40, 0x00] # 69 i 78 | ,[0x00, 0x20, 0x40, 0x44, 0x3d, 0x00] # 6a j 79 | ,[0x00, 0x7f, 0x10, 0x28, 0x44, 0x00] # 6b k 80 | ,[0x00, 0x00, 0x41, 0x7f, 0x40, 0x00] # 6c l 81 | ,[0x00, 0x7c, 0x04, 0x18, 0x04, 0x78] # 6d m 82 | ,[0x00, 0x7c, 0x08, 0x04, 0x04, 0x78] # 6e n 83 | ,[0x00, 0x38, 0x44, 0x44, 0x44, 0x38] # 6f o 84 | ,[0x00, 0x7c, 0x14, 0x14, 0x14, 0x08] # 70 p 85 | ,[0x00, 0x08, 0x14, 0x14, 0x18, 0x7c] # 71 q 86 | ,[0x00, 0x7c, 0x08, 0x04, 0x04, 0x08] # 72 r 87 | ,[0x00, 0x48, 0x54, 0x54, 0x54, 0x20] # 73 s 88 | ,[0x00, 0x04, 0x3f, 0x44, 0x40, 0x20] # 74 t 89 | ,[0x00, 0x3c, 0x40, 0x40, 0x20, 0x7c] # 75 u 90 | ,[0x00, 0x1c, 0x20, 0x40, 0x20, 0x1c] # 76 v 91 | ,[0x00, 0x3c, 0x40, 0x30, 0x40, 0x3c] # 77 w 92 | ,[0x00, 0x44, 0x28, 0x10, 0x28, 0x44] # 78 x 93 | ,[0x00, 0x0c, 0x50, 0x50, 0x50, 0x3c] # 79 y 94 | ,[0x00, 0x44, 0x64, 0x54, 0x4c, 0x44] # 7a z 95 | ,[0x00, 0x00, 0x08, 0x36, 0x41, 0x00] # 7b [ 96 | ,[0x00, 0x00, 0x00, 0x7f, 0x00, 0x00] # 7c | 97 | ,[0x00, 0x00, 0x41, 0x36, 0x08, 0x00] # 7d ] 98 | ,[0x00, 0x10, 0x08, 0x08, 0x10, 0x08] # 7e ~ 99 | ,[0x00, 0x78, 0x46, 0x41, 0x46, 0x78] # 7f (delete) 100 | ] 101 | 102 | def get_font6_8(self, data): 103 | return self.FONTTYPE6_8[bytearray(data)[0] - 0x20] 104 | 105 | -------------------------------------------------------------------------------- /02.LCD5110 --- LCD5110液晶屏/lcd5110.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | MicroPython PCD8544 driver 4 | (for Nokia 5110 displays) 5 | """ 6 | 7 | __author__ = "Markus Birth" 8 | __copyright__ = "Copyright 2015, Markus Birth" 9 | __credits__ = ["Markus Birth"] 10 | __license__ = "MIT" 11 | __version__ = "1.0" 12 | __maintainer__ = "Markus Birth" 13 | __email__ = "markus@birth-online.de" 14 | __status__ = "Production" 15 | 16 | # Datasheet: https://www.sparkfun.com/datasheets/LCD/Monochrome/Nokia5110.pdf 17 | # Inspiration from: 18 | # - https://github.com/inaugurator/upyd5110 19 | # - https://github.com/rm-hull/pcd8544/blob/master/src/lcd.py 20 | # 21 | # PINOUT 22 | # WiPy/pyBoard display function 23 | # 24 | # 3V3 or any Pin => VCC 3.3V logic voltage (0=off, 1=on) 25 | # MOSI => DIN data flow (Master out, Slave in) 26 | # SCK => CLK SPI clock 27 | # any Pin => RST Reset pin (0=reset, 1=normal) 28 | # any Pin => CE Chip Enable (0=listen for input, 1=ignore input) 29 | # any Pin => DC Data/Command (0=commands, 1=data) 30 | # any Pin => LIGHT Light (0=on, 1=off) 31 | # GND => GND 32 | # 33 | # pyBoard "Y" side 34 | # SPI = pyb.SPI(1) 35 | # RST = pyb.Pin('Y4') 36 | # CE = pyb.Pin('Y5') 37 | # DC = pyb.Pin('Y3') 38 | # LIGHT = pyb.Pin('Y2') 39 | # PWR = pyb.Pin('Y1') 40 | # 41 | # pyBoard "X" side 42 | # SPI = pyb.SPI(2) 43 | # RST = pyb.Pin('X4') 44 | # CE = pyb.Pin('X5') 45 | # DC = pyb.Pin('X3') 46 | # LIGHT = pyb.Pin('X2') 47 | # PWR = pyb.Pin('X1') 48 | # 49 | # WiPy (on Exp board, SD and User-LED jumper have to be removed!) 50 | # SPI = machine.SPI(0) # GP14 (CLK) + GP16 (MOSI->DIN), User-LED jumper removed! 51 | # RST = machine.Pin('GP24') 52 | # CE = machine.Pin('GP12') 53 | # DC = machine.Pin('GP22') 54 | # LIGHT = machine.Pin('GP23') 55 | # PWR = directly from 3V3 pin of the WiPy 56 | 57 | try: 58 | import pyb as machine 59 | except: 60 | # WiPy 61 | import machine 62 | 63 | import struct 64 | import time 65 | import font_5110 66 | 67 | class LCD5110: 68 | ADDRESSING_HORIZ = 0x00 69 | ADDRESSING_VERT = 0x02 70 | INSTR_BASIC = 0x00 71 | INSTR_EXT = 0x01 72 | POWER_UP = 0x00 73 | POWER_DOWN = 0x04 74 | DISPLAY_BLANK = 0x08 75 | DISPLAY_ALL = 0x09 76 | DISPLAY_NORMAL = 0x0c 77 | DISPLAY_INVERSE = 0x0d 78 | TEMP_COEFF_0 = 0x04 79 | TEMP_COEFF_1 = 0x05 80 | TEMP_COEFF_2 = 0x06 81 | TEMP_COEFF_3 = 0x07 82 | BIAS_1_4 = 0x17 # 1/4th 83 | BIAS_1_5 = 0x16 # 1/5th 84 | BIAS_1_6 = 0x15 # 1/6th 85 | BIAS_1_7 = 0x14 # 1/7th 86 | BIAS_1_8 = 0x13 # 1/8th 87 | BIAS_1_9 = 0x12 # 1/9th 88 | BIAS_1_10 = 0x11 # 1/10th 89 | BIAS_1_11 = 0x10 # 1/11th 90 | 91 | def __init__(self, spi, rst, ce, dc, light, pwr=None): 92 | self.width = 84 93 | self.height = 48 94 | self.power = self.POWER_DOWN 95 | self.addressing = self.ADDRESSING_HORIZ 96 | self.instr = self.INSTR_BASIC 97 | self.display_mode = self.DISPLAY_BLANK 98 | self.temp_coeff = self.TEMP_COEFF_0 99 | self.bias = self.BIAS_1_11 100 | self.voltage = 3060 101 | 102 | # init the SPI bus and pins 103 | spi.init(spi.MASTER, baudrate=328125, bits=8, polarity=0, phase=1, firstbit=spi.MSB) 104 | if "OUT_PP" in dir(rst): 105 | # pyBoard style 106 | rst.init(rst.OUT_PP, rst.PULL_NONE) # Reset line 107 | ce.init(ce.OUT_PP, ce.PULL_NONE) # Chip Enable 108 | dc.init(dc.OUT_PP, dc.PULL_NONE) # Data(1) / Command(0) mode 109 | light.init(light.OUT_PP, light.PULL_NONE) 110 | if pwr: 111 | pwr.init(pwr.OUT_PP, pwr.PULL_NONE) 112 | else: 113 | # WiPy style 114 | rst.init(rst.OUT, None) 115 | ce.init(ce.OUT, None) 116 | dc.init(dc.OUT, None) 117 | light.init(light.OUT, None) 118 | if pwr: 119 | pwr.init(pwr.OUT, None) 120 | 121 | self.spi = spi 122 | self.rst = rst 123 | self.ce = ce 124 | self.dc = dc 125 | self.light = light 126 | self.pwr = pwr 127 | 128 | self.light_off() 129 | self.power_on() 130 | self.ce.value(1) # set chip to disable (don't listen to input) 131 | self.reset() 132 | self.set_contrast(0xbf) 133 | self.clear() 134 | 135 | self.lcd_font = font_5110.FONT6_8() 136 | 137 | 138 | def _set_function(self): 139 | """ Write current power/addressing/instructionset values to lcd. """ 140 | value = 0x20 | self.power | self.addressing | self.instr 141 | self.command([value]) 142 | 143 | def set_power(self, power, set=True): 144 | """ Sets the power mode of the LCD controller """ 145 | assert power in [self.POWER_UP, self.POWER_DOWN], "Power must be POWER_UP or POWER_DOWN." 146 | self.power = power 147 | if set: 148 | self._set_function() 149 | 150 | def set_adressing(self, addr, set=True): 151 | """ Sets the adressing mode """ 152 | assert addr in [self.ADDRESSING_HORIZ, self.ADDRESSING_VERT], "Addressing must be ADDRESSING_HORIZ or ADDRESSING_VERT." 153 | self.addressing = addr 154 | if set: 155 | self._set_function() 156 | 157 | def set_instr(self, instr, set=True): 158 | """ Sets instruction set (basic/extended) """ 159 | assert instr in [self.INSTR_BASIC, self.INSTR_EXT], "Instr must be INSTR_BASIC or INSTR_EXT." 160 | self.instr = instr 161 | if set: 162 | self._set_function() 163 | 164 | def set_display(self, display_mode): 165 | """ Sets display mode (blank, black, normal, inverse) """ 166 | assert display_mode in [self.DISPLAY_BLANK, self.DISPLAY_ALL, self.DISPLAY_NORMAL, self.DISPLAY_INVERSE], "Mode must be one of DISPLAY_BLANK, DISPLAY_ALL, DISPLAY_NORMAL or DISPLAY_INVERSE." 167 | assert self.instr == self.INSTR_BASIC, "Please switch to basic instruction set first." 168 | self.display_mode = display_mode 169 | self.command([display_mode]) 170 | 171 | def set_temp_coeff(self, temp_coeff): 172 | """ Sets temperature coefficient (0-3) """ 173 | assert 4 <= temp_coeff < 8, "Temperature coefficient must be one of TEMP_COEFF_0..TEMP_COEFF_3." 174 | assert self.instr == self.INSTR_EXT, "Please switch to extended instruction set first." 175 | self.temp_coeff = temp_coeff 176 | self.command([temp_coeff]) 177 | 178 | def set_bias(self, bias): 179 | """ Sets the LCD bias. """ 180 | assert 0x10 <= bias <= 0x17, "Bias must be one of BIAS_1_4..BIAS_1_11." 181 | assert self.instr == self.INSTR_EXT, "Please switch to extended instruction set first." 182 | self.bias = bias 183 | self.command([bias]) 184 | 185 | def set_voltage(self, millivolts): 186 | """ Sets the voltage of the LCD charge pump in millivolts. """ 187 | assert 3060 <= millivolts <= 10680, "Voltage must be between 3,060 and 10,680 mV." 188 | assert self.instr == self.INSTR_EXT, "Please switch to extended instruction set first." 189 | self.voltage = millivolts 190 | basevoltage = millivolts - 3060 191 | incrementor = basevoltage // 60 192 | code = 0x80 & incrementor 193 | self.command([code]) 194 | 195 | def set_contrast(self, value): 196 | """ set LCD voltage, i.e. contrast """ 197 | assert 0x80 <= value <= 0xff, "contrast value must be between 0x80 and 0xff" 198 | self.command([0x21, self.TEMP_COEFF_2, self.BIAS_1_7, value, 0x20, self.DISPLAY_NORMAL]) 199 | # 0x21 - enter extended instruction set (H=1) 200 | # 0x06 - set temperature coefficient 2 201 | # 0x14 - set BIAS system to n=3 (recomm. mux rate 1:40/1:34) 202 | # value - (80-ff) - set Vop (80 = 3.00V, ff = 10.68V), 8b seems to work (0x3b/d70: 3.00+(70*0.06)=7.2V) 203 | # 0x20 - back to basic instruction set 204 | # 0x0c - normal display mode 205 | 206 | def position(self, x, y): 207 | """ set cursor to bank y, column x """ 208 | assert 0 <= x < self.width, "x must be between 0 and 83" 209 | assert 0 <= y < self.height // 8, "y must be between 0 and 5" 210 | assert self.instr == self.INSTR_BASIC, "Please switch to basic instruction set first." 211 | self.command([x + 0x80, y + 0x40]) 212 | 213 | def clear(self): 214 | """ clear screen """ 215 | self.position(0, 0) 216 | self.data([0] * (self.height * self.width // 8)) 217 | self.position(0, 0) 218 | 219 | def sleep_ms(self, mseconds): 220 | try: 221 | time.sleep_ms(mseconds) 222 | except AttributeError: 223 | machine.delay(mseconds) 224 | 225 | def sleep_us(self, useconds): 226 | try: 227 | time.sleep_us(useconds) 228 | except AttributeError: 229 | machine.udelay(useconds) 230 | 231 | def power_on(self): 232 | if self.pwr: 233 | self.pwr.value(1) 234 | self.reset() 235 | 236 | def reset(self): 237 | """ issue reset impulse to reset the display """ 238 | self.rst.value(0) # RST on 239 | self.sleep_us(100) # reset impulse has to be >100 ns and <100 ms 240 | self.rst.value(1) # RST off 241 | # Defaults after reset: 242 | self.power = self.POWER_DOWN 243 | self.addressing = self.ADDRESSING_HORIZ 244 | self.instr = self.INSTR_BASIC 245 | self.display_mode = self.DISPLAY_BLANK 246 | self.temp_coeff = self.TEMP_COEFF_0 247 | self.bias = self.BIAS_1_11 248 | self.voltage = 3060 249 | 250 | def power_off(self): 251 | self.clear() 252 | self.command([0x20, 0x08]) 253 | # 0x20 - basic instruction set 254 | # 0x08 - set display to blank (doesn't delete contents) 255 | self.sleep_ms(10) 256 | if self.pwr: 257 | self.pwr.value(0) # turn off power 258 | 259 | def command(self, arr): 260 | """ send bytes in command mode """ 261 | self.bitmap(arr, 0) 262 | 263 | def data(self, arr): 264 | """ send bytes in data mode """ 265 | self.bitmap(arr, 1) 266 | 267 | def bitmap(self, arr, dc): 268 | self.dc.value(dc) 269 | buf = struct.pack('B'*len(arr), *arr) 270 | self.ce.value(0) # set chip to listening/enable 271 | try: 272 | self.spi.send(buf) 273 | except AttributeError: 274 | self.spi.write(buf) 275 | self.ce.value(1) # set chip to disable 276 | 277 | def light_on(self): 278 | self.light.value(0) # pull to GND 279 | 280 | def light_off(self): 281 | self.light.value(1) # set to HIGH 282 | 283 | def lcd_write_string(self, string, x, y): 284 | self.position(x, y) 285 | for i in string: 286 | self.data(self.lcd_font.get_font6_8(i)) -------------------------------------------------------------------------------- /02.LCD5110 --- LCD5110液晶屏/main.py: -------------------------------------------------------------------------------- 1 | #main.py 2 | import pyb 3 | import lcd5110 4 | from machine import SPI,Pin 5 | 6 | def main(): 7 | SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK 8 | #DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in) 9 | #CLK =>SPI(1).SCK 'X6' SPI clock 10 | 11 | RST = pyb.Pin('Y10') 12 | CE = pyb.Pin('Y11') 13 | DC = pyb.Pin('Y9') 14 | LIGHT = pyb.Pin('Y12') 15 | lcd_5110 = lcd5110.LCD5110(SPI, RST, CE, DC, LIGHT) 16 | 17 | lcd_5110.lcd_write_string('Hello Python!',0,0) 18 | lcd_5110.lcd_write_string('Micropython',6,1) 19 | lcd_5110.lcd_write_string('TPYBoard',12,2) 20 | lcd_5110.lcd_write_string('v102',60,3) 21 | lcd_5110.lcd_write_string('This is a test of LCD5110',0,4) 22 | 23 | 24 | if __name__ == '__main__': 25 | main() 26 | -------------------------------------------------------------------------------- /03.LCD12864 --- LCD12864液晶屏/lcd12864_lib.py: -------------------------------------------------------------------------------- 1 | #地址 80-87 2 | # 90-97 3 | # 88-8F 4 | # 98-9F 5 | import pyb 6 | import time 7 | 8 | class LCD12864: 9 | 10 | def __init__(self,rs,e): 11 | self.rs=pyb.Pin(rs,pyb.Pin.OUT_PP) 12 | self.e=pyb.Pin(e,pyb.Pin.OUT_PP) 13 | self.lcd_write(0x30,0) 14 | pyb.delay(50) 15 | self.lcd_write(0x06,0) 16 | pyb.delay(50) 17 | self.lcd_write(0x01,0) 18 | pyb.delay(50) 19 | self.lcd_write(0x0c,0) 20 | pyb.delay(50) 21 | self.lcd_write(0x02,0) 22 | pyb.delay(50) 23 | self.qp_12864() 24 | 25 | def qp_12864(self): 26 | self.lcd_write(0x3f,0) 27 | self.lcd_write(0xc0,0) 28 | pyb.delay(5) 29 | self.lcd_write(0x34,0) 30 | self.lcd_write(0x36,0) 31 | pyb.delay(5) 32 | 33 | for i in range(32): 34 | self.lcd_write(0x80+i,0) 35 | self.lcd_write(0x80,0) 36 | for j in range(32): 37 | self.lcd_write(0x0,1) 38 | self.lcd_write(0x30,0) 39 | self.lcd_write(0xc0,0) 40 | pyb.delay(5) 41 | 42 | def lcd_write(self,addr,ms): 43 | self.e.value(0) 44 | self.rs.value(ms) 45 | c="X1" 46 | d=list(c) 47 | for i in range(8): 48 | b=addr&1 49 | addr>>=1 50 | pyb.Pin(''.join(d),pyb.Pin.OUT_PP).value(b) 51 | d[1]=str(int(d[1])+1) 52 | pyb.delay(1) 53 | self.e.value(1) 54 | pyb.delay(1) 55 | self.e.value(0) 56 | 57 | def lcd_write_string(self,address,string,s_bit): 58 | self.lcd_write(address,0) 59 | a=(len(string)-(s_bit-1))*s_bit 60 | for j in range(a): 61 | self.lcd_write(bytearray(string)[j],1) -------------------------------------------------------------------------------- /03.LCD12864 --- LCD12864液晶屏/main.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TPYBoard/TPYBoard_lib/6071a30bcf438c44f834e99e5209c182a2fc287d/03.LCD12864 --- LCD12864液晶屏/main.py -------------------------------------------------------------------------------- /04.TFTLCD --- TFT液晶屏/44.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TPYBoard/TPYBoard_lib/6071a30bcf438c44f834e99e5209c182a2fc287d/04.TFTLCD --- TFT液晶屏/44.bmp -------------------------------------------------------------------------------- /04.TFTLCD --- TFT液晶屏/55.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TPYBoard/TPYBoard_lib/6071a30bcf438c44f834e99e5209c182a2fc287d/04.TFTLCD --- TFT液晶屏/55.bmp -------------------------------------------------------------------------------- /04.TFTLCD --- TFT液晶屏/font1.py: -------------------------------------------------------------------------------- 1 | class FONT: 2 | f16=[ 3 | # /*-- 文字: 液 --*/ 4 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 5 | 0x00,0x80,0x20,0x40,0x17,0xFE,0x11,0x20,0x81,0x20,0x42,0x3C,0x42,0x44,0x16,0x64, 6 | 0x12,0x94,0x23,0x48,0xE2,0x48,0x22,0x30,0x22,0x20,0x22,0x50,0x22,0x88,0x03,0x06, 7 | 8 | # /*-- 文字: 晶 --*/ 9 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 10 | 0x0F,0xE0,0x08,0x20,0x08,0x20,0x0F,0xE0,0x08,0x20,0x08,0x20,0x0F,0xE0,0x00,0x00, 11 | 0x7E,0xFC,0x42,0x84,0x42,0x84,0x7E,0xFC,0x42,0x84,0x42,0x84,0x7E,0xFC,0x42,0x84, 12 | 13 | # /*-- 文字: 屏 --*/ 14 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 15 | 0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x3F,0xF8,0x24,0x10,0x22,0x20,0x2F,0xF8, 16 | 0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x42,0x20,0x44,0x20,0x84,0x20,0x08,0x20, 17 | 18 | # /*-- 文字: 测 --*/ 19 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 20 | 0x00,0x04,0x27,0xC4,0x14,0x44,0x14,0x54,0x85,0x54,0x45,0x54,0x45,0x54,0x15,0x54, 21 | 0x15,0x54,0x25,0x54,0xE5,0x54,0x21,0x04,0x22,0x84,0x22,0x44,0x24,0x14,0x08,0x08, 22 | 23 | # /*-- 文字: 试 --*/ 24 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 25 | 0x00,0x28,0x20,0x24,0x10,0x24,0x10,0x20,0x07,0xFE,0x00,0x20,0xF0,0x20,0x17,0xE0, 26 | 0x11,0x20,0x11,0x10,0x11,0x10,0x15,0x10,0x19,0xCA,0x17,0x0A,0x02,0x06,0x00,0x02 27 | ] 28 | f12=[ 29 | # /*-- 文字: 文 --*/ 30 | # /*-- 宋体9; 此字体下对应的点阵为:宽x高=12x12 --*/ 31 | # /*-- 宽度不是8的倍数,现调整为:宽度x高度=16x12 --*/ 32 | 0x08,0x00,0x04,0x00,0xFF,0xE0,0x20,0x80,0x20,0x80,0x11,0x00,0x11,0x00,0x0A,0x00, 33 | 0x04,0x00,0x0A,0x00,0x31,0x80,0xC0,0x60, 34 | 35 | # /*-- 文字: 字 --*/ 36 | # /*-- 宋体9; 此字体下对应的点阵为:宽x高=12x12 --*/ 37 | # /*-- 宽度不是8的倍数,现调整为:宽度x高度=16x12 --*/ 38 | 0x08,0x00,0x04,0x00,0xFF,0xE0,0x80,0x20,0x00,0x00,0x3F,0x80,0x01,0x00,0x02,0x00, 39 | 0xFF,0xE0,0x04,0x00,0x04,0x00,0x1C,0x00, 40 | 41 | # /*-- 文字: 测 --*/ 42 | # /*-- 宋体9; 此字体下对应的点阵为:宽x高=12x12 --*/ 43 | # /*-- 宽度不是8的倍数,现调整为:宽度x高度=16x12 --*/ 44 | 0x00,0x20,0xBE,0x20,0x62,0xA0,0x2A,0xA0,0x2A,0xA0,0xAA,0xA0,0x6A,0xA0,0x2A,0xA0, 45 | 0x2A,0xA0,0x48,0x20,0x94,0x20,0x22,0x60, 46 | 47 | # /*-- 文字: 试 --*/ 48 | # /*-- 宋体9; 此字体下对应的点阵为:宽x高=12x12 --*/ 49 | # /*-- 宽度不是8的倍数,现调整为:宽度x高度=16x12 --*/ 50 | 0x80,0xA0,0x40,0x80,0x0F,0xE0,0x00,0x80,0xC0,0x80,0x4E,0x80,0x44,0x80,0x44,0x80, 51 | 0x44,0x80,0x46,0xA0,0x6C,0x60,0x40,0x20 52 | ] 53 | fnum=[ 54 | # /*-- 文字: 0 --*/ 55 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 56 | 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00, 57 | 58 | # /*-- 文字: 1 --*/ 59 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 60 | 0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00, 61 | 62 | # /*-- 文字: 2 --*/ 63 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 64 | 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00, 65 | 66 | # /*-- 文字: 3 --*/ 67 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 68 | 0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x04,0x02,0x42,0x42,0x3C,0x00,0x00, 69 | 70 | # /*-- 文字: 4 --*/ 71 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 72 | 0x00,0x00,0x00,0x04,0x0C,0x0C,0x14,0x24,0x24,0x44,0x7F,0x04,0x04,0x1F,0x00,0x00, 73 | 74 | # /*-- 文字: 5 --*/ 75 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 76 | 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x78,0x44,0x02,0x02,0x42,0x44,0x38,0x00,0x00, 77 | 78 | # /*-- 文字: 6 --*/ 79 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 80 | 0x00,0x00,0x00,0x18,0x24,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x22,0x1C,0x00,0x00, 81 | 82 | # /*-- 文字: 7 --*/ 83 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 84 | 0x00,0x00,0x00,0x7E,0x42,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x00,0x00, 85 | 86 | # /*-- 文字: 8 --*/ 87 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 88 | 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00, 89 | 90 | # /*-- 文字: 9 --*/ 91 | # /*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ 92 | 0x00,0x00,0x00,0x38,0x44,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x24,0x18,0x00,0x00 93 | ] 94 | class image: 95 | pictuer = [ 96 | 0x0E,0x07,0x00,0x03,0x03,0x60,0x01,0xC0,0x60,0x18,0x00,0xC0,0x7F,0xC1,0x98,0x03, 97 | 0x00,0x00,0x30,0x00,0x60,0x30,0x70,0x0C,0x06,0x00,0x00,0xC0,0x00,0x30,0x18,0x00, 98 | 0x04,0x08,0x00,0x00,0x80,0x00,0x18,0x60,0x00,0x03,0x18,0x00,0x00,0x00,0x00,0x0D, 99 | 0x80,0x00,0x01,0xB0,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x60,0x00,0x00,0x00, 100 | 0x00,0x0C,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x18,0x00, 101 | 0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00, 102 | 0x0E,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00, 103 | 0x00,0x00,0x07,0x80,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x00,0x02, 104 | 0x00,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x01,0xE0,0x00, 105 | 0x00,0x0C,0x00,0x00,0x00,0x00,0x01,0xE0,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00, 106 | 0xF0,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x10,0x00,0x00,0x00, 107 | 0x00,0x00,0xF0,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x30,0x00, 108 | 0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00, 109 | 0x20,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x7C, 110 | 0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x40,0x00,0x00,0x00,0x00, 111 | 0x00,0x7C,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x40,0x00,0x00, 112 | 0x00,0x00,0x00,0x3C,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x00,0x3E,0x00,0x00,0x40, 113 | 0x00,0x00,0x00,0x06,0x00,0x3E,0x00,0x00,0x47,0x00,0x0E,0x00,0x0C,0x00,0x3E,0x00, 114 | 0x00,0x43,0x80,0x3F,0xC0,0x18,0x00,0x3E,0x00,0x00,0x40,0xC0,0xFF,0xE0,0x30,0x00, 115 | 0x3E,0x00,0xFC,0x40,0x60,0x9F,0xF0,0x60,0x00,0x3E,0x20,0x66,0x40,0x31,0x9F,0xF8, 116 | 0xC0,0x00,0x3E,0x40,0x03,0xC0,0x11,0x3F,0xF8,0x80,0x00,0x3F,0xC0,0x00,0xC0,0xFB, 117 | 0x3F,0xFD,0xFF,0x80,0x3F,0x00,0x00,0x87,0xE3,0xFF,0xFD,0x00,0xC0,0x3F,0x00,0x00, 118 | 0x86,0x03,0xFF,0xFC,0x00,0x00,0x3F,0x00,0x01,0x80,0x03,0xFF,0xFC,0x00,0x00,0x3F, 119 | 0x00,0x00,0x80,0x07,0xFF,0xFC,0x00,0x00,0x3F,0x00,0x00,0xC0,0x07,0xFF,0xFE,0x00, 120 | 0x00,0x3E,0x00,0x00,0xC0,0x07,0xFF,0xFE,0x00,0x00,0x3E,0x00,0x00,0x40,0x07,0xFF, 121 | 0xFC,0x00,0x00,0x7E,0x00,0x00,0x60,0x03,0xFF,0xFC,0x00,0x00,0x7C,0x00,0x00,0x30, 122 | 0x03,0xFF,0xFC,0x00,0x00,0xF8,0x00,0x00,0x18,0x01,0xFF,0xF8,0x00,0x01,0xF8,0x00, 123 | 0x00,0x0C,0x00,0xFF,0xE0,0x00,0x03,0xE0,0x00,0x00,0x06,0x00,0x0F,0x00,0x00,0x07, 124 | 0xC0,0x60,0x00,0x03,0x00,0x7F,0xF0,0x00,0x0F,0x81,0xC0,0x00,0x01,0xC0,0x7F,0xF0, 125 | 0x00,0x1F,0x07,0x00,0x00,0x00,0x60,0x7F,0xF0,0x00,0x7C,0x0C,0x00,0x00,0x00,0x3C, 126 | 0x3F,0xF0,0x01,0xF8,0x18,0x00,0x0C,0x00,0x07,0xBE,0x20,0x07,0xFC,0x30,0x00,0x07, 127 | 0x00,0x01,0xF8,0x60,0x7F,0x3F,0xE0,0x00,0x01,0xC0,0x00,0x38,0xFF,0xF0,0x03,0xC0, 128 | 0x00,0x00,0x70,0x00,0x7F,0xFF,0xE0,0x00,0xC0,0x00,0x00,0x1C,0x00,0xDF,0xFF,0xC0, 129 | 0x00,0x40,0x00,0x00,0x07,0x01,0x97,0xFF,0x80,0x09,0xC0,0x00,0x00,0x01,0xC3,0x17, 130 | 0xFF,0x00,0x0F,0x80,0x00,0xFF,0x00,0x72,0x1B,0xFC,0x00,0x0F,0x00,0x20,0x07,0xFE, 131 | 0x1E,0x19,0xFC,0x00,0x0E,0x00,0x60,0x00,0x07,0xFF,0x38,0x78,0x00,0x0E,0x00,0x60, 132 | 0x00,0x00,0x07,0xF8,0x38,0x00,0x0F,0x00,0x60,0x00,0x00,0x00,0x48,0x10,0x00,0x0F, 133 | 0x00,0xE0,0x00,0x00,0x00,0x0C,0x00,0x00,0x1D,0x00,0xE0,0x00,0x00,0x00,0x04,0x00, 134 | 0x00,0x1D,0x80,0xE0,0x00,0x00,0x00,0x06,0x01,0x80,0x3C,0xE0,0x60,0x00,0x00,0x00, 135 | 0x02,0x1F,0x80,0x3C,0x7F,0xE0,0x00,0x00,0x00,0x02,0x70,0x00,0x7F,0x8F,0xE0,0x00, 136 | 0x00,0x00,0x01,0xC0,0x00,0xFF,0x80,0x20,0x00,0x00,0x00,0x01,0x80,0x01,0xFF,0x80, 137 | 0x00,0x00,0x00,0x00,0x03,0x00,0x03,0xFF,0x80,0x00,0x00,0x00,0x00,0x06,0x00,0x1F, 138 | 0xFF,0x00,0x00 139 | 140 | ] -------------------------------------------------------------------------------- /04.TFTLCD --- TFT液晶屏/main.py: -------------------------------------------------------------------------------- 1 | import tftlcd 2 | import font1 3 | import gc 4 | from pyb import SPI,Pin 5 | spi=SPI(2) 6 | tft=tftlcd.TFT(spi,cs='X11',rst='X9',rs='X10',color=2000) 7 | tft.clean(2000) 8 | # tft.point(10,20,100) 9 | # tft.line(2,3,20,40,255) 10 | # tft.fill(0,0,30,10,0) 11 | # tft.rectangle(20,20,60,60,0) 12 | # tft.round(50,50,10,50) 13 | 14 | indexes_chinese16="液晶屏测试" 15 | indexes_chinese12="文字测试" 16 | indexes_roman="0123456789" 17 | 18 | tft.init_str(font1.FONT().f16,indexes_chinese16) 19 | tft.write_str(75,10,16,16,"液晶屏",0) 20 | 21 | tft.init_str(font1.FONT().f12,indexes_chinese12) 22 | tft.write_str(86,30,16,12,"测试",255) 23 | 24 | tft.init_str(font1.FONT().fnum,indexes_roman) 25 | tft.write_str(86,50,8,16,"149",TFT.RED) 26 | 27 | tft.write_pictuer(5,40,72,75,font1.image().pictuer,TFT.BRED) 28 | 29 | gc.enable() 30 | gc.collect() 31 | # print(gc.mem_free()) 32 | # tft.write_img(60,0,font1.image().img) 33 | 34 | tft.displayfile("55.bmp", 0,0,67, 75) 35 | print('1') 36 | tft.displayfile("44.bmp", 65,0,67, 75) 37 | print('2') -------------------------------------------------------------------------------- /04.TFTLCD --- TFT液晶屏/tftlcd.py: -------------------------------------------------------------------------------- 1 | # MicroPython ST7735 TFT display HAL 2 | 3 | import time 4 | from pyb import SPI,Pin 5 | import os, gc 6 | from struct import unpack 7 | 8 | LCD_W=129 9 | LCD_H=163 10 | 11 | WHITE = 0xFFFF 12 | BLACK = 0x0000 13 | BLUE = 0x001F 14 | BRED = 0XF81F 15 | GRED = 0XFFE0 16 | GBLUE = 0X07FF 17 | RED = 0xF800 18 | MAGENTA = 0xF81F 19 | GREEN = 0x07E0 20 | CYAN = 0x7FFF 21 | YELLOW = 0xFFE0 22 | BROWN = 0XBC40 #//棕色 23 | BRRED = 0XFC07 #//棕红色 24 | GRAY = 0X8430 #//灰色 25 | 26 | class TFT: 27 | def __init__(self,spi,cs,rst,rs,color): 28 | spi.init(spi.MASTER,baudrate=1000000,polarity=0, phase=0,bits=8,firstbit=SPI.MSB) 29 | self.spi=spi 30 | self.color=color 31 | self.rst=Pin(rst,Pin.OUT_PP) 32 | self.cs=Pin(cs,Pin.OUT_PP) 33 | self.rs=Pin(rs,Pin.OUT_PP) 34 | self.Init() 35 | 36 | def Init(self): 37 | self.cs.value(1) 38 | self.rst.value(1) 39 | time.sleep_ms(5) 40 | self.rst.value(0) 41 | time.sleep_ms(5) 42 | self.rst.value(1) 43 | self.cs.value(1) 44 | time.sleep_ms(5) 45 | self.cs.value(0) 46 | self.writecmd(0x11) 47 | time.sleep_ms(120) 48 | 49 | self.writecmd(0xb1) 50 | self.writedata(0x05) 51 | self.writedata(0x3c) 52 | self.writedata(0x3c) 53 | self.writecmd(0xb2) 54 | self.writedata(0x05) 55 | self.writedata(0x3c) 56 | self.writedata(0x3c) 57 | self.writecmd(0xb3) 58 | self.writedata(0x05) 59 | self.writedata(0x3c) 60 | self.writedata(0x3c) 61 | self.writedata(0x05) 62 | self.writedata(0x3c) 63 | self.writedata(0x3c) 64 | 65 | self.writecmd(0xb4) 66 | self.writedata(0x03) 67 | self.writecmd(0xc0) 68 | self.writedata(0x28) 69 | self.writedata(0x08) 70 | self.writedata(0x04) 71 | self.writecmd(0xc1) 72 | self.writedata(0xc0) 73 | self.writecmd(0xc2) 74 | self.writedata(0x0d) 75 | self.writedata(0x00) 76 | self.writecmd(0xc3) 77 | self.writedata(0x8d) 78 | self.writedata(0x2a) 79 | self.writecmd(0xc4) 80 | self.writedata(0x8d) 81 | self.writedata(0xee) 82 | 83 | self.writecmd(0xc5) 84 | self.writedata(0x1a) 85 | self.writecmd(0x36) 86 | self.writedata(0xc0) 87 | 88 | self.writecmd(0xe0) 89 | self.writedata(0x04) 90 | self.writedata(0x22) 91 | self.writedata(0x07) 92 | self.writedata(0x0a) 93 | self.writedata(0x2e) 94 | self.writedata(0x30) 95 | self.writedata(0x25) 96 | self.writedata(0x2a) 97 | self.writedata(0x28) 98 | self.writedata(0x26) 99 | self.writedata(0x2e) 100 | self.writedata(0x3a) 101 | self.writedata(0x00) 102 | self.writedata(0x01) 103 | self.writedata(0x03) 104 | self.writedata(0x13) 105 | 106 | self.writecmd(0xe1) 107 | self.writedata(0x04) 108 | self.writedata(0x16) 109 | self.writedata(0x06) 110 | self.writedata(0x0d) 111 | self.writedata(0x2d) 112 | self.writedata(0x26) 113 | self.writedata(0x23) 114 | self.writedata(0x27) 115 | self.writedata(0x27) 116 | self.writedata(0x25) 117 | self.writedata(0x2d) 118 | self.writedata(0x3b) 119 | self.writedata(0x00) 120 | self.writedata(0x01) 121 | self.writedata(0x04) 122 | self.writedata(0x13) 123 | 124 | self.writecmd(0x3a) 125 | self.writedata(0x05) 126 | self.writecmd(0x29) 127 | 128 | def clean(self,color): 129 | VH=color>>8 130 | VL=color 131 | self.address_set(0,0,LCD_W,LCD_H) 132 | for i in range(LCD_W): 133 | for k in range(LCD_H): 134 | self.writedata(VH) 135 | self.writedata(VL) 136 | 137 | def writecmd(self,cmd): 138 | self.rs.value(0) 139 | self.spi.send(cmd) 140 | 141 | def writedata(self,data): 142 | self.rs.value(1) 143 | self.spi.send(data) 144 | 145 | def address_set(self,x,y,w,h): 146 | self.writecmd(0x2a) 147 | self.writedata(x>>8) 148 | self.writedata(x) 149 | self.writedata(w>>8) 150 | self.writedata(w) 151 | 152 | self.writecmd(0x2b) 153 | self.writedata(y>>8) 154 | self.writedata(y) 155 | self.writedata(h>>8) 156 | self.writedata(h) 157 | 158 | self.writecmd(0x2c) 159 | 160 | def writecolor(self,color): 161 | self.rs.value(1) 162 | self.spi.send(color>>8) 163 | self.spi.send(color) 164 | 165 | def point(self,x,y,color): 166 | self.address_set(x,y,x,y) 167 | self.writecolor(color) 168 | 169 | def line(self,xs,ys,xe,ye,color): 170 | x=xe-xs 171 | y=ye-ys 172 | sx=xs 173 | sy=ys 174 | xerr=0 175 | yerr=0 176 | if(x>0): 177 | incx=1 178 | elif x==0: 179 | incx=0 180 | else : 181 | incx=-1 182 | x=-x 183 | if(y>0): 184 | incy=1 185 | elif y==0: 186 | incy=0 187 | else : 188 | incy=-1 189 | y=-y 190 | if x>y: 191 | xy=x 192 | else : 193 | xy=y 194 | for i in range(xy+1): 195 | self.point(sx,sy,color) 196 | xerr+=x 197 | yerr+=y 198 | if (xerr>xy): 199 | xerr-=xy 200 | sx+=incx 201 | if (yerr>xy): 202 | yerr-=xy 203 | sy+=incy 204 | 205 | def fill(self,xs,ys,xe,ye,color): 206 | self.address_set(xs,ys,xe,ye) 207 | for i in range(xe-xs): 208 | for k in range(ye-ys): 209 | self.writecolor(color) 210 | 211 | def rectangle(self,x1,y1,x2,y2,color): 212 | self.line(x1,y1,x2,y1,color) 213 | self.line(x1,y1,x1,y2,color) 214 | self.line(x1,y2,x2,y2,color) 215 | self.line(x2,y1,x2,y2,color) 216 | 217 | def round(self,x0,y0,r,color): 218 | a=0 219 | b=r 220 | di=3-(r<<1) 221 | while (a<=b): 222 | self.point(x0-b,y0-a,color) 223 | self.point(x0+b,y0-a,color) 224 | self.point(x0-a,y0+b,color) 225 | self.point(x0-b,y0-a,color) 226 | self.point(x0-a,y0-b,color) 227 | self.point(x0+b,y0+a,color) 228 | self.point(x0+a,y0-b,color) 229 | self.point(x0+a,y0+b,color) 230 | self.point(x0-b,y0+a,color) 231 | a+=1 232 | if (di<0): 233 | di+=4*a+6 234 | else : 235 | di+=10+4*(a-b) 236 | b-=1 237 | self.point(x0+a,y0+b,color) 238 | 239 | def data8(self,data,color): 240 | for i in range(8): 241 | a=(data&0x80)>>7 242 | if (a): 243 | self.writecolor(color) 244 | else : 245 | self.writecolor(self.color) 246 | data<<=1 247 | 248 | def write(self,x,y,a,b,fist,color): 249 | self.address_set(x,y,a-1,b-1) 250 | for i in range(int((a-x)*(b-y)/8)): 251 | self.data8(self.font[i+fist],color) 252 | 253 | def write_str(self,x,y,wight,high,string,color): 254 | # wight=int((a-x)/len(string)) 255 | a=x+wight 256 | b=y+high 257 | for i in range(len(string)): 258 | fist=self.indexes.index(string[i])*int(wight*high/8) 259 | self.write(x,y,a,b,fist,color) 260 | x+=wight 261 | a+=wight 262 | 263 | def write_img(self,x,y,img): 264 | self.address_set(x,y,(x+(img[2]<<8)+img[3])-1,(y+(img[4]<<8)+img[5])-1) 265 | i=8 266 | while i<(2*((img[2]<<8)+img[3])*((img[4]<<8)+img[5])): 267 | self.writecolor((img[i]<<8)|(img[i+1])) 268 | i+=2 269 | 270 | def write_pictuer(self,x,y,wight,high,pictuer,color): 271 | self.address_set(x,y,x+wight-1,y+high-1) 272 | for i in range(len(pictuer)): 273 | self.data8(pictuer[i],color) 274 | 275 | 276 | def init_str(self,font,indexes): 277 | self.font=font 278 | self.indexes=indexes 279 | 280 | def displayfile(self, name, x,y,width, height): 281 | with open(name, "rb") as f: 282 | gc.collect() 283 | row = 0 284 | parts = name.split(".") # get extension 285 | if len(parts) > 1: 286 | mode = parts[-1].lower() 287 | if mode == "bmp": # Windows bmp file 288 | BM, filesize, res0, offset = unpack(" 0: 294 | self.fillRectangle(0, height - skip, width - 1, height - 1, (0, 0, 0)) 295 | else: 296 | skip = 0 297 | if colors in (1,4,8): # must have a color table 298 | if ct_size == 0: # if 0, size is 2**colors 299 | ct_size = 1 << colors 300 | colortable = bytearray(ct_size * 4) 301 | f.seek(hdrsize + 14) # go to colortable 302 | n = f.readinto(colortable) # read colortable 303 | if colors == 1: 304 | bsize = imgwidth // 8 305 | elif colors == 2: 306 | bsize = imgwidth // 4 307 | elif colors == 4: 308 | bsize = imgwidth // 2 309 | elif colors == 8: 310 | bsize = imgwidth 311 | bsize = (bsize + 3) & 0xfffc # must read a multiple of 4 bytes 312 | b = bytearray(bsize) 313 | f.seek(offset) 314 | for row in range(height - skip - 1, -1, -1): 315 | n = f.readinto(b) 316 | if n != bsize: 317 | break 318 | self.address_set(x,row+y,x+width-1,row+y) 319 | # print(0,row,width,row) 320 | for i in range(0,width-1,+1): 321 | self.rs.value(1) 322 | # self.spi.send(b[i+2]) 323 | self.spi.send(b[i+0]) 324 | self.spi.send(b[i+0]) 325 | else: 326 | f.seek(offset) 327 | if colors == 16: 328 | bsize = (imgwidth*2 + 3) & 0xfffc # must read a multiple of 4 bytes 329 | b = bytearray(bsize) 330 | for row in range(height, -1, -1): 331 | n = f.readinto(b) 332 | if n != bsize: 333 | break 334 | self.address_set(x,row+y,x+width-1,row+y) 335 | # print(0,row,width,row) 336 | for i in range(0,width*2-1,+2): 337 | self.rs.value(1) 338 | self.spi.send(b[i+2]) 339 | self.spi.send(b[i+1]) 340 | # self.spi.send(b[i+0]) 341 | 342 | elif colors == 24: 343 | bsize = (imgwidth*3 + 3) & 0xfffc # must read a multiple of 4 bytes 344 | b = bytearray(bsize) 345 | for row in range(height - skip - 1, -1, -1): 346 | n = f.readinto(b) 347 | if n != bsize: 348 | break 349 | self.drawBitmap(0, row, imgwidth, 1, b, colors) 350 | f.close() -------------------------------------------------------------------------------- /05.DS18X20 --- DS18X20温度传感器/ds18b20.py: -------------------------------------------------------------------------------- 1 | """ 2 | DS18x20 temperature sensor driver for MicroPython. 3 | 4 | This driver uses the OneWire driver to control DS18S20 and DS18B20 5 | temperature sensors. It supports multiple devices on the same 1-wire bus. 6 | 7 | The following example assumes the ground of your DS18x20 is connected to 8 | Y11, vcc is connected to Y9 and the data pin is connected to Y10. 9 | 10 | >>> from pyb import Pin 11 | >>> gnd = Pin('Y11', Pin.OUT_PP) 12 | >>> gnd.low() 13 | >>> vcc = Pin('Y9', Pin.OUT_PP) 14 | >>> vcc.high() 15 | 16 | >>> from ds18x20 import DS18X20 17 | >>> d = DS18X20(Pin('Y10')) 18 | 19 | Call read_temps to read all sensors: 20 | 21 | >>> result = d.read_temps() 22 | >>> print(result) 23 | [20.875, 20.8125] 24 | 25 | Call read_temp to read the temperature of a specific sensor: 26 | 27 | >>> result = d.read_temp(d.roms[0]) 28 | >>> print(result) 29 | 20.25 30 | 31 | If only one DS18x20 is attached to the bus, then you don't need to 32 | pass a ROM to read_temp: 33 | 34 | >>> result = d.read_temp() 35 | >>> print(result) 36 | 20.25 37 | 38 | """ 39 | 40 | from onewire_lib import OneWire 41 | 42 | class DS18X20(object): 43 | def __init__(self, pin): 44 | self.ow = OneWire(pin) 45 | # Scan the 1-wire devices, but only keep those which have the 46 | # correct # first byte in their rom for a DS18x20 device. 47 | self.roms = [rom for rom in self.ow.scan() if rom[0] == 0x10 or rom[0] == 0x28] 48 | 49 | def read_temp(self, rom=None): 50 | """ 51 | Read and return the temperature of one DS18x20 device. 52 | Pass the 8-byte bytes object with the ROM of the specific device you want to read. 53 | If only one DS18x20 device is attached to the bus you may omit the rom parameter. 54 | """ 55 | rom = rom or self.roms[0] 56 | ow = self.ow 57 | ow.reset() 58 | ow.select_rom(rom) 59 | ow.write_byte(0x44) # Convert Temp 60 | while True: 61 | if ow.read_bit(): 62 | break 63 | ow.reset() 64 | ow.select_rom(rom) 65 | ow.write_byte(0xbe) # Read scratch 66 | data = ow.read_bytes(9) 67 | return self.convert_temp(rom[0], data) 68 | 69 | def read_temps(self): 70 | """ 71 | Read and return the temperatures of all attached DS18x20 devices. 72 | """ 73 | temps = [] 74 | for rom in self.roms: 75 | temps.append(self.read_temp(rom)) 76 | return temps 77 | 78 | def convert_temp(self, rom0, data): 79 | """ 80 | Convert the raw temperature data into degrees celsius and return as a float. 81 | """ 82 | temp_lsb = data[0] 83 | temp_msb = data[1] 84 | if rom0 == 0x10: 85 | if temp_msb != 0: 86 | # convert negative number 87 | temp_read = temp_lsb >> 1 | 0x80 # truncate bit 0 by shifting, fill high bit with 1. 88 | temp_read = -((~temp_read + 1) & 0xff) # now convert from two's complement 89 | else: 90 | temp_read = temp_lsb >> 1 # truncate bit 0 by shifting 91 | count_remain = data[6] 92 | count_per_c = data[7] 93 | temp = temp_read - 0.25 + (count_per_c - count_remain) / count_per_c 94 | return temp 95 | elif rom0 == 0x28: 96 | return (temp_msb << 8 | temp_lsb) / 16 97 | else: 98 | assert False 99 | -------------------------------------------------------------------------------- /05.DS18X20 --- DS18X20温度传感器/main.py: -------------------------------------------------------------------------------- 1 | from pyb import Pin 2 | from ds18b20 import DS18X20 3 | 4 | wd = DS18X20(Pin('Y10')) #设置DS18B20 DO引脚为Y10 5 | 6 | while True: 7 | print('当前温度:',wd.read_temp()) 8 | pyb.delay(1000) -------------------------------------------------------------------------------- /05.DS18X20 --- DS18X20温度传感器/onewire_lib.py: -------------------------------------------------------------------------------- 1 | """ 2 | OneWire library ported to MicroPython by Jason Hildebrand. 3 | 4 | 5 | TODO: 6 | * implement and test parasite-power mode (as an init option) 7 | * port the crc checks 8 | 9 | The original upstream copyright and terms follow. 10 | ------------------------------------------------------------------------------ 11 | 12 | Copyright (c) 2007, Jim Studt (original old version - many contributors since) 13 | 14 | OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since 15 | January 2010. 16 | 17 | 26 Sept 2008 -- Robin James 18 | 19 | Jim Studt's original library was modified by Josh Larios. 20 | 21 | Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008 22 | 23 | Permission is hereby granted, free of charge, to any person obtaining 24 | a copy of this software and associated documentation files (the 25 | "Software"), to deal in the Software without restriction, including 26 | without limitation the rights to use, copy, modify, merge, publish, 27 | distribute, sublicense, and/or sell copies of the Software, and to 28 | permit persons to whom the Software is furnished to do so, subject to 29 | the following conditions: 30 | 31 | The above copyright notice and this permission notice shall be 32 | included in all copies or substantial portions of the Software. 33 | 34 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 35 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 36 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 37 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 38 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 39 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 40 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 41 | 42 | Much of the code was inspired by Derek Yerger's code, though I don't 43 | think much of that remains. In any event that was.. 44 | (copyleft) 2006 by Derek Yerger - Free to distribute freely. 45 | """ 46 | 47 | import pyb 48 | from pyb import disable_irq 49 | from pyb import enable_irq 50 | 51 | class OneWire: 52 | def __init__(self, pin): 53 | """ 54 | Pass the data pin connected to your one-wire device(s), for example Pin('X1'). 55 | The one-wire protocol allows for multiple devices to be attached. 56 | """ 57 | self.data_pin = pin 58 | self.write_delays = (1, 40, 40, 1) 59 | self.read_delays = (1, 1, 40) 60 | 61 | # cache a bunch of methods and attributes. This is necessary in _write_bit and 62 | # _read_bit to achieve the timing required by the OneWire protocol. 63 | self.cache = (pin.init, pin.value, pin.OUT_PP, pin.IN, pin.PULL_NONE) 64 | 65 | pin.init(pin.IN, pin.PULL_UP) 66 | 67 | def reset(self): 68 | """ 69 | Perform the onewire reset function. 70 | Returns 1 if a device asserted a presence pulse, 0 otherwise. 71 | 72 | If you receive 0, then check your wiring and make sure you are providing 73 | power and ground to your devices. 74 | """ 75 | retries = 25 76 | self.data_pin.init(self.data_pin.IN, self.data_pin.PULL_UP) 77 | 78 | # We will wait up to 250uS for 79 | # the bus to come high, if it doesn't then it is broken or shorted 80 | # and we return a 0; 81 | 82 | # wait until the wire is high... just in case 83 | while True: 84 | if self.data_pin.value(): 85 | break 86 | retries -= 1 87 | if retries == 0: 88 | raise OSError("OneWire pin didn't go high") 89 | pyb.udelay(10) 90 | 91 | # pull the bus low for at least 480us 92 | self.data_pin.low() 93 | self.data_pin.init(self.data_pin.OUT_PP) 94 | pyb.udelay(480) 95 | 96 | # If there is a slave present, it should pull the bus low within 60us 97 | i = pyb.disable_irq() 98 | self.data_pin.init(self.data_pin.IN, self.data_pin.PULL_UP) 99 | pyb.udelay(70) 100 | presence = not self.data_pin.value() 101 | pyb.enable_irq(i) 102 | pyb.udelay(410) 103 | return presence 104 | 105 | def write_bit(self, value): 106 | """ 107 | Write a single bit. 108 | """ 109 | pin_init, pin_value, Pin_OUT_PP, Pin_IN, Pin_PULL_UP = self.cache 110 | self._write_bit(value, pin_init, pin_value, Pin_OUT_PP) 111 | 112 | def _write_bit(self, value, pin_init, pin_value, Pin_OUT_PP): 113 | """ 114 | Write a single bit - requires cached methods/attributes be passed as arguments. 115 | See also write_bit() 116 | """ 117 | d0, d1, d2, d3 = self.write_delays 118 | udelay = pyb.udelay 119 | if value: 120 | # write 1 121 | i = disable_irq() 122 | pin_value(0) 123 | pin_init(Pin_OUT_PP) 124 | udelay(d0) 125 | pin_value(1) 126 | enable_irq(i) 127 | udelay(d1) 128 | else: 129 | # write 0 130 | i = disable_irq() 131 | pin_value(0) 132 | pin_init(Pin_OUT_PP) 133 | udelay(d2) 134 | pin_value(1) 135 | enable_irq(i) 136 | udelay(d3) 137 | 138 | def write_byte(self, value): 139 | """ 140 | Write a byte. The pin will go tri-state at the end of the write to avoid 141 | heating in a short or other mishap. 142 | """ 143 | pin_init, pin_value, Pin_OUT_PP, Pin_IN, Pin_PULL_UP = self.cache 144 | for i in range(8): 145 | self._write_bit(value & 1, pin_init, pin_value, Pin_OUT_PP) 146 | value >>= 1 147 | pin_init(Pin_IN, Pin_PULL_UP) 148 | 149 | def write_bytes(self, bytestring): 150 | """ 151 | Write a sequence of bytes. 152 | """ 153 | for byte in bytestring: 154 | self.write_byte(byte) 155 | 156 | def _read_bit(self, pin_init, pin_value, Pin_OUT_PP, Pin_IN, Pin_PULL_UP): 157 | """ 158 | Read a single bit - requires cached methods/attributes be passed as arguments. 159 | See also read_bit() 160 | """ 161 | d0, d1, d2 = self.read_delays 162 | udelay = pyb.udelay 163 | pin_init(Pin_IN, Pin_PULL_UP) # TODO why do we need this? 164 | i = disable_irq() 165 | pin_value(0) 166 | pin_init(Pin_OUT_PP) 167 | udelay(d0) 168 | pin_init(Pin_IN, Pin_PULL_UP) 169 | udelay(d1) 170 | value = pin_value() 171 | enable_irq(i) 172 | udelay(d2) 173 | return value 174 | 175 | def read_bit(self): 176 | """ 177 | Read a single bit. 178 | """ 179 | pin_init, pin_value, Pin_OUT_PP, Pin_IN, Pin_PULL_UP = self.cache 180 | return self._read_bit(pin_init, pin_value, Pin_OUT_PP, Pin_IN, Pin_PULL_UP) 181 | 182 | def read_byte(self): 183 | """ 184 | Read a single byte and return the value as an integer. 185 | See also read_bytes() 186 | """ 187 | pin_init, pin_value, Pin_OUT_PP, Pin_IN, Pin_PULL_UP = self.cache 188 | value = 0 189 | for i in range(8): 190 | bit = self._read_bit(pin_init, pin_value, Pin_OUT_PP, Pin_IN, Pin_PULL_UP) 191 | value |= bit << i 192 | return value 193 | 194 | def read_bytes(self, count): 195 | """ 196 | Read a sequence of N bytes. 197 | The bytes are returned as a bytearray. 198 | """ 199 | s = bytearray(count) 200 | for i in range(count): 201 | s[i] = self.read_byte() 202 | return s 203 | 204 | def select_rom(self, rom): 205 | """ 206 | Select a specific device to talk to. Pass in rom as a bytearray (8 bytes). 207 | """ 208 | assert len(rom) == 8, "ROM must be 8 bytes" 209 | self.reset() 210 | self.write_byte(0x55) # ROM MATCH 211 | self.write_bytes(rom) 212 | 213 | def read_rom(self): 214 | """ 215 | Read the ROM - this works if there is only a single device attached. 216 | """ 217 | self.reset() 218 | self.write_byte(0x33) # READ ROM 219 | rom = self.read_bytes(8) 220 | # TODO: check CRC of the ROM 221 | return rom 222 | 223 | def skip_rom(self): 224 | """ 225 | Send skip-rom command - this works if there is only one device attached. 226 | """ 227 | self.write_byte(0xCC) # SKIP ROM 228 | 229 | def depower(self): 230 | self.data_pin.init(self.data_pin.IN, self.data_pin.PULL_NONE) 231 | 232 | def scan(self): 233 | """ 234 | Return a list of ROMs for all attached devices. 235 | Each ROM is returned as a bytes object of 8 bytes. 236 | """ 237 | devices = [] 238 | self._reset_search() 239 | while True: 240 | rom = self._search() 241 | if not rom: 242 | return devices 243 | devices.append(rom) 244 | 245 | def _reset_search(self): 246 | self.last_discrepancy = 0 247 | self.last_device_flag = False 248 | self.last_family_discrepancy = 0 249 | self.rom = bytearray(8) 250 | 251 | def _search(self): 252 | # initialize for search 253 | id_bit_number = 1 254 | last_zero = 0 255 | rom_byte_number = 0 256 | rom_byte_mask = 1 257 | search_result = 0 258 | pin_init, pin_value, Pin_OUT_PP, Pin_IN, Pin_PULL_UP = self.cache 259 | 260 | # if the last call was not the last one 261 | if not self.last_device_flag: 262 | # 1-Wire reset 263 | if not self.reset(): 264 | self._reset_search() 265 | return None 266 | 267 | # issue the search command 268 | self.write_byte(0xF0) 269 | 270 | # loop to do the search 271 | while rom_byte_number < 8: # loop until through all ROM bytes 0-7 272 | # read a bit and its complement 273 | id_bit = self._read_bit(pin_init, pin_value, Pin_OUT_PP, Pin_IN, Pin_PULL_UP) 274 | cmp_id_bit = self._read_bit(pin_init, pin_value, Pin_OUT_PP, Pin_IN, Pin_PULL_UP) 275 | 276 | # check for no devices on 1-wire 277 | if (id_bit == 1) and (cmp_id_bit == 1): 278 | break 279 | else: 280 | # all devices coupled have 0 or 1 281 | if (id_bit != cmp_id_bit): 282 | search_direction = id_bit # bit write value for search 283 | else: 284 | # if this discrepancy if before the Last Discrepancy 285 | # on a previous next then pick the same as last time 286 | if (id_bit_number < self.last_discrepancy): 287 | search_direction = (self.rom[rom_byte_number] & rom_byte_mask) > 0 288 | else: 289 | # if equal to last pick 1, if not then pick 0 290 | search_direction = (id_bit_number == self.last_discrepancy) 291 | 292 | # if 0 was picked then record its position in LastZero 293 | if search_direction == 0: 294 | last_zero = id_bit_number 295 | 296 | # check for Last discrepancy in family 297 | if last_zero < 9: 298 | self.last_family_discrepancy = last_zero 299 | 300 | # set or clear the bit in the ROM byte rom_byte_number 301 | # with mask rom_byte_mask 302 | if search_direction == 1: 303 | self.rom[rom_byte_number] |= rom_byte_mask 304 | else: 305 | self.rom[rom_byte_number] &= ~rom_byte_mask 306 | 307 | # serial number search direction write bit 308 | #print('sd', search_direction) 309 | self.write_bit(search_direction) 310 | 311 | # increment the byte counter id_bit_number 312 | # and shift the mask rom_byte_mask 313 | id_bit_number += 1 314 | rom_byte_mask <<= 1 315 | 316 | # if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask 317 | if rom_byte_mask == 0x100: 318 | rom_byte_number += 1 319 | rom_byte_mask = 1 320 | 321 | # if the search was successful then 322 | if not (id_bit_number < 65): 323 | # search successful so set last_discrepancy,last_device_flag,search_result 324 | self.last_discrepancy = last_zero 325 | 326 | # check for last device 327 | if self.last_discrepancy == 0: 328 | self.last_device_flag = True 329 | search_result = True 330 | 331 | # if no device found then reset counters so next 'search' will be like a first 332 | if not search_result or not self.rom[0]: 333 | self._reset_search() 334 | return None 335 | else: 336 | return bytes(self.rom) 337 | -------------------------------------------------------------------------------- /06.AM2320 --- 高精度温湿度传感器/am2320.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython Aosong AM2320 I2C driver 3 | """ 4 | 5 | import ustruct 6 | import time 7 | from pyb import Pin, I2C 8 | import pyb 9 | class AM2320: 10 | def __init__(self, id=1, address=0x5c): 11 | self.i2c = pyb.I2C(id) 12 | self.i2c.init(pyb.I2C.MASTER, baudrate=400000) 13 | self.address = address 14 | self.buf = bytearray(8) 15 | 16 | def measure(self): 17 | buf = self.buf 18 | address = self.address 19 | self.i2c.scan() 20 | if(self.i2c.is_ready(self.address)!=True): 21 | print('not found AM2320') 22 | try: 23 | self.i2c.send(b'',address) 24 | except AttributeError: 25 | pass 26 | self.i2c.send(b'\x03\x00\x04',address) 27 | time.sleep_ms(2) 28 | self.i2c.recv(buf, address, timeout=5000) 29 | crc = ustruct.unpack('>= 1 40 | crc ^= 0xA001 41 | else: 42 | crc >>= 1 43 | return crc 44 | 45 | def humidity(self): 46 | return (self.buf[2] << 8 | self.buf[3]) * 0.1 47 | 48 | def temperature(self): 49 | t = ((self.buf[4] & 0x7f) << 8 | self.buf[5]) * 0.1 50 | if self.buf[4] & 0x80: 51 | t = -t 52 | return t -------------------------------------------------------------------------------- /06.AM2320 --- 高精度温湿度传感器/main.py: -------------------------------------------------------------------------------- 1 | import time 2 | from am2320 import AM2320 3 | am_2320 = AM2320.AM2320(1) 4 | 5 | while True: 6 | am_2320.measure() 7 | print('温度:',am_2320.temperature()) 8 | print('湿度:',am_2320.humidity()) 9 | time.sleep_ms(500) -------------------------------------------------------------------------------- /07.GY-30 --- 光照强度传感器/gy30.py: -------------------------------------------------------------------------------- 1 | import pyb 2 | from pyb import Pin, I2C 3 | 4 | class GY30: 5 | def __init__(self,id): 6 | self.accel_addr = 35 7 | self.i2c = pyb.I2C(id) 8 | self.i2c.init(pyb.I2C.MASTER, baudrate=400000) 9 | print(self.i2c.scan()) 10 | 11 | def start(self): 12 | self.i2c.scan() 13 | self.i2c.is_ready(self.accel_addr) 14 | self.i2c.send(1,35) 15 | self.i2c.send(0x10,35) 16 | 17 | def read(self): 18 | self.i2c.scan() 19 | self.i2c.is_ready(self.accel_addr) 20 | self.data=self.i2c.mem_read(2, self.accel_addr, 0x47, timeout=1000,addr_size=8) 21 | return self.data -------------------------------------------------------------------------------- /07.GY-30 --- 光照强度传感器/main.py: -------------------------------------------------------------------------------- 1 | import pyb 2 | from pyb import Pin, I2C 3 | from gy30 import GY30 4 | 5 | gy30=GY30(1) 6 | gy30.start() 7 | while True: 8 | a=gy30.read() 9 | print(a[0]*0xff+a[1]) -------------------------------------------------------------------------------- /08.GY39 --- 气象监测模块/GY39_V1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TPYBoard/TPYBoard_lib/6071a30bcf438c44f834e99e5209c182a2fc287d/08.GY39 --- 气象监测模块/GY39_V1.exe -------------------------------------------------------------------------------- /08.GY39 --- 气象监测模块/gy39.py: -------------------------------------------------------------------------------- 1 | from pyb import UART 2 | import time 3 | 4 | class GY39: 5 | def __init__(self,uart): 6 | self.uart = UART(uart, 9600) 7 | 8 | def read(self): 9 | self.uart.read() 10 | time.sleep_ms(10) 11 | hc=self.uart.read() 12 | # hex_array = [] 13 | # for i in list(hc): 14 | # hex_array.append('%02X'%i) 15 | # print(hex_array,hex_array[0]) 16 | 17 | l=(hc[4]<<24)|(hc[5]<<16)|(hc[6]<<8)|hc[9] 18 | t=((hc[13]<<8)|hc[14])/100 19 | p=((hc[15]<<24)|(hc[16]<<16)|(hc[17]<<8)|hc[18])/100 20 | h=((hc[19]<<8)|hc[20])/100 21 | H=((hc[21]<<8)|hc[22]) 22 | return l,t,p,h,H -------------------------------------------------------------------------------- /08.GY39 --- 气象监测模块/gy39_i2c.py: -------------------------------------------------------------------------------- 1 | import pyb 2 | from pyb import I2C 3 | 4 | class GY39I2C: 5 | def __init__(self,i2c): 6 | self.i2c = pyb.I2C(i2c) 7 | self.i2c.init(pyb.I2C.MASTER, addr=43,baudrate=40000,gencall = True,dma = False) 8 | self.addr=self.i2c.scan()[0] 9 | 10 | def read(self): 11 | self.i2c.is_ready(self.addr) 12 | i=0 13 | while 1: 14 | try: 15 | hc=self.i2c.mem_read(14,i,0,timeout=500,addr_size=8) 16 | l=(hc[0]<<24)|(hc[1]<<16)|(hc[2]<<8)|hc[3] 17 | t=((hc[4]<<8)|hc[5])/100 18 | p=((hc[6]<<24)|(hc[7]<<16)|(hc[8]<<8)|hc[9])/100 19 | h=((hc[10]<<8)|hc[11])/100 20 | H=((hc[12]<<8)|hc[13]) 21 | return l,t,p,h,H 22 | except OSError: 23 | i+=1 -------------------------------------------------------------------------------- /08.GY39 --- 气象监测模块/main.py: -------------------------------------------------------------------------------- 1 | import GY39 2 | import time 3 | gy39=GY39.GY39(1) 4 | 5 | while True: 6 | l,t,p,h,H=gy39.read() 7 | print('光照强度:%s lux'%l) 8 | print('当前温度:%s ℃'%t) 9 | print('当前湿度:%s %'%h) 10 | print('当前气压:%s pa'%p) 11 | print('海拔高度:%s m'%H) 12 | print('') 13 | time.sleep_ms(200) -------------------------------------------------------------------------------- /09.GY68_BMP180 -- 大气压传感器/bmp180.py: -------------------------------------------------------------------------------- 1 | import pyb 2 | import time 3 | from pyb import I2C 4 | 5 | BMP180_I2C_ADDR = 119 6 | class BMP180(): 7 | def __init__(self, i2c_num): 8 | self.i2c = I2C(i2c_num, I2C.MASTER, baudrate = 100000) 9 | self.i2c.scan() 10 | self.i2c.is_ready(BMP180_I2C_ADDR) 11 | self.AC1 = self.short(self.getReg(0xAA)) 12 | self.AC2 = self.short(self.getReg(0xAC)) 13 | self.AC3 = self.short(self.getReg(0xAE)) 14 | self.AC4 = self.getReg(0xB0) 15 | self.AC5 = self.getReg(0xB2) 16 | self.AC6 = self.getReg(0xB4) 17 | self.B1 = self.short(self.getReg(0xB6)) 18 | self.B2 = self.short(self.getReg(0xB8)) 19 | self.MB = self.short(self.getReg(0xBA)) 20 | self.MC = self.short(self.getReg(0xBC)) 21 | self.MD = self.short(self.getReg(0xBE)) 22 | self.UT = 0 23 | self.UP = 0 24 | self.B3 = 0 25 | self.B4 = 0 26 | self.B5 = 0 27 | self.B6 = 0 28 | self.B7 = 0 29 | self.X1 = 0 30 | self.X2 = 0 31 | self.X3 = 0 32 | 33 | def readpress(self): 34 | self.i2c.is_ready(BMP180_I2C_ADDR) 35 | self.setReg(0x34,0xf4) 36 | time.sleep_ms(5) 37 | 38 | self.i2c.send(bytearray(0xf6), BMP180_I2C_ADDR) 39 | up=list(self.i2c.mem_read(2, BMP180_I2C_ADDR, 0xf6, timeout=1000,addr_size=8)) 40 | up=up[0]<<8|up[1] 41 | 42 | b6 = self.b5 - 4000 43 | x1 = (self.B2*((b6*b6)/(1<<12)))/(1<<11) 44 | x2 = (self.AC2*b6)/(1<<11) 45 | x3 = (x1+x2) 46 | b3 = ((self.AC1*4+x3)+2)/4 47 | x1 = (self.AC3*b6)/(1<<13) 48 | x2 = (self.B1*((b6*b6)/(1<<12)))/(1<<16) 49 | x3 = (x1+x2+2)/(1<<2) 50 | b4 = (self.AC4*(x3+32768))/(1<<15) 51 | b7 = (up-b3)*50000 52 | if b7 < 0x80000000: 53 | p = (b7*2)/b4 54 | else: 55 | p = (b7/b4)*2 56 | x1 = (p/(1<<8))*(p/(1<<8)) 57 | x1 = (x1*3038)/(1<<16) 58 | x2 = (-7357*p)/(1<<16) 59 | self.p = p + ((x1 + x2 + 3791)/(1<<4)) 60 | 61 | return self.p 62 | 63 | def readtemp(self): 64 | self.i2c.is_ready(BMP180_I2C_ADDR) 65 | self.setReg(0x2e,0xf4) 66 | time.sleep_ms(5) 67 | 68 | ut=list(self.i2c.mem_read(2, BMP180_I2C_ADDR, 0xf6, timeout=1000,addr_size=8)) 69 | ut=ut[0]<<8|ut[1] 70 | x1=(ut-self.AC6)*self.AC5>>15 71 | x2=(self.MC<<11)/(x1+self.MD) 72 | self.b5=x1+x2 73 | return round((self.b5+8)/10/16,2) 74 | 75 | def readaltitude(self): 76 | return round((44330.0*(1.0-pow((float)(self.p)/101325.0,1.0/5.255))),2) 77 | 78 | def short(self, dat): 79 | if dat > 32767: 80 | return dat - 65536 81 | else: 82 | return dat 83 | 84 | def setReg(self, dat, reg): 85 | buf = bytearray(2) 86 | buf[0] = reg 87 | buf[1] = dat 88 | self.i2c.send(buf, BMP180_I2C_ADDR) 89 | 90 | def getReg(self, reg): 91 | t=list(self.i2c.mem_read(2, BMP180_I2C_ADDR, reg, timeout=1000,addr_size=8)) 92 | t=t[0]<<8|t[1] 93 | return t -------------------------------------------------------------------------------- /09.GY68_BMP180 -- 大气压传感器/main.py: -------------------------------------------------------------------------------- 1 | from bmp180 import BMP180 2 | import time 3 | bmp=BMP180.BMP180(2) 4 | 5 | while True: 6 | print('当前温度:%s ℃'%bmp.readtemp()) 7 | print('当前气压:%s pa'%bmp.readpress()) 8 | print('当前海拔:%s m'%bmp.readaltitude()) 9 | time.sleep_ms(500) -------------------------------------------------------------------------------- /10.DS3231 --- 时钟模块/ds3231.py: -------------------------------------------------------------------------------- 1 | import pyb 2 | from pyb import I2C 3 | DS3231_ADDR = const(0x68) 4 | DS3231_REG_SEC = const(0x00) 5 | DS3231_REG_MIN = const(0x01) 6 | DS3231_REG_HOUR = const(0x02) 7 | DS3231_REG_WEEKDAY= const(0x03) 8 | DS3231_REG_DAY = const(0x04) 9 | DS3231_REG_MONTH = const(0x05) 10 | DS3231_REG_YEAR = const(0x06) 11 | DS3231_REG_A1SEC = const(0x07) 12 | DS3231_REG_A1MIN = const(0x08) 13 | DS3231_REG_A1HOUR = const(0x09) 14 | DS3231_REG_A1DAY = const(0x0A) 15 | DS3231_REG_A2MIN = const(0x0B) 16 | DS3231_REG_A2HOUR = const(0x0C) 17 | DS3231_REG_A2DAY = const(0x0D) 18 | DS3231_REG_CTRL = const(0x0E) 19 | DS3231_REG_STA = const(0x0F) 20 | DS3231_REG_OFF = const(0x10) 21 | DS3231_REG_TEMP = const(0x11) 22 | 23 | class DS3231(object): 24 | def __init__(self, i2c_num): 25 | self.i2c = I2C(i2c_num, I2C.MASTER, baudrate = 100000) 26 | 27 | def DATE(self, dat=[]): 28 | if dat==[]: 29 | t = [] 30 | t.append(self.year()) 31 | t.append(self.month()) 32 | t.append(self.day()) 33 | return t 34 | else: 35 | self.year(dat[0]) 36 | self.month(dat[1]) 37 | self.day(dat[2]) 38 | 39 | def TIME(self, dat=[]): 40 | if dat==[]: 41 | t = [] 42 | t.append(self.hour()) 43 | t.append(self.min()) 44 | t.append(self.sec()) 45 | # t = "" 46 | # t+=self.hour()+":" 47 | # t+=self.min()+":" 48 | # t+=self.sec() 49 | return t 50 | else: 51 | self.hour(dat[0]) 52 | self.min(dat[1]) 53 | self.sec(dat[2]) 54 | 55 | def DateTime(self, dat=[]): 56 | if dat==[]: 57 | return self.DATE() + self.TIME() 58 | else: 59 | self.year(dat[0]) 60 | self.month(dat[1]) 61 | self.day(dat[2]) 62 | self.hour(dat[3]) 63 | self.min(dat[4]) 64 | self.sec(dat[5]) 65 | 66 | def dec2hex(self, dat): 67 | return (int(dat/10)<<4) + (dat%10) 68 | 69 | def setREG(self, dat, reg): 70 | buf = bytearray(2) 71 | buf[0] = reg 72 | buf[1] = dat 73 | self.i2c.send(buf, DS3231_ADDR) 74 | 75 | def getREG_DEC(self, reg): 76 | self.i2c.send(reg, DS3231_ADDR) 77 | t = self.i2c.recv(1, DS3231_ADDR)[0] 78 | return (t>>4)*10 + (t%16) 79 | 80 | def sec(self, sec=''): 81 | if sec == '': 82 | return self.getREG_DEC(DS3231_REG_SEC) 83 | else: 84 | self.setREG(self.dec2hex(sec), DS3231_REG_SEC) 85 | 86 | def min(self, min=''): 87 | if min == '': 88 | return self.getREG_DEC(DS3231_REG_MIN) 89 | else: 90 | self.setREG(self.dec2hex(min), DS3231_REG_MIN) 91 | 92 | def hour(self, hour=''): 93 | if hour=='': 94 | return self.getREG_DEC(DS3231_REG_HOUR) 95 | else: 96 | self.setREG(self.dec2hex(hour), DS3231_REG_HOUR) 97 | 98 | def day(self, day=''): 99 | if day=='': 100 | return self.getREG_DEC(DS3231_REG_DAY) 101 | else: 102 | self.setREG(self.dec2hex(day), DS3231_REG_DAY) 103 | 104 | def month(self, month=''): 105 | if month=='': 106 | return self.getREG_DEC(DS3231_REG_MONTH) 107 | else: 108 | self.setREG(self.dec2hex(month), DS3231_REG_MONTH) 109 | 110 | def year(self, year=''): 111 | if year=='': 112 | return self.getREG_DEC(DS3231_REG_YEAR) 113 | else: 114 | self.setREG(self.dec2hex(year), DS3231_REG_YEAR) 115 | 116 | def TEMP(self): 117 | self.i2c.send(DS3231_REG_TEMP, DS3231_ADDR) 118 | t1 = self.i2c.recv(1, DS3231_ADDR)[0] 119 | self.i2c.send(DS3231_REG_TEMP+1, DS3231_ADDR) 120 | t2 = self.i2c.recv(1, DS3231_ADDR)[0] 121 | if t1>0x7F: 122 | return t1 - t2/256 -256 123 | else: 124 | return t1 + t2/256 125 | 126 | 127 | -------------------------------------------------------------------------------- /10.DS3231 --- 时钟模块/main.py: -------------------------------------------------------------------------------- 1 | import machine 2 | import time 3 | from ds3231 import DS3231 4 | 5 | ds=DS3231() 6 | ds.DATE([17,9,1]) 7 | ds.TIME([10,10,10]) 8 | 9 | while True: 10 | print('Date:',ds.DATE()) 11 | print('Time:',ds.TIME()) 12 | print('TEMP:',ds.TEMP()) 13 | time.sleep(5) -------------------------------------------------------------------------------- /11.VS1838B --- 红外接收模块/bm.py: -------------------------------------------------------------------------------- 1 | nec_bm=0 2 | def nec_cb(nec, a, c, r): 3 | global nec_bm 4 | print(a, c, r) # Address, Command, Repeat 5 | nec_bm=c 6 | 7 | def necbm(): 8 | global nec_bm 9 | if nec_bm==69: 10 | nec_bm=0xa0 11 | elif nec_bm==70: 12 | nec_bm=0xa1 13 | elif nec_bm==71: 14 | nec_bm=0xa2 15 | elif nec_bm==68: 16 | nec_bm=0xa3 17 | elif nec_bm==64: 18 | nec_bm=0xa4 19 | elif nec_bm==67: 20 | nec_bm=0xa5 21 | elif nec_bm==7: 22 | nec_bm=0xa6 23 | elif nec_bm==21: 24 | nec_bm=0xa7 25 | elif nec_bm==9: 26 | nec_bm=0xa8 27 | elif nec_bm==22: 28 | nec_bm=0xa9 29 | elif nec_bm==25: 30 | nec_bm=0xaa 31 | elif nec_bm==13: 32 | nec_bm=0xab 33 | elif nec_bm==12: 34 | nec_bm=0xac 35 | elif nec_bm==24: 36 | nec_bm=0xad 37 | elif nec_bm==94: 38 | nec_bm=0xae 39 | elif nec_bm==8: 40 | nec_bm=0xaf 41 | elif nec_bm==28: 42 | nec_bm=0xb0 43 | elif nec_bm==90: 44 | nec_bm=0xb1 45 | elif nec_bm==66: 46 | nec_bm=0xb2 47 | elif nec_bm==82: 48 | nec_bm=0xb3 49 | elif nec_bm==74: 50 | nec_bm=0xb4 51 | return nec_bm -------------------------------------------------------------------------------- /11.VS1838B --- 红外接收模块/main.py: -------------------------------------------------------------------------------- 1 | from necir import NecIr 2 | from bm import necbm 3 | from bm import nec_cb 4 | 5 | def main(): 6 | nec = NecIr() 7 | while True: 8 | nec.callback(nec_cb) 9 | if necbm(): 10 | print("bm=",necbm()) 11 | 12 | 13 | main() -------------------------------------------------------------------------------- /11.VS1838B --- 红外接收模块/necir.py: -------------------------------------------------------------------------------- 1 | # NEC Infrared capture module for MicroPython board 2 | # 3 | # Connect TL1838 receiver to X4 4 | # (That's a 38kHz IR receiver, as shipped on eBay) 5 | # 6 | # See http://www.sbprojects.com/knowledge/ir/nec.php 7 | # 8 | # 2015-04-27 Initial draft 9 | # Matt Page / mattmatic@hotmail.com 10 | 11 | 12 | # Usage: 13 | # def nec_cb(nec, a, c, r) 14 | # print(a, c, r) # Address, Command, Repeat 15 | # 16 | # from necir import NecIr 17 | # nec = NecIr() 18 | # nec.callback(nec_cb) 19 | 20 | import pyb 21 | 22 | class NecIr: 23 | def __init__(self, timer=2, channel=4, pin=pyb.Pin.board.X4): 24 | self._t = pyb.Timer(timer, prescaler=83, period=0x0fffffff) 25 | self._ic_pin = pin 26 | self._ic = self._t.channel(channel, pyb.Timer.IC, pin=self._ic_pin, polarity=pyb.Timer.BOTH) 27 | self._ic_start = 0 28 | self._ic_width = 0 29 | self._ic.callback(self._ic_cb) 30 | self._sr = [0,0,0,0] 31 | self._rst() 32 | self._address = 0 33 | self._command = 0 34 | self._cb = None 35 | 36 | def _rst(self): 37 | self._sr[0] = 0 38 | self._sr[1] = 0 39 | self._sr[2] = 0 40 | self._sr[3] = 0 41 | self._sc = 0 42 | self._sb = 0 43 | 44 | def _bit(self, v): 45 | self._sr[self._sb] = (self._sr[self._sb] >> 1) + v 46 | self._sc = self._sc + 1 47 | if (self._sc > 7): 48 | self._sc = 0 49 | self._sb = self._sb + 1 50 | if (self._sb > 3): 51 | if ((self._sr[0] ^ self._sr[1] ^ self._sr[2] ^ self._sr[3])==0): 52 | self._address = self._sr[0] 53 | self._command = self._sr[2] 54 | if (self._cb): 55 | self._cb(self, self._address, self._command, False) # Contains the address & command 56 | self._rst() 57 | 58 | def _ic_cb(self, timer): 59 | if self._ic_pin.value(): 60 | # Rising edge 61 | self._ic_start = self._ic.capture() 62 | else: 63 | # Falling edge 64 | icw = self._ic.capture() - self._ic_start & 0x0fffffff 65 | self._ic_width = icw 66 | if (icw > 5000): 67 | # print('[gap]') # gap in transmission 68 | pass 69 | elif (icw > 4000): 70 | #print('IR start') 71 | self._rst() 72 | elif (icw > 2000): # Repeat command 73 | #print('IR repeat') 74 | if (self._cb): 75 | self._cb(self, self._address, self._command, True) 76 | elif (icw > 1500): 77 | self._bit(0x80) # High bit 78 | else: 79 | self._bit(0x00) # Low bit 80 | 81 | # print(self._ic_start, self._ic_width) 82 | 83 | def callback(self, fn): 84 | self._cb = fn -------------------------------------------------------------------------------- /12.NRF24L01 --- 2.4G无线收发模块/main.py: -------------------------------------------------------------------------------- 1 | import nrf24l01use 2 | 3 | nrf=nrf24l01use.NRF24L01(spi=2,csn='Y5',ce='Y4') 4 | 5 | while True: 6 | print(nrf.slave()) 7 | 8 | # import nrf24l01use 9 | 10 | # nrf=nrf24l01use.NRF24L01(spi=2,csn='Y5',ce='Y4') 11 | # i=0 12 | # while True: 13 | # nrf.master(i) 14 | # i+=1 -------------------------------------------------------------------------------- /12.NRF24L01 --- 2.4G无线收发模块/nrf24l01.py: -------------------------------------------------------------------------------- 1 | """NRF24L01 driver for MicroPython 2 | """ 3 | 4 | from micropython import const 5 | import utime 6 | 7 | # nRF24L01+ registers 8 | CONFIG = const(0x00) 9 | EN_RXADDR = const(0x02) 10 | SETUP_AW = const(0x03) 11 | SETUP_RETR = const(0x04) 12 | RF_CH = const(0x05) 13 | RF_SETUP = const(0x06) 14 | STATUS = const(0x07) 15 | RX_ADDR_P0 = const(0x0a) 16 | TX_ADDR = const(0x10) 17 | RX_PW_P0 = const(0x11) 18 | FIFO_STATUS = const(0x17) 19 | DYNPD = const(0x1c) 20 | 21 | # CONFIG register 22 | EN_CRC = const(0x08) # enable CRC 23 | CRCO = const(0x04) # CRC encoding scheme; 0=1 byte, 1=2 bytes 24 | PWR_UP = const(0x02) # 1=power up, 0=power down 25 | PRIM_RX = const(0x01) # RX/TX control; 0=PTX, 1=PRX 26 | 27 | # RF_SETUP register 28 | POWER_0 = const(0x00) # -18 dBm 29 | POWER_1 = const(0x02) # -12 dBm 30 | POWER_2 = const(0x04) # -6 dBm 31 | POWER_3 = const(0x06) # 0 dBm 32 | SPEED_1M = const(0x00) 33 | SPEED_2M = const(0x08) 34 | SPEED_250K = const(0x20) 35 | 36 | # STATUS register 37 | RX_DR = const(0x40) # RX data ready; write 1 to clear 38 | TX_DS = const(0x20) # TX data sent; write 1 to clear 39 | MAX_RT = const(0x10) # max retransmits reached; write 1 to clear 40 | 41 | # FIFO_STATUS register 42 | RX_EMPTY = const(0x01) # 1 if RX FIFO is empty 43 | 44 | # constants for instructions 45 | R_RX_PL_WID = const(0x60) # read RX payload width 46 | R_RX_PAYLOAD = const(0x61) # read RX payload 47 | W_TX_PAYLOAD = const(0xa0) # write TX payload 48 | FLUSH_TX = const(0xe1) # flush TX FIFO 49 | FLUSH_RX = const(0xe2) # flush RX FIFO 50 | NOP = const(0xff) # use to read STATUS register 51 | 52 | class NRF24L01: 53 | def __init__(self, spi, cs, ce, channel=46, payload_size=16): 54 | assert payload_size <= 32 55 | 56 | self.buf = bytearray(1) 57 | 58 | # store the pins 59 | self.spi = spi 60 | self.cs = cs 61 | self.ce = ce 62 | 63 | # init the SPI bus and pins 64 | self.init_spi(4000000) 65 | 66 | # reset everything 67 | ce.init(ce.OUT, value=0) 68 | cs.init(cs.OUT, value=1) 69 | 70 | self.payload_size = payload_size 71 | self.pipe0_read_addr = None 72 | utime.sleep_ms(5) 73 | 74 | # set address width to 5 bytes and check for device present 75 | self.reg_write(SETUP_AW, 0b11) 76 | if self.reg_read(SETUP_AW) != 0b11: 77 | raise OSError("nRF24L01+ Hardware not responding") 78 | 79 | # disable dynamic payloads 80 | self.reg_write(DYNPD, 0) 81 | 82 | # auto retransmit delay: 1750us 83 | # auto retransmit count: 8 84 | self.reg_write(SETUP_RETR, (6 << 4) | 8) 85 | 86 | # set rf power and speed 87 | self.set_power_speed(POWER_3, SPEED_250K) # Best for point to point links 88 | 89 | # init CRC 90 | self.set_crc(2) 91 | 92 | # clear status flags 93 | self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) 94 | 95 | # set channel 96 | self.set_channel(channel) 97 | 98 | # flush buffers 99 | self.flush_rx() 100 | self.flush_tx() 101 | 102 | def init_spi(self, baudrate): 103 | try: 104 | master = self.spi.MASTER 105 | except AttributeError: 106 | self.spi.init(baudrate=baudrate, polarity=0, phase=0) 107 | else: 108 | self.spi.init(master, baudrate=baudrate, polarity=0, phase=0) 109 | 110 | def reg_read(self, reg): 111 | self.cs(0) 112 | self.spi.readinto(self.buf, reg) 113 | self.spi.readinto(self.buf) 114 | self.cs(1) 115 | return self.buf[0] 116 | 117 | def reg_write_bytes(self, reg, buf): 118 | self.cs(0) 119 | self.spi.readinto(self.buf, 0x20 | reg) 120 | self.spi.write(buf) 121 | self.cs(1) 122 | return self.buf[0] 123 | 124 | def reg_write(self, reg, value): 125 | self.cs(0) 126 | self.spi.readinto(self.buf, 0x20 | reg) 127 | ret = self.buf[0] 128 | self.spi.readinto(self.buf, value) 129 | self.cs(1) 130 | return ret 131 | 132 | def flush_rx(self): 133 | self.cs(0) 134 | self.spi.readinto(self.buf, FLUSH_RX) 135 | self.cs(1) 136 | 137 | def flush_tx(self): 138 | self.cs(0) 139 | self.spi.readinto(self.buf, FLUSH_TX) 140 | self.cs(1) 141 | 142 | # power is one of POWER_x defines; speed is one of SPEED_x defines 143 | def set_power_speed(self, power, speed): 144 | setup = self.reg_read(RF_SETUP) & 0b11010001 145 | self.reg_write(RF_SETUP, setup | power | speed) 146 | 147 | # length in bytes: 0, 1 or 2 148 | def set_crc(self, length): 149 | config = self.reg_read(CONFIG) & ~(CRCO | EN_CRC) 150 | if length == 0: 151 | pass 152 | elif length == 1: 153 | config |= EN_CRC 154 | else: 155 | config |= EN_CRC | CRCO 156 | self.reg_write(CONFIG, config) 157 | 158 | def set_channel(self, channel): 159 | self.reg_write(RF_CH, min(channel, 125)) 160 | 161 | # address should be a bytes object 5 bytes long 162 | def open_tx_pipe(self, address): 163 | assert len(address) == 5 164 | self.reg_write_bytes(RX_ADDR_P0, address) 165 | self.reg_write_bytes(TX_ADDR, address) 166 | self.reg_write(RX_PW_P0, self.payload_size) 167 | 168 | # address should be a bytes object 5 bytes long 169 | # pipe 0 and 1 have 5 byte address 170 | # pipes 2-5 use same 4 most-significant bytes as pipe 1, plus 1 extra byte 171 | def open_rx_pipe(self, pipe_id, address): 172 | assert len(address) == 5 173 | assert 0 <= pipe_id <= 5 174 | if pipe_id == 0: 175 | self.pipe0_read_addr = address 176 | if pipe_id < 2: 177 | self.reg_write_bytes(RX_ADDR_P0 + pipe_id, address) 178 | else: 179 | self.reg_write(RX_ADDR_P0 + pipe_id, address[0]) 180 | self.reg_write(RX_PW_P0 + pipe_id, self.payload_size) 181 | self.reg_write(EN_RXADDR, self.reg_read(EN_RXADDR) | (1 << pipe_id)) 182 | 183 | def start_listening(self): 184 | self.reg_write(CONFIG, self.reg_read(CONFIG) | PWR_UP | PRIM_RX) 185 | self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) 186 | 187 | if self.pipe0_read_addr is not None: 188 | self.reg_write_bytes(RX_ADDR_P0, self.pipe0_read_addr) 189 | 190 | self.flush_rx() 191 | self.flush_tx() 192 | self.ce(1) 193 | utime.sleep_us(130) 194 | 195 | def stop_listening(self): 196 | self.ce(0) 197 | self.flush_tx() 198 | self.flush_rx() 199 | 200 | # returns True if any data available to recv 201 | def any(self): 202 | return not bool(self.reg_read(FIFO_STATUS) & RX_EMPTY) 203 | 204 | def recv(self): 205 | # get the data 206 | self.cs(0) 207 | self.spi.readinto(self.buf, R_RX_PAYLOAD) 208 | buf = self.spi.read(self.payload_size) 209 | self.cs(1) 210 | # clear RX ready flag 211 | self.reg_write(STATUS, RX_DR) 212 | 213 | return buf 214 | 215 | # blocking wait for tx complete 216 | def send(self, buf, timeout=500): 217 | self.send_start(buf) 218 | start = utime.ticks_ms() 219 | result = None 220 | while result is None and utime.ticks_diff(utime.ticks_ms(), start) < timeout: 221 | result = self.send_done() # 1 == success, 2 == fail 222 | if result == 2: 223 | raise OSError("send failed") 224 | 225 | # non-blocking tx 226 | def send_start(self, buf): 227 | # power up 228 | self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX) 229 | utime.sleep_us(150) 230 | # send the data 231 | self.cs(0) 232 | self.spi.readinto(self.buf, W_TX_PAYLOAD) 233 | self.spi.write(buf) 234 | if len(buf) < self.payload_size: 235 | self.spi.write(b'\x00' * (self.payload_size - len(buf))) # pad out data 236 | self.cs(1) 237 | 238 | # enable the chip so it can send the data 239 | self.ce(1) 240 | utime.sleep_us(15) # needs to be >10us 241 | self.ce(0) 242 | 243 | # returns None if send still in progress, 1 for success, 2 for fail 244 | def send_done(self): 245 | if not (self.reg_read(STATUS) & (TX_DS | MAX_RT)): 246 | return None # tx not finished 247 | 248 | # either finished or failed: get and clear status flags, power down 249 | status = self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) 250 | self.reg_write(CONFIG, self.reg_read(CONFIG) & ~PWR_UP) 251 | return 1 if status & TX_DS else 2 252 | -------------------------------------------------------------------------------- /12.NRF24L01 --- 2.4G无线收发模块/nrf24l01use.py: -------------------------------------------------------------------------------- 1 | """Test for nrf24l01 module. Portable between MicroPython targets.""" 2 | import ustruct as struct 3 | import utime 4 | from pyb import Pin, SPI 5 | from nrf24l01 import NRF24L01 6 | 7 | pipes = (b'\xf0\xf0\xf0\xf0\xe1', b'\xf0\xf0\xf0\xf0\xd2') 8 | 9 | class nrf24l01: 10 | def __init__(self,spi,csn,ce): 11 | csn0 = Pin(csn, mode=Pin.OUT, value=1) 12 | ce0 = Pin(ce, mode=Pin.OUT, value=0) 13 | self.nrf = NRF24L01(SPI(spi), csn0, ce0, payload_size=8) 14 | 15 | def master(self,data): 16 | self.nrf.open_tx_pipe(pipes[0]) 17 | self.nrf.open_rx_pipe(1, pipes[1]) 18 | self.nrf.stop_listening() 19 | try: 20 | self.nrf.send(struct.pack('i', data)) #发送内容 pack为封包函数 21 | self.nrf.start_listening() 22 | start_time = utime.ticks_ms() 23 | timeout = False 24 | while not self.nrf.any() and not timeout: 25 | if utime.ticks_diff(utime.ticks_ms(), start_time) > 250: 26 | timeout = True 27 | except OSError: 28 | pass 29 | 30 | def slave(self): 31 | self.nrf.open_tx_pipe(pipes[1]) 32 | self.nrf.open_rx_pipe(1, pipes[0]) 33 | self.nrf.start_listening() 34 | while True: 35 | if self.nrf.any(): 36 | while self.nrf.any(): 37 | buf = self.nrf.recv() #接收内容 38 | data,a= struct.unpack('ii', buf)#解析包unpack为解析包函数 39 | break 40 | return data -------------------------------------------------------------------------------- /13.NRF905 --- 2.4G无线收发模块/main.py: -------------------------------------------------------------------------------- 1 | import nrf905 2 | import time 3 | from pyb import SPI 4 | 5 | RFConf=[0x00, #配置命令 6 | 0x4c, #频段设置为423Mhz 7 | 0x0c, #输出功率为10db,不重发,节电模式为正常 8 | 0x44, #地址宽度设置为4字节 9 | 0x0a,0x0a, #接收发送有效数据长度为3字节 10 | 0xcc,0xcc,0xcc,0xcc, #接收地址 11 | 0x58 #CRC允许,8位CRC校验,外部时钟信号不使能 12 | ] 13 | TxAddress=[0xcc,0xcc,0xcc,0xcc] #接收地址 14 | 15 | buf=[0x06,0xa0,0xb0,0x01,0x02,0] #发送内容 16 | 17 | spi=pyb.SPI(2) 18 | n=nrf905.NRF905(spi=spi,ce='Y1',txen='Y2',pwr='Y3',cd='Y4',dr='Y12',cs='Y11', 19 | RFConf=RFConf,TxAddress=TxAddress) 20 | i=0 21 | while True: 22 | buf[5]=i 23 | n.sender_bruff(buf) 24 | time.sleep_ms(200) 25 | print(i) 26 | i+=1 27 | 28 | # import nrf905 29 | # import time 30 | # import pyb 31 | 32 | # RFConf=[0x00, #配置命令 33 | # 0x4c, #频段设置为423Mhz 34 | # 0x0c, #输出功率为10db,不重发,节电模式为正常 35 | # 0x44, #地址宽度设置为4字节 36 | # 0x0a,0x0a, #接收发送有效数据长度为3字节 37 | # 0xcc,0xcc,0xcc,0xcc, #接收地址 38 | # 0x58 #CRC允许,8位CRC校验,外部时钟信号不使能 39 | # ] 40 | 41 | # spi=pyb.SPI(2) 42 | # n=nrf905.NRF905(spi=spi,ce='Y1',txen='Y2',pwr='Y3',cd='Y4',dr='X9',cs='X10', 43 | # RFConf=RFConf,TxAddress=None) 44 | # while True: 45 | # buf=n.recvrx() 46 | # print (buf) -------------------------------------------------------------------------------- /13.NRF905 --- 2.4G无线收发模块/nrf905.py: -------------------------------------------------------------------------------- 1 | import pyb 2 | from pyb import SPI,Pin 3 | import time 4 | 5 | WC =0X00 6 | RC =0X10 7 | WTP=0X20 8 | RTP=0X21 9 | WTA=0X22 10 | RTA=0X23 11 | PRP=0X24 12 | 13 | class NRF905: 14 | def __init__(self,spi,ce,txen,pwr,cd,dr,cs,RFConf,TxAddress): 15 | spi.init(spi.MASTER,baudrate=1000000,polarity=0, phase=0,bits=8,firstbit=SPI.MSB) 16 | self.spi=spi 17 | self.ce=Pin(ce,Pin.OUT_PP) 18 | self.txen=Pin(txen,Pin.OUT_PP) 19 | self.pwr=Pin(pwr,Pin.OUT_PP) 20 | self.cs=Pin(cs,Pin.OUT_PP) 21 | self.cd=Pin(cd,Pin.IN) 22 | self.dr=Pin(dr,Pin.IN) 23 | self.RFConf=RFConf 24 | self.TxAddress=TxAddress 25 | 26 | self.cs.value(1) 27 | self.dr.value(0) 28 | self.cd.value(0) 29 | self.pwr.value(1) 30 | self.ce.value(0) 31 | self.txen.value(0) 32 | self.Config905() 33 | 34 | def Config905(self): 35 | self.cs.value(0) 36 | time.sleep_ms(1) 37 | for i in range(11): 38 | self.spi.send(self.RFConf[i]) 39 | self.cs.value(1) 40 | 41 | def txpacket(self,buf): 42 | self.cs.value(0) 43 | time.sleep_ms(1) 44 | self.spi.send(WTP) 45 | for i in range(len(buf)): 46 | self.spi.send(buf[i]) 47 | self.cs.value(1) 48 | time.sleep_ms(1) 49 | self.cs.value(0) 50 | time.sleep_ms(1) 51 | self.spi.send(WTA) 52 | for i in range(4): 53 | self.spi.send(self.TxAddress[i]) 54 | self.cs.value(1) 55 | time.sleep_ms(1) 56 | self.ce.value(1) 57 | time.sleep_ms(100) 58 | self.ce.value(0) 59 | 60 | def setTXmode(self): 61 | self.ce.value(1) 62 | self.txen.value(1) 63 | time.sleep_ms(1) 64 | 65 | def sender_bruff(self,buf): 66 | self.setTXmode() 67 | time.sleep_ms(10) 68 | self.txpacket(buf) 69 | time.sleep_ms(100) 70 | 71 | def rxpacket(self): 72 | time.sleep_ms(100) 73 | self.cs.value(0) 74 | time.sleep_ms(1) 75 | self.spi.send(PRP) 76 | a=list(self.spi.recv(1))[0] 77 | rx_bruff=[] 78 | for i in range(a): 79 | rx_bruff.append(list(self.spi.recv(1))[0]) 80 | self.cs.value(1) 81 | time.sleep_ms(100) 82 | self.ce.value(0) 83 | return rx_bruff 84 | 85 | def checkDR(self): 86 | if self.dr.value(): 87 | return 1 88 | return 0 89 | 90 | def setRXmode(self): 91 | self.txen.value(0) 92 | self.ce.value(1) 93 | time.sleep_ms(1) 94 | 95 | def recvrx(self): 96 | self.setRXmode() 97 | while (self.checkDR()==0): 98 | a=0 99 | time.sleep_ms(100) 100 | return self.rxpacket() -------------------------------------------------------------------------------- /14.SYN6288 --- SYN6288语音合成模块/main.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TPYBoard/TPYBoard_lib/6071a30bcf438c44f834e99e5209c182a2fc287d/14.SYN6288 --- SYN6288语音合成模块/main.py -------------------------------------------------------------------------------- /14.SYN6288 --- SYN6288语音合成模块/syn6288.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TPYBoard/TPYBoard_lib/6071a30bcf438c44f834e99e5209c182a2fc287d/14.SYN6288 --- SYN6288语音合成模块/syn6288.py -------------------------------------------------------------------------------- /15.AT24C0X --- AT24C0X存储器/at24c0x.py: -------------------------------------------------------------------------------- 1 | import pyb 2 | from pyb import Pin, I2C 3 | 4 | class AT24C0X: 5 | def __init__(self,spi): 6 | self.accel_addr = 80 7 | self.i2c = pyb.I2C(spi) 8 | self.i2c.init(pyb.I2C.MASTER, baudrate=400000) 9 | print(self.i2c.scan()) 10 | 11 | def writeAT24C0X(self,addr,data): 12 | self.i2c.scan() 13 | self.i2c.is_ready(self.accel_addr) 14 | if isinstance(data,int): 15 | size=1 16 | else: 17 | size=int(len(data)/8)+1 18 | b=bytearray(data) 19 | for i in range(size): 20 | self.i2c.mem_write(b[i*8:i*8+8], self.accel_addr,0,timeout=1000, addr_size=8) 21 | 22 | def readAT24C0X(self,add,bit_len): 23 | self.i2c.scan() 24 | self.i2c.is_ready(self.accel_addr) 25 | self.data=self.i2c.mem_read(bit_len, self.accel_addr, add, timeout=1000,addr_size=8) 26 | return self.data -------------------------------------------------------------------------------- /15.AT24C0X --- AT24C0X存储器/main.py: -------------------------------------------------------------------------------- 1 | import at24c0x 2 | 3 | def main(): 4 | at24c=at24c0x.AT24C0x(1) 5 | at24c.writeAT24C0x(0,'qxw') 6 | print(at24c.readAT24C0x(0,3)) 7 | main() -------------------------------------------------------------------------------- /16.NixieTube --- 数码管/digital.py: -------------------------------------------------------------------------------- 1 | import pyb 2 | 3 | class Digital(): 4 | def __init__(self,type,p_list): 5 | if type: 6 | self.tab = [0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e] 7 | else: 8 | self.tab = [0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71] 9 | self.pins = p_list 10 | 11 | def display(self,data): 12 | a=self.tab[data] 13 | for i in self.pins: 14 | b=a&1 15 | a>>=1 16 | i.value(b) -------------------------------------------------------------------------------- /16.NixieTube --- 数码管/main.py: -------------------------------------------------------------------------------- 1 | import pyb 2 | from pyb import Pin 3 | from digital import Digital 4 | 5 | def main(): 6 | pins = [Pin('X' + str(p),Pin.OUT_PP) for p in range(1,9)] 7 | d = Digital(1,pins) 8 | while True: 9 | for i in range(10): 10 | d.display(i) 11 | pyb.delay(500) 12 | 13 | main() -------------------------------------------------------------------------------- /17.SteperMotor --- 四相步进电机/main.py: -------------------------------------------------------------------------------- 1 | # main.py -- put your code here! 2 | from pyb import Pin 3 | from stepermotor import SteperMotor 4 | 5 | Pin_All=[Pin(p,Pin.OUT_PP) for p in ['X1','X2','X3','X4']] 6 | 7 | if __name__=='__main__': 8 | #转速(ms) 数值越大转速越慢 最小值1.8ms 9 | sm = SteperMotor(pin = Pin_All,speed=2) 10 | sm.steperRun(-360) 11 | 12 | 13 | -------------------------------------------------------------------------------- /17.SteperMotor --- 四相步进电机/stepermotor.py: -------------------------------------------------------------------------------- 1 | # main.py -- put your code here! 2 | import pyb 3 | from pyb import Pin 4 | 5 | Pin_All=[Pin(p,Pin.OUT_PP) for p in ['X1','X2','X3','X4']] 6 | STEPER_ROUND=512 #转动一圈(360度)的周期 7 | ANGLE_PER_ROUND=STEPER_ROUND/360 #转动1度的周期 8 | 9 | class SteperMotor(): 10 | 11 | def __init__(self,pin = None,speed=2): 12 | if pin != None: 13 | self.Pins = pin 14 | else: 15 | self.Pins = Pin_All 16 | self.Speed = speed 17 | #私有方法 18 | def __SteperWriteData(self,data): 19 | count=0 20 | for i in data: 21 | self.Pins[count].value(i) 22 | count+=1 23 | def __SteperFrontTurn(self): 24 | speed = self.Speed 25 | 26 | self.__SteperWriteData([1,1,0,0]) 27 | pyb.delay(speed) 28 | 29 | self.__SteperWriteData([0,1,1,0]) 30 | pyb.delay(speed) 31 | 32 | self.__SteperWriteData([0,0,1,1]) 33 | pyb.delay(speed) 34 | 35 | self.__SteperWriteData([1,0,0,1]) 36 | pyb.delay(speed) 37 | 38 | def __SteperBackTurn(self): 39 | speed = self.Speed 40 | 41 | self.__SteperWriteData([1,1,0,0]) 42 | pyb.delay(speed) 43 | 44 | self.__SteperWriteData([1,0,0,1]) 45 | pyb.delay(speed) 46 | 47 | self.__SteperWriteData([0,0,1,1]) 48 | pyb.delay(speed) 49 | 50 | self.__SteperWriteData([0,1,1,0]) 51 | pyb.delay(speed) 52 | 53 | 54 | def __SteperStop(self): 55 | self.__SteperWriteData([0,0,0,0]) 56 | 57 | def steperRun(self,angle): 58 | val=ANGLE_PER_ROUND*abs(angle) 59 | if(angle>0): 60 | for i in range(0,val): 61 | self.__SteperFrontTurn() 62 | else: 63 | for i in range(0,val): 64 | self.__SteperBackTurn() 65 | angle = 0 66 | self.__SteperStop() -------------------------------------------------------------------------------- /18.PS2 --- PS2无线手柄/main.py: -------------------------------------------------------------------------------- 1 | # main.py -- put your code here! 2 | import PS2 3 | 4 | while True: 5 | ps=PS2.PS2KEY('X18','X19','X20','X21') 6 | a=ps.ps2_key() 7 | if(a==13): 8 | pyb.LED(1).on() 9 | elif(a==14): 10 | pyb.LED(2).on() 11 | elif(a==15): 12 | pyb.LED(3).on() 13 | elif(a==16): 14 | pyb.LED(4).on() 15 | elif(a==5): 16 | pyb.LED(1).off() 17 | elif(a==6): 18 | pyb.LED(2).off() 19 | elif(a==7): 20 | pyb.LED(3).off() 21 | elif(a==8): 22 | pyb.LED(4).off() 23 | -------------------------------------------------------------------------------- /18.PS2 --- PS2无线手柄/ps2.py: -------------------------------------------------------------------------------- 1 | # main.py -- put your code here! 2 | import pyb 3 | from pyb import Pin 4 | import time 5 | 6 | PSB_SELECT = 1 7 | PSB_L3 = 2 8 | PSB_R3 = 3 9 | PSB_START = 4 10 | PSB_PAD_UP = 5 11 | PSB_PAD_RIGHT = 6 12 | PSB_PAD_DOWN = 7 13 | PSB_PAD_LEFT = 8 14 | PSB_L2 = 9 15 | PSB_R2 = 10 16 | PSB_L1 = 11 17 | PSB_R1 = 12 18 | PSB_GREEN = 13 19 | PSB_RED = 14 20 | PSB_BLUE = 15 21 | PSB_PINK = 16 22 | PSB_TRIANGLE = 13 23 | PSB_CIRCLE = 14 24 | PSB_CROSS = 15 25 | PSB_SQUARE = 26 26 | PSS_RX = 5 #x 27 | PSS_RY = 6 28 | PSS_LX = 7 29 | PSS_LY = 8 30 | 31 | mask=[ 32 | PSB_SELECT, 33 | PSB_L3, 34 | PSB_R3 , 35 | PSB_START, 36 | PSB_PAD_UP, 37 | PSB_PAD_RIGHT, 38 | PSB_PAD_DOWN, 39 | PSB_PAD_LEFT, 40 | PSB_L2, 41 | PSB_R2, 42 | PSB_L1, 43 | PSB_R1 , 44 | PSB_GREEN, 45 | PSB_RED, 46 | PSB_BLUE, 47 | PSB_PINK] 48 | comd=[0x01,0x42] 49 | data=[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] 50 | 51 | class PS2KEY: 52 | #PS2KEY('X18','X19','X20','X21') 53 | def __init__(self,_di,_do,_cs,_clk): 54 | 55 | self.di=Pin(_di,Pin.IN,Pin.PULL_DOWN) 56 | self.do=Pin(_do,Pin.OUT_PP) 57 | self.cs=Pin(_cs,Pin.OUT_PP) 58 | self.clk=Pin(_clk,Pin.OUT_PP) 59 | 60 | self.ps2_init() 61 | self.ps2_red() 62 | 63 | def ps2_init(self): 64 | self.clk.value(1) 65 | self.do.value(1) 66 | time.sleep_ms(10) 67 | 68 | def ps2_cmd(self,cmd): 69 | global data 70 | data[1]=0 71 | for ref in (1,2,4,8,16,32,64,128): 72 | if ( ref & cmd): 73 | self.do.value(1) 74 | else: 75 | self.do.value(0) 76 | self.clk.value(1) 77 | time.sleep_us(10) 78 | self.clk.value(0) 79 | time.sleep_us(10) 80 | self.clk.value(1) 81 | if(self.di.value()==1): 82 | data[1]=ref|data[1] 83 | 84 | def ps2_red(self): 85 | global data 86 | global comd 87 | self.cs.value(0) 88 | self.ps2_cmd(comd[0]) 89 | self.ps2_cmd(comd[1]) 90 | self.cs.value(1) 91 | if(data[1]==57): 92 | return 0#red light 93 | else: 94 | return 1#not red 95 | 96 | def ps2_read(self): 97 | global data 98 | global comd 99 | byte=0 100 | ref=0x01 101 | self.cs.value(0) 102 | self.ps2_cmd(comd[0]) 103 | self.ps2_cmd(comd[1]) 104 | for byte in (2,3,4,5,6,7,8): 105 | for ref in (1,2,4,8,16,32,64,128): 106 | self.clk.value(1) 107 | self.clk.value(0) 108 | time.sleep_us(10) 109 | self.clk.value(1) 110 | if(self.di.value()==1): 111 | data[byte]= ref|data[byte] 112 | time.sleep_us(10) 113 | self.cs.value(1) 114 | 115 | def ps2_clear(self):#ok 116 | global data 117 | for i in range(0,9,1): 118 | data[i]=0 119 | 120 | def ps2_andata(self,button): 121 | global data 122 | return data[button] 123 | 124 | def ps2_key(self): 125 | global data 126 | global mask 127 | self.ps2_clear() 128 | self.ps2_read() 129 | handkey=(data[4]<<8)|data[3] 130 | for index in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15): 131 | if (( handkey&(1<<(mask[index]-1)))==0): 132 | return index+2 133 | return 0 134 | 135 | # while True: 136 | # ps2_init() 137 | # ps2_red() 138 | # a=ps2_key() 139 | # if(a==13): 140 | # pyb.LED(1).on() 141 | # elif(a==14): 142 | # pyb.LED(2).on() 143 | # elif(a==15): 144 | # pyb.LED(3).on() 145 | # elif(a==16): 146 | # pyb.LED(4).on() 147 | # elif(a==5): 148 | # pyb.LED(1).off() 149 | # elif(a==6): 150 | # pyb.LED(2).off() 151 | # elif(a==7): 152 | # pyb.LED(3).off() 153 | # elif(a==8): 154 | # pyb.LED(4).off() 155 | -------------------------------------------------------------------------------- /19.AS608 --- AS608指纹识别/as608.py: -------------------------------------------------------------------------------- 1 | from pyb import UART 2 | from pyb import delay 3 | 4 | head=b'\xEF\x01\xFF\xFF\xFF\xFF\x01\x00' 5 | link=b'\x07\x13\x00\x00\x00\x00\x00\x1B' 6 | readflash=b'\x03\x16\x00\x1A' 7 | readmould=b'\x03\x1D\x00\x21' 8 | readindex=b'\x04\x1F\x00\x00\x24' 9 | readindex1=b'\x04\x1F\x01\x00\x25' 10 | cmd_search=b'\x03\x01\x00\x05' 11 | cmd_upload=b'\x03\x0A\x00\x0E' 12 | cmd_gen1=b'\x04\x02\x01\x00\x08' 13 | cmd_gen2=b'\x04\x02\x02\x00\x09' 14 | cmd_reg=b'\x03\x05\x00\x09' 15 | cmd_save=b'\x06\x06\x01\x00' #+存储地址+两字节校验(0xE+存储地址) 16 | cmd_dis=b'\x08\x04\x01\x00\x00\x01\x2C\x00\x3B' 17 | 18 | class FIG: 19 | def __init__(self,uart): 20 | self.uart = UART(uart, 57600) 21 | self.sendcmd(link) 22 | self.sendcmd(readflash) 23 | self.sendcmd(readmould) 24 | self.sendcmd(readindex) 25 | self.sendcmd(readindex1) 26 | delay(500) 27 | 28 | def sendcmd(self,cmd): 29 | self.uart.write(head) 30 | self.uart.write(cmd) 31 | 32 | def searchfig(self): 33 | hc=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 34 | self.uart.read() 35 | self.sendcmd(cmd_search) 36 | hc=self.uart.read() 37 | while hc[11]!=0xa: 38 | self.sendcmd(cmd_search) 39 | hc=self.uart.read() 40 | self.sendcmd(cmd_upload) 41 | 42 | def savefig(self,addr): 43 | print('请按手指') 44 | self.searchfig() 45 | self.sendcmd(cmd_gen1) 46 | print('请再按手指') 47 | self.searchfig() 48 | self.sendcmd(cmd_gen2) 49 | self.sendcmd(cmd_reg) 50 | add=cmd_save+bytearray([addr,0,addr+0xe]) 51 | self.sendcmd(add) 52 | print('存入成功') 53 | 54 | def disfig(self): 55 | print('请按手指') 56 | self.searchfig() 57 | print('识别中') 58 | self.uart.read() 59 | delay(20) 60 | self.sendcmd(cmd_gen1) 61 | self.sendcmd(cmd_dis) 62 | delay(10) 63 | hc=self.uart.read() 64 | delay(10) 65 | if hc[9]==9: 66 | return 0 67 | else : 68 | return hc[11] -------------------------------------------------------------------------------- /19.AS608 --- AS608指纹识别/main.py: -------------------------------------------------------------------------------- 1 | import as608 2 | 3 | fig=as608.FIG(4) 4 | 5 | fig.savefig(37) 6 | user=fig.disfig() 7 | if(user==0): 8 | print('无法识别') 9 | else : 10 | print('找到用户',user) -------------------------------------------------------------------------------- /19.AS608 --- AS608指纹识别/指纹指令.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TPYBoard/TPYBoard_lib/6071a30bcf438c44f834e99e5209c182a2fc287d/19.AS608 --- AS608指纹识别/指纹指令.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TPYBoard_lib 2 | 3 | 此项目是TPYBoard积累的一些模块的驱动类库,为了方便TPYBoard/MicroPython的爱好者使用,特此共享。大家也可以将自己积累的一些类库共享在此处,共同学习、共同进步。 4 | 5 | 模块对应的使用方法:http://docs.tpyboard.com/zh/latest/tpyboard/driver/ 6 | --------------------------------------------------------------------------------