2024年10月3日 星期四

pi zero2w to setup QT5.14

ref:
https://www.waveshare.net/study/article-1042-1.html

2024年我的pi zero 2W裝的是bulleye,但QT官方說QT4只有buster,沒有bulleye

問題,與排除:

1「sudo apt-get build-dep libqt5gui5」會遇到「you need to put some deb-src URIs in your sources.list」錯誤,要你加入apt source

此時,請到「/etc/apt/sources.list」把
「#deb-src http://raspbian.raspberrypi.org/raspbian/ bullseye main contrib non-free rpi」
的「#」拿掉,再用apt-update,才會找到套件

之後,請務必照以下的步驟找到/置放設定檔
-------------------------

下载树莓派的编译配置文件

~ $ git clone https://github.com/oniongarlic/qt-raspberrypi-configuration.git

放到Qt的源代码中。具体为:

common/raspberrypi.conf 放到 /qtbase/mkspecs/common/

linux-rpi2-g++ , linux-rpi3-g++ , linux-rpi-g++ , linux-rpi-vc4-g++ , linux-rpi4-v3d-g++ 这4个文件夹放到 /qtbase/mkspecs/中

------------------上述這過程一定要做,別偷懶!!-------

2.configure的指令要改一下,因為不是用pi4,是用pi zero,所以要小改

(其中build $是路徑,不是指令)
----------------------

build $ PKG_CONFIG_LIBDIR=/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig \

../qt-everywhere-src-5.14.2/configure -platform linux-rpi-g++ \

-D__ARM_ARCH_5TEJ__ \

-v \

-opengl es2 -eglfs \

-no-gtk \

-opensource -confirm-license -release \

-reduce-exports \

-force-pkg-config \

-nomake examples -no-compile-examples \

-skip qtwayland \

-skip qtwebengine \

-no-feature-geoservices_mapboxgl \

-qt-pcre \

-no-pch \

-ssl \

-evdev \

-system-freetype \

-fontconfig \

-glib \

-prefix /opt/Qt5.14 \

-qpa eglfs \

-qt-xcb

----------------------- 

3.make中,遇到錯誤
  cannot find -lGLESv2 
   cannot find -lbrcmGLESv2
解法:請到/home/john/qt-everywhere-src-5.14.2/qtbase/mkspecs/commonqt-everywhere-src-5.14.2/qtbase/mkspecs/common修改「raspberrypi.conf」
-----

QMAKE_LIBS_EGL          = -lbrcmEGL -lbrcmGLESv2

QMAKE_LIBS_OPENVG       = -lbrcmEGL -lbrcmOpenVG -lbrcmGLESv2

QMAKE_LIBS_OPENGL_ES2   = -lbrcmGLESv2 -lbrcmEGL

QMAKE_LIBS_BCM_HOST     = -lbcm_host


EGLFS_DEVICE_INTEGRATION = eglfs_brcm

-----
save後,再去 make

4.再make,再遇到錯誤
----------------------------

qeglfsbrcmintegration.cpp:74:5: error: ‘EGL_DISPMANX_WINDOW_T’ was not declared in this scope

   74 |     EGL_DISPMANX_WINDOW_T *eglWindow = new EGL_DISPMANX_WINDOW_T;

----------------------------
這要改一點地方,先用bulleye xwin之下的檔案總管找「eglplatform.h」
每一個eglplatform.h都加上這個
-----

typedef uint32_t DISPMANX_ELEMENT_HANDLE_T;
typedef struct {
  DISPMANX_ELEMENT_HANDLE_T element;
  int width;   /* This is necessary because dispmanx elements are not queriable. */
  int height;
} EGL_DISPMANX_WINDOW_T;

-----
然後,把這個檔案qeglfsbrcmintegration.cpp  蓋到 /home/john/qt-everywhere-src-5.14.2/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm 裡去
(當然,這還是會有error,所以...也要把「qeglfsbrcmintegration.h」加上上面那些typedef...宣告,才能繼續給他make下去)

------------

/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qeglfsbrcmintegration.h"
#include <bcm_host.h>


QT_BEGIN_NAMESPACE

static DISPMANX_DISPLAY_HANDLE_T dispman_display = 0;

