diff --git a/code/demo1/main/spi.c b/code/demo1/main/spi.c index e451230..5a4e9d9 100644 --- a/code/demo1/main/spi.c +++ b/code/demo1/main/spi.c @@ -49,7 +49,8 @@ void spi_init() .quadwp_io_num = -1, // 不使用 QWP .quadhd_io_num = -1, // 不使用 QHD .max_transfer_sz = 4096, // 最大传输大小 - .flags = SPICOMMON_BUSFLAG_MASTER, + .flags = 0, + .intr_flags = 0, }; // 2. 初始化 SPI 总线 @@ -69,6 +70,9 @@ void spi_init() .spics_io_num = LCD_CS, .queue_size = 7, // 队列深度 .flags = SPI_DEVICE_NO_DUMMY, // 禁用 dummy 周期 + .input_delay_ns = 0, + .pre_cb = NULL, + .post_cb = NULL, }; @@ -82,15 +86,33 @@ void spi_init() } -// SPI 写数据 -esp_err_t lcd_spi_write8(uint8_t data) { - spi_transaction_t trans = { - .length = 8, // 数据位数 - .tx_buffer = &data, // 发送缓冲区 - .rx_buffer = NULL, // 不接收 +// 高速数据传输函数 +esp_err_t spi_transfer_fast(spi_device_handle_t spi, uint8_t *tx_data, uint8_t *rx_data, size_t len) +{ + spi_transaction_t t = { + .flags = 0, + .cmd = 0, + .addr = 0, + .length = 8 * len, + .tx_buffer = tx_data, + .rx_buffer = rx_data, }; - return spi_device_transmit(lcd_spi, &trans); + // 使用轮询传输(小数据量更快) + return spi_device_polling_transmit(spi, &t); +} + +// SPI 写数据 +esp_err_t lcd_spi_write8(uint8_t data) { + // spi_transaction_t trans = { + // .length = 8, // 数据位数 + // .tx_buffer = &data, // 发送缓冲区 + // .rx_buffer = NULL, // 不接收 + // }; + + // return spi_device_transmit(lcd_spi, &trans); + + return spi_transfer_fast(lcd_spi,&data,NULL,1); } // SPI 写数据 @@ -100,15 +122,15 @@ esp_err_t lcd_spi_write16(uint16_t data) { tx_buf[1] = data & 0xFF; tx_buf[0] = (data >> 8) & 0xFF; - spi_transaction_t trans = { - .length = 16, // 数据位数 - .tx_buffer = tx_buf, // 发送缓冲区 - .rx_buffer = NULL, // 不接收 - }; + // spi_transaction_t trans = { + // .length = 16, // 数据位数 + // .tx_buffer = tx_buf, // 发送缓冲区 + // .rx_buffer = NULL, // 不接收 + // }; - - - return spi_device_transmit(lcd_spi, &trans); + // return spi_device_transmit(lcd_spi, &trans); + + return spi_transfer_fast(lcd_spi,tx_buf,NULL,2); } // SPI 写命令 diff --git a/code/demo2/.gitignore b/code/demo2/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/code/demo2/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/code/demo2/.vscode/extensions.json b/code/demo2/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/code/demo2/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/code/demo2/include/README b/code/demo2/include/README new file mode 100644 index 0000000..49819c0 --- /dev/null +++ b/code/demo2/include/README @@ -0,0 +1,37 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the convention is to give header files names that end with `.h'. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/code/demo2/lib/README b/code/demo2/lib/README new file mode 100644 index 0000000..9379397 --- /dev/null +++ b/code/demo2/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into the executable file. + +The source code of each library should be placed in a separate directory +("lib/your_library_name/[Code]"). + +For example, see the structure of the following example libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +Example contents of `src/main.c` using Foo and Bar: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +The PlatformIO Library Dependency Finder will find automatically dependent +libraries by scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/code/demo2/platformio.ini b/code/demo2/platformio.ini new file mode 100644 index 0000000..c8aca15 --- /dev/null +++ b/code/demo2/platformio.ini @@ -0,0 +1,14 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:seeed_xiao_esp32c3] +platform = espressif32 +board = seeed_xiao_esp32c3 +framework = arduino diff --git a/code/demo2/src/lcd.cpp b/code/demo2/src/lcd.cpp new file mode 100644 index 0000000..4aee279 --- /dev/null +++ b/code/demo2/src/lcd.cpp @@ -0,0 +1,241 @@ +#include "lcd.h" +#include + +SPIClass * vspi = NULL; + + + + +/****************************************************************************** + 函数说明:LCD写入命令 + 入口数据:dat 写入的命令 + 返回值: 无 +******************************************************************************/ +void LCD_WR_REG(uint8_t dat) +{ + digitalWrite(LCD_DS,0);//写命令 + vspi->transfer(dat); + digitalWrite(LCD_DS,1);//写数据 +} + +/****************************************************************************** + 函数说明:设置起始和结束地址 + 入口数据:x1,x2 设置列的起始和结束地址 + y1,y2 设置行的起始和结束地址 + 返回值: 无 +******************************************************************************/ +void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2) +{ + +#if USE_HORIZONTAL==0 + LCD_WR_REG(0x2a);//列地址设置 + vspi->transfer16(x1); + vspi->transfer16(x2); + LCD_WR_REG(0x2b);//行地址设置 + vspi->transfer16(y1); + vspi->transfer16(y2); + LCD_WR_REG(0x2c);//储存器写 + #elif USE_HORIZONTAL==1 + LCD_WR_REG(0x2a);//列地址设置 + vspi->transfer16(x1); + vspi->transfer16(x2); + LCD_WR_REG(0x2b);//行地址设置 + vspi->transfer16(y1+80); + vspi->transfer16(y2+80); + LCD_WR_REG(0x2c);//储存器写 + #elif USE_HORIZONTAL==2 + LCD_WR_REG(0x2a);//列地址设置 + vspi->transfer16(x1); + vspi->transfer16(x2); + LCD_WR_REG(0x2b);//行地址设置 + vspi->transfer16(y1); + vspi->transfer16(y2); + LCD_WR_REG(0x2c);//储存器写 + #elif USE_HORIZONTAL==3 + LCD_WR_REG(0x2a);//列地址设置 + vspi->transfer16(x1+80); + vspi->transfer16(x2+80); + LCD_WR_REG(0x2b);//行地址设置 + vspi->transfer16(y1); + vspi->transfer16(y2); + LCD_WR_REG(0x2c);//储存器写 + +#endif + + +} + + +void LCD_fillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) +{ + LCD_Address_Set(x,y,width+x-1,height+y-1); + for(uint16_t i=0;itransfer16(color); + //delay(100); + } + } + +} + + +/****************************************************************************** + 函数说明:LCD清屏函数 + 入口数据:无 + 返回值: 无 +******************************************************************************/ +void LCD_Clear(uint16_t Color) +{ + uint16_t i,j; + LCD_Address_Set(0,0,LCD_W-1,LCD_H-1); + for(i=0;itransfer16(Color); + } + } +} + +void LCD_Clear_Rand() +{ + uint16_t i,j; + LCD_Address_Set(0,0,LCD_W-1,LCD_H-1); + for(i=0;itransfer16(rand()); + } + + } +} + +unsigned int rgb555torgb565(unsigned int c) +{ + c=c&0x7fff; + unsigned int r=c>>10; + c=c&0x03ff; + unsigned int g=c>>5; + c=c&0x001f; + unsigned int b=c; + + unsigned int output=0; + + g=g*2; + output= (r<<11)|(g<<5)|(b); + return output; + +} + +void lcd_init() +{ + + pinMode(LCD_SDA, OUTPUT); + pinMode(LCD_SCL, OUTPUT); + pinMode(LCD_CS, OUTPUT); + pinMode(LCD_DS, OUTPUT); + + digitalWrite(LCD_SDA,0); + digitalWrite(LCD_SCL,0); + digitalWrite(LCD_CS,0); + digitalWrite(LCD_DS,0); + + vspi = new SPIClass(VSPI); + vspi->begin(LCD_SCL, 0, LCD_SDA, LCD_CS); + vspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0)); + pinMode(vspi->pinSS(), OUTPUT); //HSPI SS + + + digitalWrite(vspi->pinSS(), LOW); //pull SS slow to prep other end for transfer + + + + + //************* Start Initial Sequence **********// +//delay(120); +//LCD_WR_REG(0x01); +//上电后硬件会自己复位 +delay(220); +LCD_WR_REG(0x36); +if(USE_HORIZONTAL==0)vspi->transfer(0x00); +else if(USE_HORIZONTAL==1)vspi->transfer(0xC0); +else if(USE_HORIZONTAL==2)vspi->transfer(0x70); +else vspi->transfer(0xA0); + +LCD_WR_REG(0x3A); +vspi->transfer(0x05); + +LCD_WR_REG(0xB2); +vspi->transfer(0x0C); +vspi->transfer(0x0C); +vspi->transfer(0x00); +vspi->transfer(0x33); +vspi->transfer(0x33); + +LCD_WR_REG(0xB7); +vspi->transfer(0x35); + +LCD_WR_REG(0xBB); +vspi->transfer(0x19); + +LCD_WR_REG(0xC0); +vspi->transfer(0x2C); + +LCD_WR_REG(0xC2); +vspi->transfer(0x01); + +LCD_WR_REG(0xC3); +vspi->transfer(0x12); + +LCD_WR_REG(0xC4); +vspi->transfer(0x20); + +LCD_WR_REG(0xC6); +vspi->transfer(0x0F); + +LCD_WR_REG(0xD0); +vspi->transfer(0xA4); +vspi->transfer(0xA1); + +LCD_WR_REG(0xE0); +vspi->transfer(0xD0); +vspi->transfer(0x04); +vspi->transfer(0x0D); +vspi->transfer(0x11); +vspi->transfer(0x13); +vspi->transfer(0x2B); +vspi->transfer(0x3F); +vspi->transfer(0x54); +vspi->transfer(0x4C); +vspi->transfer(0x18); +vspi->transfer(0x0D); +vspi->transfer(0x0B); +vspi->transfer(0x1F); +vspi->transfer(0x23); + +LCD_WR_REG(0xE1); +vspi->transfer(0xD0); +vspi->transfer(0x04); +vspi->transfer(0x0C); +vspi->transfer(0x11); +vspi->transfer(0x13); +vspi->transfer(0x2C); +vspi->transfer(0x3F); +vspi->transfer(0x44); +vspi->transfer(0x51); +vspi->transfer(0x2F); +vspi->transfer(0x1F); +vspi->transfer(0x1F); +vspi->transfer(0x20); +vspi->transfer(0x23); + +LCD_WR_REG(0x21); + +LCD_WR_REG(0x11); +delay(120); + +LCD_WR_REG(0x29); +} diff --git a/code/demo2/src/lcd.h b/code/demo2/src/lcd.h new file mode 100644 index 0000000..7ea7445 --- /dev/null +++ b/code/demo2/src/lcd.h @@ -0,0 +1,33 @@ +#ifndef LCD_H +#define LCD_H + +#include + +//硬件spi貌似接错线了 + +#define LCD_SDA 3 +#define LCD_SCL 2 +#define LCD_CS 7 +#define LCD_DS 6 + + +#define USE_HORIZONTAL 2 //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏 +#define LCD_W 320 +#define LCD_H 240 +#define OLED_CMD 0 //写命令 +#define OLED_DATA 1 //写数据 + +#define VSPI FSPI + + +static const long spiClk = 80000000; // 80 MHz + + +void lcd_init(); + +void LCD_Clear(uint16_t Color); + +void LCD_fillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color); + + +#endif diff --git a/code/demo2/src/main.cpp b/code/demo2/src/main.cpp new file mode 100644 index 0000000..f9db7a8 --- /dev/null +++ b/code/demo2/src/main.cpp @@ -0,0 +1,18 @@ +#include +#include "lcd.h" +// put function declarations here: +int myFunction(int, int); + +void setup() +{ + // put your setup code here, to run once: + lcd_init(); + + LCD_Clear(rand()); +} + +void loop() +{ + // put your main code here, to run repeatedly: + LCD_Clear(rand()); +} diff --git a/code/demo2/test/README b/code/demo2/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/code/demo2/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html