Arduino_ST7789_Fast 项目下载及安装教程

Arduino_ST7789_Fast 项目下载及安装教程

Arduino_ST7789_Fast Fast SPI library for the ST7789 IPS display Arduino_ST7789_Fast 项目地址: https://gitcode.com/gh_mirrors/ar/Arduino_ST7789_Fast

1. 项目介绍

Arduino_ST7789_Fast 是一个针对 ST7789 240x240 IPS 显示屏的快速 SPI 库。该库经过优化,特别适用于 16MHz AVR Arduino 板,能够实现高达 6.9Mbps 的 SPI 传输速率。此外,该库还支持兼容模式,可以在其他 Arduino 兼容板上运行。

2. 项目下载位置

要下载 Arduino_ST7789_Fast 项目,请按照以下步骤操作:

  1. 打开终端或命令提示符。
  2. 使用 git clone 命令下载项目:
git clone https://github.com/cbm80amiga/Arduino_ST7789_Fast.git

3. 项目安装环境配置

在安装项目之前,请确保您的开发环境已正确配置。以下是配置步骤:

3.1 安装 Arduino IDE

  1. 访问 Arduino 官方网站 下载并安装 Arduino IDE。
  2. 安装完成后,打开 Arduino IDE。

3.2 安装 Adafruit_GFX 库

  1. 在 Arduino IDE 中,点击 工具 -> 管理库
  2. 在库管理器中搜索 Adafruit_GFX,然后点击安装。

3.3 配置开发板

  1. 在 Arduino IDE 中,点击 工具 -> 开发板,选择您使用的 Arduino 开发板(例如 Arduino Uno)。
  2. 配置正确的端口(工具 -> 端口)。

3.4 环境配置示例

Arduino IDE 配置示例

4. 项目安装方式

  1. 将下载的项目文件夹 Arduino_ST7789_Fast 复制到您的 Arduino 库目录中。通常,该目录位于 Documents/Arduino/libraries/
  2. 在 Arduino IDE 中,点击 文件 -> 示例,您应该能够看到 Arduino_ST7789_Fast 示例程序。
  3. 打开一个示例程序,例如 Arduino_ST7789_Fast_Example,然后点击 上传 按钮将代码上传到您的 Arduino 开发板。

5. 项目处理脚本

在项目中,您可以使用以下脚本来处理显示操作:

#include <Arduino_ST7789_Fast.h>

#define TFT_DC    7
#define TFT_RST   8
#define TFT_CS    9

Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_CS);

void setup() {
  tft.init();
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(2);
  tft.setCursor(0, 0);
  tft.println("Hello, ST7789!");
}

void loop() {
  // 循环操作
}

以上代码展示了如何初始化显示屏并显示文本。您可以根据需要修改和扩展该脚本。


通过以上步骤,您应该能够成功下载、安装并运行 Arduino_ST7789_Fast 项目。如果在安装过程中遇到任何问题,请参考项目的 README 文件或联系项目维护者。

Arduino_ST7789_Fast Fast SPI library for the ST7789 IPS display Arduino_ST7789_Fast 项目地址: https://gitcode.com/gh_mirrors/ar/Arduino_ST7789_Fast

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