static EGLNativeWindowType createDispmanxLayer(const QPoint &pos, const QSize &size, int z, DISPMANX_FLAGS_ALPHA_T flags)
{
    VC_RECT_T dst_rect;
    dst_rect.x = pos.x();
    dst_rect.y = pos.y();
    dst_rect.width = size.width();
    dst_rect.height = size.height();

    VC_RECT_T src_rect;
    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = size.width() << 16;
    src_rect.height = size.height() << 16;

    DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start(0);

    VC_DISPMANX_ALPHA_T alpha;
    alpha.flags = flags;
    alpha.opacity = 0xFF;
    alpha.mask = 0;

    DISPMANX_ELEMENT_HANDLE_T dispman_element = vc_dispmanx_element_add(
            dispman_update, dispman_display, z, &dst_rect, 0, &src_rect,
            DISPMANX_PROTECTION_NONE, &alpha, (DISPMANX_CLAMP_T *)NULL, (DISPMANX_TRANSFORM_T)0);

    vc_dispmanx_update_submit_sync(dispman_update);

    EGL_DISPMANX_WINDOW_T *eglWindow = new EGL_DISPMANX_WINDOW_T;
    eglWindow->element = dispman_element;
    eglWindow->width = size.width();
    eglWindow->height = size.height();

    return (EGLNativeWindowType)eglWindow;
}

static void destroyDispmanxLayer(EGLNativeWindowType window)
{
    EGL_DISPMANX_WINDOW_T *eglWindow = (EGL_DISPMANX_WINDOW_T*)(window);
    DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start(0);
    vc_dispmanx_element_remove(dispman_update, eglWindow->element);
    vc_dispmanx_update_submit_sync(dispman_update);
    delete eglWindow;
}

void QEglFSBrcmIntegration::platformInit()
{
    bcm_host_init();
}

static int getDisplayId()
{
    // As defined in vc_dispmanx_types.h
    // DISPMANX_ID_MAIN_LCD     0
    // DISPMANX_ID_AUX_LCD      1
    // DISPMANX_ID_HDMI         2
    // DISPMANX_ID_SDTV         3
    // DISPMANX_ID_FORCE_LCD    4
    // DISPMANX_ID_FORCE_TV     5
    // DISPMANX_ID_FORCE_OTHER  6 /* non-default display */
    static const int dispmanxId = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISPMANX_ID");
    return (dispmanxId >= 0 && dispmanxId <= 6) ? dispmanxId : 0;
}

EGLNativeDisplayType QEglFSBrcmIntegration::platformDisplay() const
{
    dispman_display = vc_dispmanx_display_open(getDisplayId());
    return EGL_DEFAULT_DISPLAY;
}

void QEglFSBrcmIntegration::platformDestroy()
{
    vc_dispmanx_display_close(dispman_display);
}

QSize QEglFSBrcmIntegration::screenSize() const
{
    uint32_t width, height;
    graphics_get_display_size(getDisplayId(), &width, &height);
    return QSize(width, height);
}

EGLNativeWindowType QEglFSBrcmIntegration::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format)
{
    Q_UNUSED(window)
    return createDispmanxLayer(QPoint(0, 0), size, 1, format.hasAlpha() ? DISPMANX_FLAGS_ALPHA_FROM_SOURCE : DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS);
}

void QEglFSBrcmIntegration::destroyNativeWindow(EGLNativeWindowType window)
{
    destroyDispmanxLayer(window);
}

bool QEglFSBrcmIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
    switch (cap) {
        case QPlatformIntegration::ThreadedPixmaps:
        case QPlatformIntegration::OpenGL:
        case QPlatformIntegration::ThreadedOpenGL:
        case QPlatformIntegration::BufferQueueingOpenGL:
            return true;
        default:
            return false;
    }
}

QT_END_NAMESPACE
-------------------------------------
之後就沒遇到什麼錯誤(然後花了三天才make 完)
先裝起來,日後試出在他台ubuntu做cross link & 在EGFL模式下跑都正常的話,再來向大家報告

------2024/10/31:颱風天,讀書天--繼續玩我們的QT大法-------
在ubuntu 22.04 做Cross Link的設定,可參考這篇,我測過可用
https://blog.csdn.net/weixin_44658484/article/details/118655494

(在這次的建構中,我是把zero 2W設定為跟pi3一樣等級的板子,
所以configure時, -device是以「-device linux-rasp-pi3-g++」設定的)
惟一要注意的是在configure階段時會遇到類似以下的訊息:
/qfloat16.h:300:7: error: 'numeric_limits' is not a class template
300 | class numeric limits<QT PREPEND_NAMESPACE(qfloat16)> : public numeric limits<float>
這時要在qglobal.h加入<limits>,不是隨便加,要看#if條件加的
----------------
#ifdef __cplusplus
#  include <type_traits>
#  include <cstddef>
#  include <utility>
#  include <limits>
#endif
----------------
,save後,再去configure,就正確了
之後,你會在make階段會遇到「 : error: ‘EGL_DISPMANX_WINDOW_T’ was not declared in this scope 」錯誤
沒錯,就是照之前寫的那樣去改.h & .c 檔,就可以完成make & make install了

(颱風後要去修屋簷了...)



2024年6月25日 星期二

在BBB中安裝TOTOLINK A650UA驅動程式

sudo apt-get install dkms

sudo apt install -y linux-headers-$(uname -r) build-essential bc dkms git libelf-dev rfkill iwsudo apt install -y linux-headers-$(uname -r) build-essential bc dkms git libelf-dev rfkill iw


git clone https://github.com/brektrou/rtl8821CU
cd rtl8821CU
make 
sudo make install
參考
還有這個
(裝完driver記得重開機才會載入driver,用ifconfig才會看到「wlan0」)

2024年4月24日 星期三

在ubuntu啟動.net core webapp https時,遇到「No server certificate was specified, and the default developer certificate could not be found or is out of date.」如何解決

 這個錯誤的全文是這樣的:

-----------------

sudo dotnet 你的DotNetMvcApp.dll
crit: Microsoft.AspNetCore.Server.Kestrel[0]
      Unable to start Kestrel.
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
   at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Load()
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.ValidateOptions()
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
Unhandled exception. System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
   at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Load()
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.ValidateOptions()
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at 你的DotNetMvcApp.Program.Main(String[] args) in P:\你的DotNetMvcApp\你的DotNetMvcApp\Program.cs:line 49
Aborted
-----------------
這時,你可以用這些指令去重新產生並查詢憑證
----
dotnet dev-certs https --clean
dotnet dev-certs https
sudo dotnet dev-certs https --check --verbose
---
參考這個連結
大家一起加油吧

2023年11月29日 星期三

for .net core mvc ,關於json輸出、反序列化一二事

 1.有時系統太自動也不好,像是在json轉換時就是最好的例子了
明明在serverside裡的類別屬性是大寫開頭,結果輸出到json ( 像是在Action裡用「return Json(.....) 」) 去就變成小寫開頭
這就是System.Text.Json的問題了
想整個規避掉就直接在Program.cs裡做點小設定
-------------------------.net 6.0的 program.cs--------------------
 builder.Services.AddControllersWithViews()        
 .AddJsonOptions(options => {
     options.JsonSerializerOptions.PropertyNamingPolicy = null; // This preserves the original case
 });
-------------------------------------------------
(一般都只是「 builder.Services.AddControllersWithViews() ;  」而沒有用到AddJsonOptions)


有json出就有json入,最常用的是系統預設的
System.Text.Json.JsonSerializer.Deserialize<T>(string)」
沒有什麼不好啦,只是厚....如果遇到null轉換就會出錯了
如:
-----------------------
System.Text.Json.JsonException: 'The JSON value could not be converted to System.Nullable`1[System.Decimal]
-----------------------
像上述的錯誤會發生在parsing json string 把null轉成其他型態時會發生錯誤
如何解決?
這時就要請老朋友--NewtonSoft的Json lib相助了
-------------------------------------------
var v = Newtonsoft.Json.JsonConvert.DeserializeObject<Type>(jsonfiledString);
-----------------------------------------
問題就解決了
參考這裡

以上,大家加油吧




2023年10月28日 星期六