根据以下代码,修改SPI速度#include "Arduino_ST7789_Fast.h" #include <limits.h> #include "pins_arduino.h" #include "wiring_private.h" #include <SPI.h> // ----------------------------------------- // ST7789 commands #define ST7789_NOP 0x00 #define ST7789_SWRESET 0x01 #define ST7789_SLPIN 0x10 // sleep on #define ST7789_SLPOUT 0x11 // sleep off #define ST7789_PTLON 0x12 // partial on #define ST7789_NORON 0x13 // partial off #define ST7789_INVOFF 0x20 // invert off #define ST7789_INVON 0x21 // invert on #define ST7789_DISPOFF 0x28 // display off #define ST7789_DISPON 0x29 // display on #define ST7789_IDMOFF 0x38 // idle off #define ST7789_IDMON 0x39 // idle on #define ST7789_CASET 0x2A #define ST7789_RASET 0x2B #define ST7789_RAMWR 0x2C #define ST7789_RAMRD 0x2E #define ST7789_COLMOD 0x3A #define ST7789_MADCTL 0x36 #define ST7789_PTLAR 0x30 // partial start/end #define ST7789_VSCRDEF 0x33 // SETSCROLLAREA #define ST7789_VSCRSADD 0x37 #define ST7789_WRDISBV 0x51 #define ST7789_WRCTRLD 0x53 #define ST7789_WRCACE 0x55 #define ST7789_WRCABCMB 0x5e #define ST7789_POWSAVE 0xbc #define ST7789_DLPOFFSAVE 0xbd // bits in MADCTL #define ST7789_MADCTL_MY 0x80 #define ST7789_MADCTL_MX 0x40 #define ST7789_MADCTL_MV 0x20 #define ST7789_MADCTL_ML 0x10 #define ST7789_MADCTL_RGB 0x00 #define ST7789_240x240_XSTART 0 #define ST7789_240x240_YSTART 0 #define ST_CMD_DELAY 0x80 // Initialization commands for ST7789 240x240 1.3" IPS // taken from Adafruit static const uint8_t PROGMEM init_240x240[] = { 9, // 9 commands in list: ST7789_SWRESET, ST_CMD_DELAY, // 1: Software reset, no args, w/delay 150, // 150 ms delay ST7789_SLPOUT , ST_CMD_DELAY, // 2: Out of sleep mode, no args, w/delay 255, // 255 = 500 ms delay ST7789_COLMOD , 1+ST_CMD_DELAY, // 3: Set color mode, 1 arg + delay: 0x55, // 16-bit color 10, // 10 ms delay ST7789_MADCTL , 1, // 4: Memory access ctrl (directions), 1 arg: 0x00, // Row addr/col addr, bottom to top refresh ST7789_CASET , 4, // 5: Column addr set, 4 args, no delay: 0x00, ST7789_240x240_XSTART, // XSTART = 0 (ST7789_TFTWIDTH+ST7789_240x240_XSTART) >> 8, (ST7789_TFTWIDTH+ST7789_240x240_XSTART) & 0xFF, // XEND = 240 ST7789_RASET , 4, // 6: Row addr set, 4 args, no delay: 0x00, ST7789_240x240_YSTART, // YSTART = 0 (ST7789_TFTHEIGHT+ST7789_240x240_YSTART) >> 8, (ST7789_TFTHEIGHT+ST7789_240x240_YSTART) & 0xFF, // YEND = 240 ST7789_INVON , ST_CMD_DELAY, // 7: Inversion ON 10, ST7789_NORON , ST_CMD_DELAY, // 8: Normal display on, no args, w/delay 10, // 10 ms delay ST7789_DISPON , ST_CMD_DELAY, // 9: Main screen turn on, no args, w/delay 20 }; // ----------------------------------------- #ifdef COMPATIBILITY_MODE static SPISettings spiSettings; #define SPI_START SPI.beginTransaction(spiSettings) #define SPI_END SPI.endTransaction() #else #define SPI_START #define SPI_END #endif // macros for fast DC and CS state changes #ifdef COMPATIBILITY_MODE #define DC_DATA digitalWrite(dcPin, HIGH) #define DC_COMMAND digitalWrite(dcPin, LOW) #define CS_IDLE digitalWrite(csPin, HIGH) #define CS_ACTIVE digitalWrite(csPin, LOW) #else #define DC_DATA *dcPort |= dcMask #define DC_COMMAND *dcPort &= ~dcMask #define CS_IDLE *csPort |= csMask #define CS_ACTIVE *csPort &= ~csMask #endif // if CS always connected to the ground then don't do anything for better performance #ifdef CS_ALWAYS_LOW #define CS_IDLE #define CS_ACTIVE #endif // ---------------------------------------------------------- // speed test results: // in AVR best performance mode -> about 6.9 Mbps // in compatibility mode (SPI.transfer(c)) -> about 4 Mbps inline void Arduino_ST7789::writeSPI(uint8_t c) { #ifdef COMPATIBILITY_MODE SPI.transfer(c); #else SPDR = c; /* asm volatile("nop"); // 8 NOPs seem to be enough for 16MHz AVR @ DIV2 to avoid using while loop asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); */ asm volatile("rjmp .+0\n"); asm volatile("rjmp .+0\n"); asm volatile("rjmp .+0\n"); asm volatile("rjmp .+0\n"); //while(!(SPSR & _BV(SPIF))) ; #endif } // ---------------------------------------------------------- // fast method to send multiple 16-bit values via SPI inline void Arduino_ST7789::writeMulti(uint16_t color, uint16_t num) { #ifdef COMPATIBILITY_MODE while(num--) { SPI.transfer(color>>8); SPI.transfer(color); } #else asm volatile ( "next:\n" "out %[spdr],%[hi]\n" "rjmp .+0\n" // wait 8*2+1 = 17 cycles "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "nop\n" "out %[spdr],%[lo]\n" "rjmp .+0\n" // wait 6*2+1 = 13 cycles + sbiw + brne "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "nop\n" "sbiw %[num],1\n" "brne next\n" : [num] "+w" (num) : [spdr] "I" (_SFR_IO_ADDR(SPDR)), [lo] "r" ((uint8_t)color), [hi] "r" ((uint8_t)(color>>8)) ); #endif } // ---------------------------------------------------------- // fast method to send multiple 16-bit values from RAM via SPI inline void Arduino_ST7789::copyMulti(uint8_t *img, uint16_t num) { #ifdef COMPATIBILITY_MODE while(num--) { SPI.transfer(*(img+1)); SPI.transfer(*(img+0)); img+=2; } #else uint8_t lo,hi; asm volatile ( "nextCopy:\n" "ld %[hi],%a[img]+\n" "ld %[lo],%a[img]+\n" "out %[spdr],%[lo]\n" "rjmp .+0\n" // wait 8*2+1 = 17 cycles "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "nop\n" "out %[spdr],%[hi]\n" "rjmp .+0\n" // wait 4*2+1 = 9 cycles + sbiw + brne + ld*2 "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "nop\n" "sbiw %[num],1\n" "brne nextCopy\n" : [num] "+w" (num) : [spdr] "I" (_SFR_IO_ADDR(SPDR)), [img] "e" (img), [lo] "r" (lo), [hi] "r" (hi) ); #endif } // ---------------------------------------------------------- Arduino_ST7789::Arduino_ST7789(int8_t dc, int8_t rst, int8_t cs) : Adafruit_GFX(ST7789_TFTWIDTH, ST7789_TFTHEIGHT) { csPin = cs; dcPin = dc; rstPin = rst; } // ---------------------------------------------------------- void Arduino_ST7789::init(uint16_t width, uint16_t height) { commonST7789Init(NULL); if(width==240 && height==240) { _colstart = 0; _rowstart = 80; } else { _colstart = 0; _rowstart = 0; } _ystart = _xstart = 0; _width = width; _height = height; displayInit(init_240x240); setRotation(2); } // ---------------------------------------------------------- void Arduino_ST7789::writeCmd(uint8_t c) { DC_COMMAND; CS_ACTIVE; SPI_START; writeSPI(c); CS_IDLE; SPI_END; } // ---------------------------------------------------------- void Arduino_ST7789::writeData(uint8_t d8) { DC_DATA; CS_ACTIVE; SPI_START; writeSPI(d8); CS_IDLE; SPI_END; } // ---------------------------------------------------------- void Arduino_ST7789::writeData16(uint16_t d16) { DC_DATA; CS_ACTIVE; SPI_START; writeMulti(d16,1); CS_IDLE; SPI_END; } // ---------------------------------------------------------- void Arduino_ST7789::displayInit(const uint8_t *addr) { uint8_t numCommands, numArgs; uint16_t ms; numCommands = pgm_read_byte(addr++); while(numCommands--) { writeCmd(pgm_read_byte(addr++)); numArgs = pgm_read_byte(addr++); ms = numArgs & ST_CMD_DELAY; numArgs &= ~ST_CMD_DELAY; while(numArgs--) writeData(pgm_read_byte(addr++)); if(ms) { ms = pgm_read_byte(addr++); if(ms==255) ms=500; delay(ms); } } } // ---------------------------------------------------------- // Initialization code common to all ST7789 displays void Arduino_ST7789::commonST7789Init(const uint8_t *cmdList) { pinMode(dcPin, OUTPUT); #ifndef CS_ALWAYS_LOW pinMode(csPin, OUTPUT); #endif #ifndef COMPATIBILITY_MODE dcPort = portOutputRegister(digitalPinToPort(dcPin)); dcMask = digitalPinToBitMask(dcPin); #ifndef CS_ALWAYS_LOW csPort = portOutputRegister(digitalPinToPort(csPin)); csMask = digitalPinToBitMask(csPin); #endif #endif // on AVR ST7789 works correctly in MODE2 and MODE3 but for STM32 only MODE3 seems to be working SPI.begin(); #ifdef COMPATIBILITY_MODE spiSettings = SPISettings(16000000, MSBFIRST, SPI_MODE3); // 8000000 gives max speed on AVR 16MHz #else SPI.setClockDivider(SPI_CLOCK_DIV2); SPI.setDataMode(SPI_MODE3); #endif CS_ACTIVE; if(rstPin != -1) { pinMode(rstPin, OUTPUT); digitalWrite(rstPin, HIGH); delay(50); digitalWrite(rstPin, LOW); delay(50); digitalWrite(rstPin, HIGH); delay(50); } if(cmdList) displayInit(cmdList); } // ---------------------------------------------------------- void Arduino_ST7789::setRotation(uint8_t m) { writeCmd(ST7789_MADCTL); rotation = m & 3; switch (rotation) { case 0: writeData(ST7789_MADCTL_MX | ST7789_MADCTL_MY | ST7789_MADCTL_RGB); _xstart = _colstart; _ystart = _rowstart; break; case 1: writeData(ST7789_MADCTL_MY | ST7789_MADCTL_MV | ST7789_MADCTL_RGB); _ystart = _colstart; _xstart = _rowstart; break; case 2: writeData(ST7789_MADCTL_RGB); _xstart = 0; _ystart = 0; break; case 3: writeData(ST7789_MADCTL_MX | ST7789_MADCTL_MV | ST7789_MADCTL_RGB); _xstart = 0; _ystart = 0; break; } } // ---------------------------------------------------------- void Arduino_ST7789::setAddrWindow(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye) { xs+=_xstart; xe+=_xstart; ys+=_ystart; ye+=_ystart; CS_ACTIVE; SPI_START; DC_COMMAND; writeSPI(ST7789_CASET); DC_DATA; writeSPI(xs >> 8); writeSPI(xs); writeSPI(xe >> 8); writeSPI(xe); DC_COMMAND; writeSPI(ST7789_RASET); DC_DATA; writeSPI(ys >> 8); writeSPI(ys); writeSPI(ye >> 8); writeSPI(ye); DC_COMMAND; writeSPI(ST7789_RAMWR); DC_DATA; // no CS_IDLE + SPI_END, DC_DATA to save memory } // ---------------------------------------------------------- void Arduino_ST7789::pushColor(uint16_t color) { SPI_START; //DC_DATA; CS_ACTIVE; writeSPI(color>>8); writeSPI(color); CS_IDLE; SPI_END; } // ---------------------------------------------------------- void Arduino_ST7789::drawPixel(int16_t x, int16_t y, uint16_t color) { if(x<0 ||x>=_width || y<0 || y>=_height) return; setAddrWindow(x,y,x+1,y+1); writeSPI(color>>8); writeSPI(color); /* asm volatile ( "out %[spdr],%[hi]\n" "rjmp .+0\n" // wait 8*2+1 = 17 cycles "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "rjmp .+0\n" "nop\n" "out %[spdr],%[lo]\n" //"rjmp .+0\n" // wait 6*2+1 = 13 cycles + sbiw + brne //"rjmp .+0\n" //"rjmp .+0\n" //"rjmp .+0\n" //"nop\n" : : [spdr] "I" (_SFR_IO_ADDR(SPDR)), [lo] "r" ((uint8_t)color), [hi] "r" ((uint8_t)(color>>8)) ); */ CS_IDLE; SPI_END; } // ---------------------------------------------------------- void Arduino_ST7789::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { if(x>=_width || y>=_height || h<=0) return; if(y+h-1>=_height) h=_height-y; setAddrWindow(x, y, x, y+h-1); writeMulti(color,h); CS_IDLE; SPI_END; } // ---------------------------------------------------------- void Arduino_ST7789::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { if(x>=_width || y>=_height || w<=0) return; if(x+w-1>=_width) w=_width-x; setAddrWindow(x, y, x+w-1, y); writeMulti(color,w); CS_IDLE; SPI_END; } // ---------------------------------------------------------- void Arduino_ST7789::fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } // ---------------------------------------------------------- void Arduino_ST7789::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { if(x>=_width || y>=_height || w<=0 || h<=0) return; if(x+w-1>=_width) w=_width -x; if(y+h-1>=_height) h=_height-y; setAddrWindow(x, y, x+w-1, y+h-1); writeMulti(color,w*h); CS_IDLE; SPI_END; } // ---------------------------------------------------------- // draws image from RAM void Arduino_ST7789::drawImage(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t *img16) { // all protections should be on the application side if(w<=0 || h<=0) return; // left for compatibility //if(x>=_width || y>=_height || w<=0 || h<=0) return; //if(x+w-1>=_width) w=_width -x; //if(y+h-1>=_height) h=_height-y; setAddrWindow(x, y, x+w-1, y+h-1); copyMulti((uint8_t *)img16, w*h); CS_IDLE; SPI_END; } // ---------------------------------------------------------- // draws image from flash (PROGMEM) void Arduino_ST7789::drawImageF(int16_t x, int16_t y, int16_t w, int16_t h, const uint16_t *img16) { if(x>=_width || y>=_height || w<=0 || h<=0) return; setAddrWindow(x, y, x+w-1, y+h-1); uint32_t num = (uint32_t)w*h; uint16_t num16 = num>>3; uint8_t *img = (uint8_t *)img16; while(num16--) { writeSPI(pgm_read_byte(img+1)); writeSPI(pgm_read_byte(img+0)); img+=2; writeSPI(pgm_read_byte(img+1)); writeSPI(pgm_read_byte(img+0)); img+=2; writeSPI(pgm_read_byte(img+1)); writeSPI(pgm_read_byte(img+0)); img+=2; writeSPI(pgm_read_byte(img+1)); writeSPI(pgm_read_byte(img+0)); img+=2; writeSPI(pgm_read_byte(img+1)); writeSPI(pgm_read_byte(img+0)); img+=2; writeSPI(pgm_read_byte(img+1)); writeSPI(pgm_read_byte(img+0)); img+=2; writeSPI(pgm_read_byte(img+1)); writeSPI(pgm_read_byte(img+0)); img+=2; writeSPI(pgm_read_byte(img+1)); writeSPI(pgm_read_byte(img+0)); img+=2; } uint8_t num8 = num & 0x7; while(num8--) { writeSPI(pgm_read_byte(img+1)); writeSPI(pgm_read_byte(img+0)); img+=2; } CS_IDLE; SPI_END; } // ---------------------------------------------------------- // Pass 8-bit (each) R,G,B, get back 16-bit packed color uint16_t Arduino_ST7789::Color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } // ---------------------------------------------------------- void Arduino_ST7789::invertDisplay(boolean mode) { writeCmd(!mode ? ST7789_INVON : ST7789_INVOFF); // modes inverted? } // ---------------------------------------------------------- void Arduino_ST7789::partialDisplay(boolean mode) { writeCmd(mode ? ST7789_PTLON : ST7789_NORON); } // ---------------------------------------------------------- void Arduino_ST7789::sleepDisplay(boolean mode) { writeCmd(mode ? ST7789_SLPIN : ST7789_SLPOUT); delay(5); } // ---------------------------------------------------------- void Arduino_ST7789::enableDisplay(boolean mode) { writeCmd(mode ? ST7789_DISPON : ST7789_DISPOFF); } // ---------------------------------------------------------- void Arduino_ST7789::idleDisplay(boolean mode) { writeCmd(mode ? ST7789_IDMON : ST7789_IDMOFF); } // ---------------------------------------------------------- void Arduino_ST7789::resetDisplay() { writeCmd(ST7789_SWRESET); delay(5); } // ---------------------------------------------------------- void Arduino_ST7789::setScrollArea(uint16_t tfa, uint16_t bfa) { uint16_t vsa = 320-tfa-bfa; // ST7789 320x240 VRAM writeCmd(ST7789_VSCRDEF); writeData16(tfa); writeData16(vsa); writeData16(bfa); } // ---------------------------------------------------------- void Arduino_ST7789::setScroll(uint16_t vsp) { writeCmd(ST7789_VSCRSADD); writeData16(vsp); } // ---------------------------------------------------------- void Arduino_ST7789::setPartArea(uint16_t sr, uint16_t er) { writeCmd(ST7789_PTLAR); writeData16(sr); writeData16(er); } // ---------------------------------------------------------- // doesn't work void Arduino_ST7789::setBrightness(uint8_t br) { //writeCmd(ST7789_WRCACE); //writeData(0xb1); // 80,90,b0, or 00,01,02,03 //writeCmd(ST7789_WRCABCMB); //writeData(120); //BCTRL=0x20, dd=0x08, bl=0x04 int val = 0x04; writeCmd(ST7789_WRCTRLD); writeData(val); writeCmd(ST7789_WRDISBV); writeData(br); } // ---------------------------------------------------------- // 0 - off // 1 - idle // 2 - normal // 4 - display off void Arduino_ST7789::powerSave(uint8_t mode) { if(mode==0) { writeCmd(ST7789_POWSAVE); writeData(0xec|3); writeCmd(ST7789_DLPOFFSAVE); writeData(0xff); return; } int is = (mode&1) ? 0 : 1; int ns = (mode&2) ? 0 : 2; writeCmd(ST7789_POWSAVE); writeData(0xec|ns|is); if(mode&4) { writeCmd(ST7789_DLPOFFSAVE); writeData(0xfe); } } // ------------------------------------------------ // Input a value 0 to 511 (85*6) to get a color value. // The colours are a transition R - Y - G - C - B - M - R. void Arduino_ST7789::rgbWheel(int idx, uint8_t *_r, uint8_t *_g, uint8_t *_b) { idx &= 0x1ff; if(idx < 85) { // R->Y *_r = 255; *_g = idx * 3; *_b = 0; return; } else if(idx < 85*2) { // Y->G idx -= 85*1; *_r = 255 - idx * 3; *_g = 255; *_b = 0; return; } else if(idx < 85*3) { // G->C idx -= 85*2; *_r = 0; *_g = 255; *_b = idx * 3; return; } else if(idx < 85*4) { // C->B idx -= 85*3; *_r = 0; *_g = 255 - idx * 3; *_b = 255; return; } else if(idx < 85*5) { // B->M idx -= 85*4; *_r = idx * 3; *_g = 0; *_b = 255; return; } else { // M->R idx -= 85*5; *_r = 255; *_g = 0; *_b = 255 - idx * 3; return; } } uint16_t Arduino_ST7789::rgbWheel(int idx) { uint8_t r,g,b; rgbWheel(idx, &r,&g,&b); return RGBto565(r,g,b); }
最新发布
06-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张旦宪Sacha

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值