informix之.net core EF 套用.

 直接參考這文章做就差不多了
很多人會卡在Scaffold-DbContext這一關
重點是要注意一下PORT ,因為informix EF Core用的是DRDA的port,所以不是之前我們用odbc的(預設)9088而是9089.
如同上述內文說的:Please note: The IBM Data Server providers only works with the Distributed Relational Database Architecture™ (DRDA) protocols, and you therefore need to ensure that your Informix server is configured accordingly.


(這點你要跟你們家的DBA問一下給不給連,也要問網管開不開port,說真的,我也沒把握一次要他們從DEV、UAT到Production這樣一次開這麼多東西給你,所以本單元真的就是自己練功用的)


上述超連結提到的package有點舊了,我實驗的package有update,也都正常
-----------project target framework是.net 6.0------------------



-----------------------------
這是我localhost的scaffold-Dbcontext script,留做我日後小抄用
------------------------------------------------------------- 
Scaffold-DbContext -Connection "user id=informix;server=localhost:9089;database=db_with_log;Password=xxxOOO" -Provider IBM.EntityFrameworkCore -OutputDir Models  -Force -UseDatabaseNames -Tables test_user,test_data

--------------------------------------------
彩蛋一下:
這份PDF不錯,如果你是.net+informix的重度使用者,可以看一下

OS:明明用到的機會渺茫.我還是堅持到底地把它試出來玩了幾番,這也是種職業病吧





2023年10月20日 星期五

拜見老前輩--informix使用記錄(.net 4.5用)

最近因為案子需要,所以接觸到informix

為此在本機(win11)安裝了informix develper version
照理說應該不需要管到informix server的管理,這應該是DBA的工作
不過如果是本機開發測試需要,真的都要自己來

註:以下是為ODBC+.net4.5準備的操作,如果是可以用 .net core開發informix應用的話,請用entity framework core即可,IBM有為.net core發行了相關的EFcore套件.比較不必費心在transaction控管上面.既然上面要求要用.net4.x就老老實實配合就是了

----言歸正傳-----
安裝informix develper server不是問題,我們是用Odbc連線做之後的增刪修查
(因為這樣日後移機會比較好改比較簡單,只要做odbc 設定就好)
雖說「比較簡單」,一點也不簡單
首先來說,你要怎麼測能不能連,當然是用他們自家的工具--ConnectTesst Demo 測比較快

(以上的database下拉可以選才是真的連起來了,有驚嘆號沒選項就是沒連好,仔細看他的訊息,別使戇力猛試)



如果連不上,或是想把上面的host改成ip的話,請到「C:\Program Files\IBM Informix Software Bundle\etc\sqlhosts.ol_informix1410」去改把host pc name改成 ip

--------------------
ol_informix1410 olsoctcp 127.0.0.1 ol_informix1410 
dr_informix1410 drsoctcp 127.0.0.1 dr_informix1410 
lo_informix1410 olsoctcp 127.0.0.1 lo_informix1410 
--------------------
必要時,連「C:\Program Files\IBM Informix Software Bundle\ol_informix1410.cmd」的內容也要改
(連在C:\Windows\System32\drivers\etc\裡的「hosts」也加上本機名稱跟ip對應也再所不惜地改吧)
--------------------

set INFORMIXDIR=C:\PROGRA~1\IBMINF~1
rem set REGMACHINE=\\你的主機名稱    <--先remark起來,以下用ip替代
set REGMACHINE=127.0.0.1
set INFORMIXSERVER=ol_informix1410
set ONCONFIG=onconfig.ol_informix1410
set INFORMIXSQLHOSTS=C:\Program Files\IBM Informix Software Bundle\etc\sqlhosts.ol_informix1410
set GL_USEGLU=1
set PATH=%INFORMIXDIR%\bin;%PATH%
--------------------
這關過了,之後就是ODBC設定了(基本上,「ConnectTest Demo」 能通的話,這也是可以通了)
「可是只能用英文,我要能支援中文的話,可以嗎」

當然可以,而且你也一定不會在內建的「sysxxx」db裡操作(DBA也會把你趕出去的),我們要用別的工具來create db.免驚啦,免錢的哦,他就是鼎鼎大名的DBVisualizer 而且重點不是只有在creeate db而已,是在其連線過程.
一般只會講到這一頁


但是,為了要設定之後的locale,就要用到這一頁了
(注意上面有三個user setting:DB_LOCALE,CLIENT_LOCALE & charSet,一般是沒這三個設定)

這樣後,用DBvisualizer連入informix後,就可以用它來create db了



然後,再回到odbc設定語系,才不會因為語系不同而無法連入
(照理dba會幫你做好db的建置的,但別忘了註明我要中文在地化支援)
看一下中文語系是不是DB的預設語系


這樣你就可以好好享用ODBC + .net操作了
「可是....我怎麼試,transaction總是auto commit,到底要怎樣才能支援transaction?」
「很好,這表示你真的有在玩下去,你可以出山下山了」
想要用.net的OdbcTransaction ,你不只要在odbc那裡把「Auto Commit Optimization」不打勾之外


(以上這點有沒有 check都沒差)
更重要的是.....
在create db時,log mode一定不能選「none」,好歹有個log模式就是了(不知道就用「with log」)


這樣,才會支援交易機制
上述的設定,請參考以下討論
大家加油吧
(忘了跟這次的要角--IBM informix ODBC Driver Setup合影一下,來,笑一個吧)





2023年7月5日 星期三

小試一下,FSMC之於LCD(NT35510),在F103的設定(by Stm32CubeMx)

  雖然用GPIO會比較快,也可以省卻「如果你的chip不支援FSMC...」的問題

不過多學會點會比較好些,也許哪天會用到也不一定,
本篇參考以下兩個URL:這個 & 這個
NT35510的規格書在此

先上圖吧


(別忘了Back Light要On起來,沒有back light,沒有顯示)
先用read ID & color fomat測看看,如果讀出是亂碼,請到上圖的NOR/PSRAME timing for wirte access那裡改一下,有時要多點clock才會正確 (參考上面兩個URL的內文介紹如個推算,因為我是用NT35510的,所以會以第二個link為主)

程式碼如下
---------------------------------------------------
//因為是用base1 第 4區,所以base address是0x6C000000
 (即0x60000000~0x6FFFFFFF分成區,第四區起始位址即為0x6C000000,參考「STM32F103 战舰开发指南V1.1.pdf」P365)
#define FMC_ADDR_CMD  ((uint32_t) 0x6C000000)
//而A10做為C/D(或曰register select),又要往左shfit一位,故為00800
#define FMC_ADDR_DATA  ((uint32_t) 0x6C000800)
//在 MX_FSMC_Init();後,這些對應建立起來後,就可以直接用位址的方式讀寫,不必再用8080介面操作了...
void lcd_wr_cmd(volatile uint16_t cmd)
{
    cmd = cmd;
    *(uint16_t *)(FMC_ADDR_CMD) = cmd;
}
void lcd_wr_data(volatile uint16_t data)
{
     data = data;
*(uint16_t *)(FMC_ADDR_DATA) = data;
}
uint16_t lcd_rd_data(void)
{
volatile uint16_t ram; 
ram = *(uint16_t *)(FMC_ADDR_DATA);
return ram;
}
...
...
main的內容
    HAL_Init();
   MX_FSMC_Init();
   MX_USART1_UART_Init();
 //神說,要有光,於是就有了光
 HAL_GPIO_WritePin(LCD_BL_GPIO_Port,LCD_BL_Pin,GPIO_PIN_SET);
  HAL_Delay(10);
  lcd_wr_cmd(0x1100);    //Sleep out & booster on 
  HAL_Delay(10);
  lcd_wr_cmd(0x2900);   //display memory  to frame.
  HAL_Delay(10);
  //第一步,先試著讀id,如果傳回值不是80h的話,就是錯了
  lcd_wr_cmd(0x0401);
  HAL_Delay(100);
  uint16_t chip_id=0xabcd;
  chip_id=lcd_rd_data();
  
  //試著讀寫 color format,原先是8x8x8 RBG格式,如今我們為了測試,用565格式
  //0x0C00是read color mode,而0x3A00是write color mode.
  uint16_t pix_fomrat_org=0;
  lcd_wr_cmd(0x0c00);pix_fomrat_org=lcd_rd_data();
  lcd_wr_cmd(0x3A00); lcd_wr_data(0x55);
  lcd_wr_cmd(0x0c00);
  uint16_t pix_fomrat=lcd_rd_data();
   //清除資料一下 (預設尺寸是480*800)
  lcd_wr_cmd(0x2c00);; //demo how to do "clear screen"
  for(uint32_t i=0;i<(0x01df-1)*(0x03ef-1);i++){
      lcd_wr_data(0x07E0);
  }
  
  //最後,把大頭照放上去 x,y : 200,200, width& height:140x140
  lcd_wr_cmd(0x2A00);lcd_wr_data(0);;
  lcd_wr_cmd(0x2A01);lcd_wr_data(200);
  lcd_wr_cmd(0x2A02);lcd_wr_data(339>>8);
  lcd_wr_cmd(0x2A03);lcd_wr_data(339&0xff);
  
  lcd_wr_cmd(0x2B00);lcd_wr_data(0);
  lcd_wr_cmd(0x2B01);lcd_wr_data(200);
  lcd_wr_cmd(0x2B02);lcd_wr_data(339>>8);
  lcd_wr_cmd(0x2B03);lcd_wr_data(339&0xff);  
  lcd_wr_cmd(0x2c00); //demo how to do "clear screen"
  for(uint32_t i=0;i<(140*140);i++){
      lcd_wr_data(g_pexl[i]);
  }
  
 //然後就是while(1)...

---------------------------------------------------
 耶~ 有看到圖片了(會不會太自戀了?)
------




------
這次的實作基本上只是個小插曲,還是建議用GPIO直接去操作,以清除螢幕這個函數來說好了
-----------
void fill_color(uint16_t color, uint32_t count)

   //當然以下的HAL_GPIO_WritePin都可以再直接操作BSRR暫存器來最佳化之,
  //只是為了實作驗證是否了解正確,直接用HAL程式庫了
    set_d0tod7_output();
    HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_RESET);//RS:0
    HAL_GPIO_WritePin(LCD_WRITE_GPIO_Port,LCD_WRITE_Pin,GPIO_PIN_SET);//write 1
    HAL_GPIO_WritePin(LCD_READ_GPIO_Port,LCD_READ_Pin,GPIO_PIN_SET);//RD 1
    HAL_GPIO_WritePin(LCD_CS_GPIO_Port,LCD_CS_Pin,GPIO_PIN_RESET);//CS 0
    
    write_byte_to_gpio(0x2c00);
    HAL_GPIO_WritePin(LCD_WRITE_GPIO_Port,LCD_WRITE_Pin,GPIO_PIN_RESET);//write 0
    HAL_GPIO_WritePin(LCD_WRITE_GPIO_Port,LCD_WRITE_Pin,GPIO_PIN_SET);//write 1
    
    //set to data mode
    HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_SET);//RS:1
    write_byte_to_gpio(color);
    uint32_t pin16u=(uint32_t)LCD_WRITE_Pin<< 16u;
    for(uint32_t i=0;i<count;i++)
    {
         LCD_WRITE_GPIO_Port->BSRR = pin16u; //RESET
         LCD_WRITE_GPIO_Port->BSRR = LCD_WRITE_Pin;//SET
     }
    //all done
    HAL_GPIO_WritePin(LCD_CS_GPIO_Port,LCD_CS_Pin,GPIO_PIN_SET);//CS 1
    HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_SET);//RS:1
    HAL_GPIO_WritePin(LCD_READ_GPIO_Port,LCD_READ_Pin,GPIO_PIN_SET);//read 1
    HAL_GPIO_WritePin(LCD_WRITE_GPIO_Port,LCD_WRITE_Pin,GPIO_PIN_SET);//write 1
}
-----------
這比填入FSMC再填入LCD快了點(直接高低電位切換,當然快啊,這樣比很不講武德捏)
而且會看技術規格文件,是這行必備的生存技能
當然FSMC會了也是很好的一件事,畢竟很多時候可以對應到別的設備的,大大節省開發難度
要學的東西真的太多了,一起加油吧.