--- url: "/about/\U0001F4C7站点日志.md" --- # 📇站点日志 *** ::: timeline **2026-02-13** * 改用 [Vitepress Theme Teek](https://vp.teek.top/guide/intro.html)主题 ::: ::: timeline **2026-01-08** * 改用[docsearch](https://ecosystem.vuejs.press/zh/plugins/search/docsearch.html#usage)搜索 ::: ::: timeline **2025-12-26** * 改用[vuepress-theme-hope](https://theme-hope.vuejs.press/zh/)主题 ::: ::: timeline **2023-06-25** * 引入 [vitepress-plugin-mermaid](https://github.com/emersonbottero/vitepress-plugin-mermaid) 添加对 [mermaid](https://mermaid.js.org/intro/n00b-syntaxReference.html) 语法的支持 * 引入 [自定义mermaid的vue插件](https://hez2z.github.io/2025/09/19/vitepress-mermaid/) 代替原有的[vitepress-plugin-mermaid](https://github.com/emersonbottero/vitepress-plugin-mermaid) 插件(这个插件只支持 `vitepress-1.0`,当前已经升级到`vitepress-2.0`了) ::: ::: timeline **2023-06-09** * 添加 [本地搜索](https://vitepress.dev/reference/default-theme-search) 功能 ::: ::: timeline **2023-06-08** * 使用shell脚本实现文章内容的 [统计](../pages/📦归档.md) * 使用shell脚本实现自动生成 [目录](../list-concept/1.md) 列表 ::: ::: timeline **2023-05-29** * 引入 [vitepress-markdown-timeline](https://www.npmjs.com/package/vitepress-markdown-timeline?activeTab=readme) 渲染时间轴页面 ::: ::: timeline **2023-05-26** * [用github\_action自动部署vitepress项目](../pages_old/用github_action自动部署vitepress项目.md) * 使用 [vitepress-auto-configure-nav-sidebar](https://github.com/w3ctech-editorial-department/vitepress-auto-configure-nav-sidebar) 插件实现自动生成侧边栏、导航栏 * 由 [VitePress](https://vitepress.dev/guide/what-is-vitepress) 驱动,基于 [markdown](https://markdown.com.cn/basic-syntax/) 文档建站 ::: --- --- url: /posts/batch脚本后台静默执行.md --- # batch脚本后台自动静默执行 通过任务计划程序实现,定时重复执行batch脚本 ## 流程 创建**基本任务**,配置如下 程序 ```shell cmd ``` 添加参数 ```shell \c "C:\Users\Shelton\Workspaces\code\my-blog\deploy.bat" ``` 起始于 ```shell C:\Users\Shelton\Workspaces\code\my-blog ``` 如图 ![](../public/images/Pasted%20image%2020260104122359.png) --- --- url: /posts/Clash Verge配置.md --- # Clash Verge配置 ## 订阅源 ```yml https://gh.llkk.cc/https://raw.githubusercontent.com/chengaopan/AutoMergePublicNodes/master/list.meta.yml ``` ```yml https://gh.llkk.cc/https://raw.githubusercontent.com/a2470982985/getNode/main/clash.yaml ``` ## 全局扩展脚本 ```yml // 国内DNS服务器 const domesticNameservers = [ "https://dns.alidns.com/dns-query", // 阿里云公共DNS "https://doh.pub/dns-query", // 腾讯DNSPod "https://doh.360.cn/dns-query" // 360安全DNS ]; // 国外DNS服务器 const foreignNameservers = [ "https://1.1.1.1/dns-query", // Cloudflare(主) "https://1.0.0.1/dns-query", // Cloudflare(备) "https://208.67.222.222/dns-query", // OpenDNS(主) "https://208.67.220.220/dns-query", // OpenDNS(备) "https://194.242.2.2/dns-query", // Mullvad(主) "https://194.242.2.3/dns-query" // Mullvad(备) ]; // DNS配置 const dnsConfig = { "enable": true, "listen": "0.0.0.0:1053", "ipv6": true, "use-system-hosts": false, "cache-algorithm": "arc", "enhanced-mode": "fake-ip", "fake-ip-range": "198.18.0.1/16", "fake-ip-filter": [ // 本地主机/设备 "+.lan", "+.local", // Windows网络出现小地球图标 "+.msftconnecttest.com", "+.msftncsi.com", // QQ快速登录检测失败 "localhost.ptlogin2.qq.com", "localhost.sec.qq.com", // 微信快速登录检测失败 "localhost.work.weixin.qq.com" ], "default-nameserver": ["223.5.5.5", "119.29.29.29", "1.1.1.1", "8.8.8.8"], "nameserver": [...domesticNameservers, ...foreignNameservers], "proxy-server-nameserver": [...domesticNameservers, ...foreignNameservers], "nameserver-policy": { "geosite:private,cn,geolocation-cn": domesticNameservers, "geosite:google,youtube,telegram,gfw,geolocation-!cn": foreignNameservers } }; // 规则集通用配置 const ruleProviderCommon = { "type": "http", "format": "yaml", "interval": 86400 }; // 规则集配置 const ruleProviders = { "reject": { ...ruleProviderCommon, "behavior": "domain", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/reject.txt", "path": "./ruleset/loyalsoldier/reject.yaml" }, "icloud": { ...ruleProviderCommon, "behavior": "domain", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/icloud.txt", "path": "./ruleset/loyalsoldier/icloud.yaml" }, "apple": { ...ruleProviderCommon, "behavior": "domain", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/apple.txt", "path": "./ruleset/loyalsoldier/apple.yaml" }, "google": { ...ruleProviderCommon, "behavior": "domain", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/google.txt", "path": "./ruleset/loyalsoldier/google.yaml" }, "proxy": { ...ruleProviderCommon, "behavior": "domain", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/proxy.txt", "path": "./ruleset/loyalsoldier/proxy.yaml" }, "direct": { ...ruleProviderCommon, "behavior": "domain", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/direct.txt", "path": "./ruleset/loyalsoldier/direct.yaml" }, "private": { ...ruleProviderCommon, "behavior": "domain", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/private.txt", "path": "./ruleset/loyalsoldier/private.yaml" }, "gfw": { ...ruleProviderCommon, "behavior": "domain", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/gfw.txt", "path": "./ruleset/loyalsoldier/gfw.yaml" }, "tld-not-cn": { ...ruleProviderCommon, "behavior": "domain", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/tld-not-cn.txt", "path": "./ruleset/loyalsoldier/tld-not-cn.yaml" }, "telegramcidr": { ...ruleProviderCommon, "behavior": "ipcidr", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/telegramcidr.txt", "path": "./ruleset/loyalsoldier/telegramcidr.yaml" }, "cncidr": { ...ruleProviderCommon, "behavior": "ipcidr", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/cncidr.txt", "path": "./ruleset/loyalsoldier/cncidr.yaml" }, "lancidr": { ...ruleProviderCommon, "behavior": "ipcidr", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/lancidr.txt", "path": "./ruleset/loyalsoldier/lancidr.yaml" }, "applications": { ...ruleProviderCommon, "behavior": "classical", "url": "https://fastly.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/applications.txt", "path": "./ruleset/loyalsoldier/applications.yaml" }, "openai": { ...ruleProviderCommon, "behavior": "classical", "url": "https://fastly.jsdelivr.net/gh/blackmatrix7/ios_rule_script@master/rule/Clash/OpenAI/OpenAI.yaml", "path": "./ruleset/blackmatrix7/openai.yaml" } }; // 规则 const rules = [ // 自定义规则 //"PROCESS-NAME,masterduel.exe,DIRECT", // 决斗大师 //"DOMAIN-SUFFIX,ayk-web.mo.konami.net,节点选择", // 决斗大师 "DOMAIN-SUFFIX,vercel.com,节点选择", // vercel "DOMAIN-SUFFIX,chatgpt.com,节点选择", // chatgpt "DOMAIN-SUFFIX,microsoft.com,DIRECT", // MS "DOMAIN-SUFFIX,zxd.bar,DIRECT", // Nas "DOMAIN-SUFFIX,cn.bing.com,DIRECT", // 中国版bing // "DOMAIN-SUFFIX,edclub.com,节点选择", // typeclub "DOMAIN-SUFFIX,typingclub.com,节点选择", // typeclub /////////////////////// "DOMAIN-SUFFIX,googleapis.cn,节点选择", // Google服务 "DOMAIN-SUFFIX,gstatic.com,节点选择", // Google静态资源 "DOMAIN-SUFFIX,xn--ngstr-lra8j.com,节点选择", // Google Play下载服务 "DOMAIN-SUFFIX,github.com,节点选择", // github "DOMAIN-SUFFIX,github.io,节点选择", // Github Pages "DOMAIN,v2rayse.com,节点选择", // V2rayse节点工具 // blackmatrix7 规则集 "RULE-SET,openai,节点选择", // Loyalsoldier 规则集 "RULE-SET,applications,DIRECT", "RULE-SET,private,DIRECT", "RULE-SET,reject,REJECT", "RULE-SET,icloud,节点选择", "RULE-SET,apple,节点选择", "RULE-SET,google,节点选择", "RULE-SET,proxy,节点选择", "RULE-SET,gfw,节点选择", "RULE-SET,tld-not-cn,节点选择", "RULE-SET,direct,DIRECT", "RULE-SET,lancidr,DIRECT,no-resolve", // 局域网 IP 及保留 IP 地址列表 "RULE-SET,cncidr,DIRECT,no-resolve", // 中国大陆 IP 地址列表 "RULE-SET,telegramcidr,节点选择,no-resolve", // 其他规则 "GEOIP,LAN,DIRECT,no-resolve", "GEOIP,CN,DIRECT,no-resolve", "MATCH,steam" ]; // 代理组通用配置 const groupBaseOption = { "interval": 300, "timeout": 3000, "url": "https://www.google.com/generate_204", "lazy": true, "max-failed-times": 3, "hidden": false }; // 程序入口 function main(config) { const proxyCount = config?.proxies?.length ?? 0; const proxyProviderCount = typeof config?.["proxy-providers"] === "object" ? Object.keys(config["proxy-providers"]).length : 0; if (proxyCount === 0 && proxyProviderCount === 0) { throw new Error("配置文件中未找到任何代理"); } // 覆盖原配置中DNS配置 config["dns"] = dnsConfig; // 覆盖原配置中的代理组 config["proxy-groups"] = [ { ...groupBaseOption, "name": "节点选择", "type": "select", "proxies": ["DIRECT", "延迟选优"], "include-all": true, "icon": "https://fastly.jsdelivr.net/gh/clash-verge-rev/clash-verge-rev.github.io@main/docs/assets/icons/adjust.svg" }, { ...groupBaseOption, "name": "延迟选优", "type": "url-test", "tolerance": 400, "include-all": true, "icon": "https://fastly.jsdelivr.net/gh/clash-verge-rev/clash-verge-rev.github.io@main/docs/assets/icons/speed.svg" }, { ...groupBaseOption, "name": "steam", "type": "select", "proxies": ["节点选择","DIRECT"], "icon": "https://fastly.jsdelivr.net/gh/clash-verge-rev/clash-verge-rev.github.io@main/docs/assets/icons/steam.svg" }, ]; // 覆盖原配置中的规则 config["rule-providers"] = ruleProviders; config["rules"] = rules; // 返回修改后的配置 return config; } ``` --- --- url: /posts/claude code desktop接入第三方api.md --- # claude code desktop接入第三方api ## 效果 用 `claude code` 写一个贪吃蛇页游 ![](../public/images/Pasted%20image%2020260602015323.png) ## 背景 公司提供了 阿里百炼的token 使用,研究了一下如何使用,最初是通过 `claude code for vscode` 的插件实现在 vscode 中使用,但实际上体验不如 `copolit`,于是便想使用完全体的 `claude code desktop` ## 思路 主要是 1. 开启claude code desktop的 `develop mode` 启用第三方api 2. 通过`cc switch` 管理第三方api,转发路由给 `claude code` 使用 ## 操作 ### cc switch 配置 > [下载地址](https://ccswitch.io/zh/) 选中 `claude code desktop` 添加 阿里百炼 `api` ![](../public/images/Pasted%20image%2020260602012847.png) 配置如下(我的api是百炼团队版的) ![](../public/images/Pasted%20image%2020260602012818.png) 启用 `claude` 的路由转发 ![](../public/images/Pasted%20image%2020260602013013.png) 至此 `cc switch` 相关配置已完成 ### claude code desktop 配置 > [下载地址](https://claude.com/download) 参考[百炼文档](https://help.aliyun.com/zh/model-studio/claude-code?spm=a2c4g.11186623.help-menu-2400256.d_0_4_2.39083ba2Uds2xd#ccswitch-desktop-section) ![](../public/images/Pasted%20image%2020260602013550.png) 配置如下 ![](../public/images/Pasted%20image%2020260602013753.png) 配置完应用更改,重启即可使用了 ### claude code desktop 汉化 最后做一个 `claude code desktop` 的汉化,使用开源项目 [javaht/claude-desktop-zh-cn: Claude Desktop Chinese Patch (macOS & Windows)](https://github.com/javaht/claude-desktop-zh-cn) 选择第 `1` 种汉化方式即可 ![](../public/images/Pasted%20image%2020260602012647.png) --- --- url: /posts/c和c++混合编程.md --- # c和c++混合编程 ## 头文件 ```c #ifndef __INT_LCD1602_H__ #define __INT_LCD1602_H__ #include "../Com/Com_Util.h" // 关键:告诉 C++ 编译器,这些函数是 C 语言实现的 #ifdef __cplusplus extern "C" { #endif void Int_LCD_Init(); void Int_LCD_Clear(); void Int_LCD_ShowChar(u8 line, u8 pos, u8 ch); void Int_LCD_ShowString(u8 line, u8 pos, u8 str[]); void Int_LCD_ShowNum(u8 line, u8 pos, int num, u8 digit); void Int_LCD_ShowSignedNum(u8 line, u8 pos, int num, u8 digit); void Int_LCD_ShowHexNum(u8 line, u8 pos, int num, u8 digit); void Int_LCD_ShowBinNum(u8 line, u8 pos, int num, u8 digit); // 结束 C 链接声明 #ifdef __cplusplus } #endif #endif // __INT_LCD1602_H__ ``` --- --- url: /posts/esp32_蓝牙ble通信.md --- # esp32\_蓝牙ble通信 ## 效果 ![](/assets/Screenshot_20260329_170217.CwOTwDzL.png) ## 原理 ### ble通信步骤 ![](../public/images/Pasted%20image%2020260329154651.png) 1. 创建蓝牙Ble服务 ```cpp #include #include "arduino.h" // 初始化BLE设备,设置设备名称 BLEDevice::init("ESP32-BLE"); p_server = BLEDevice::createServer(); // 创建服务 p_service = p_server->createService(SERVICE_UUID); // 服务回调 p_server->setCallbacks(new MyServerCallbacks()); // 设置回调断连时再次打开蓝牙 ``` 服务回调 ```cpp class MyServerCallbacks : public BLEServerCallbacks { void onConnect(BLEServer* pServer) { Serial.println("Client connected"); } void onDisconnect(BLEServer* pServer) { Serial.println("Client disconnected, restarting advertising"); p_advertising->start(); // 断开连接后重新开始广播 } }; ``` 2. 创建特征 * 设置特征描述符 * 设置特征值 ```cpp // 创建特征 p_characteristic = p_service->createCharacteristic( CHARACTERISTIC_UUID, // UUID BLECharacteristic::PROPERTY_READ // 读取描述符 | BLECharacteristic::PROPERTY_WRITE // 写入描述符 | BLECharacteristic::PROPERTY_NOTIFY // 通知描述符 ); // p_characteristic->setValue("Hello BLE"); // 设置特征值 p_characteristic->setCallbacks(new MyCharacteristicCallbacks()); // 设置读取回调 p_characteristic->addDescriptor(new BLE2902()); // 添加客户端配置描述符,允许通知和指示 p_service->start(); // 启动服务 ``` 蓝牙主动通知读取 ```cpp if (p_server->getConnectedCount() > 0) { static unsigned long lastSendMillis = 0; if (millis() - lastSendMillis >= 1000) { // 每秒通知一次,避免过于频繁 p_characteristic->setValue(time_str); // 获取当前显示数据并设置为特征值 p_characteristic->notify(); lastSendMillis = millis(); } } ``` 读取回调 ```cpp // 纯虚函数不能直接new,需要实现接口类 class MyCharacteristicCallbacks : public BLECharacteristicCallbacks { void onWrite(BLECharacteristic* pCharacteristic) { std::string value = pCharacteristic->getValue(); Serial.print("Received value: "); Serial.println(value.c_str()); } }; ``` 3. 创建广播 ```cpp // 启动广播 p_advertising = BLEDevice::getAdvertising(); // 获取广告对象 p_advertising->addServiceUUID(SERVICE_UUID); // 广播服务UUID p_advertising->setScanResponse(true); // 设置扫描响应 p_advertising->start(); ``` ## 参考资料 [ESP32低功耗蓝牙BLE教学\_哔哩哔哩\_bilibili](https://www.bilibili.com/video/BV1kgsPzbEuD/?spm_id_from=333.788.top_right_bar_window_history.content.click\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) --- --- url: /posts/esp32rev1原理图.md --- # esp32rev1原理图 ![](../public/images/Pasted%20image%2020260308014316.png) --- --- url: /posts/esp32rev1驱动墨水屏.md --- # esp32rev1驱动墨水屏 ## 引脚图 * VCC ---> 3V * GND ---> GND * RST ---> D16 * DC ---> D17\`\` * Busy ---> D4 * SPI * CS ---> 5 * SCK ---> 18 * SDA ---> 23 ## 参考资料 * [esp32驱动4.2寸三色墨水屏](esp32驱动4.2寸三色墨水屏.md) * [JADE-Jerry/jcalendar: Ink Screen Calendar](https://github.com/JADE-Jerry/jcalendar) --- --- url: /posts/esp32使用u8g2字库在墨水屏显示中文.md --- # esp32使用u8g2字库在墨水屏显示中文 使用 epd2 驱动的屏幕,因此可以使用 u8g2 中文字库来显示中文 ## 操作步骤 安装 `U8g2_for_Adafruit_GFX` 插件 ![](../public/images/Pasted%20image%2020260223220401.png) ```cpp #include #include // 选择水墨屏的驱动,根据水墨屏型号选择 GxEPD2_3C < GxEPD2_750c_Z08, GxEPD2_750c_Z08::HEIGHT / 4 > display(GxEPD2_750c_Z08(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4)); // GDEW075Z08 800x480, GD7965 U8G2_FOR_ADAFRUIT_GFX u8g2Fonts; // 导入字体 void setup() { display.init(115200); // 初始化屏幕 display.setRotation(3); // 设置屏幕旋转方向,分别有0,1,2,3这四个方向 u8g2Fonts.begin(display); display.setTextWrap(false); // 设置文本是否自动换行,false则为不自动换行,如果文本溢出则显示异常或者不显示 u8g2Fonts.setFontDirection(0); // 设置文字显示方向 u8g2Fonts.setForegroundColor(GxEPD_BLACK); // 设置前景色 u8g2Fonts.setBackgroundColor(GxEPD_WHITE); // 设置背景色 u8g2Fonts.setFont(u8g2_font_wqy14_t_chinese3); // 设置文本字体 display.setTextColor(GxEPD_BLACK); // 设置文本颜色 display.setFullWindow(); // 设置全屏刷新,与之相对的是局部刷新 display.firstPage(); // 显示开始 // 通常来说,所有的显示都放在do while 循环中完成。 // 主要原因是 水墨屏使用循环刷新,一次循环可能不会刷新所有显示内容 do { u8g2Fonts.setCursor(10, 50); // 设置显示坐标 x=10, y=50 String content = "中文显示测试"; u8g2Fonts.println(content); // 显示文本 } while (display.nextPage()); // 显示结束 } ``` ## 参考资料 * [esp8266 水墨屏显示中文之简单字库 - 金色旭光 - 博客园](https://www.cnblogs.com/goldsunshine/p/17403341.html) --- --- url: /posts/esp32驱动4.2寸三色墨水屏.md --- # esp32驱动4.2寸三色墨水屏 ``` # esp32驱动4.2寸三色墨水屏 ``` ## 演示 ![](../public/images/Pasted%20image%2020260221143127.png) ## 实践 ### 引脚 * GND ---> G * 3.3V ---> 3v * RES ---> **D4** ---> GPIO4 * BUSY ---> **D16** ---> GPIO16 * DC ---> **D2** ---> GPIO2 * SPI * SCL ---> **D18** ---> GPIO18·························· * SDI ---> **D23** ---> GPIO23 (MOSI) * CS ---> **D5** ---> GPIO5 ![](../public/images/Pasted%20image%2020260220125303.png) ### 驱动屏幕 #### 通过 `GxEPD2` 库驱动 ```cpp GxEPD2_3C display(GxEPD2_420c_GDEY042Z98(/*CS=5*/ 5, /*DC=*/ 2, /*RST=*/ 4, /*BUSY=*/ 19)); ``` #### 通过 `waveshare` 库驱动 [E-Paper ESP32 Driver Board - Waveshare Wiki](https://www.waveshare.net/wiki/E-Paper_ESP32_Driver_Board#.E6.96.87.E6.A1.A3) ### 参考资料 * [esp8266驱动4.2寸三色墨水屏](esp8266驱动4.2寸三色墨水屏.md) * [esp32rev1驱动墨水屏](esp32rev1驱动墨水屏.md) --- --- url: /posts/esp8266驱动4.2寸三色墨水屏.md --- # esp8266驱动4.2寸三色墨水屏 ## 演示 ![](../public/images/Pasted%20image%2020260221134128.png) ## 实践 ### 创建项目 ![](../public/images/Pasted%20image%2020260221135332.png) ### 引脚 > esp8266 的引脚和实际的GPIO不一致,因此要参考原理图 * GND ---> G * 3.3V ---> 3v * RES ---> **D4** ---> GPIO2 * BUSY ---> **D1** ---> GPIO5 * DC ---> **D2** ---> GPIO4 * SPI * SCL ---> **D5** ---> GPIO14 * SDI ---> **D7** ---> GPIO13 (MOSI) * CS ---> **D8** ---> GPIO15 ![](../public/images/Pasted%20image%2020260221134856.png) ### 驱动板 由于是纯数字电路,只要是24pin的转接板都可以,A模式就可以点亮。 ![](../public/images/Pasted%20image%2020260221141826.png) ### 代码 基于 `Arduino` 的 `GxEPD2` 库的示例修改 ![](../public/images/Pasted%20image%2020260221133917.png) ```cpp #define ENABLE_GxEPD2_GFX 1 #if ARDUINO >= 100 #include #else #include #endif #include #include #include #include #include #if defined(ESP32) //**** 注意1、2.9寸黑白屏初始化,注意修改相应的引脚,我这里是ESP32的,你改成自己的就可以了 // ESP32主控接法: // SS(CS)=5 MOSI(SDA)=23 MISO(不接)=19 SCK=18 DC=17 RST=16 BUSY=19 // 2.9寸屏 // GxEPD2_BW display(GxEPD2_290_T94_V2(/*CS=5*/ 5, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 19)); // 2.13寸屏 // GxEPD2_BW display(GxEPD2_213_B72(/*CS=5*/ 5, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 19)); // 1.54寸屏 // GxEPD2_BW display(GxEPD2_154_T8(/*CS=5*/ 5, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 19)); // ESP32C3主控接法: // SS(CS)=7 MOSI(SDA)=6 MISO(不接)=5 SCK=4 DC=3 RST=2 BUSY=10 // 2.9寸屏 // GxEPD2_BW display(GxEPD2_290_T94_V2(/*CS=5*/ 7, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 10)); // 2.13寸屏 GxEPD2_BW display(GxEPD2_213_B72(/*CS=5*/ 7, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 10)); // 1.54寸屏 // GxEPD2_BW display(GxEPD2_154_T8(/*CS=5*/ 7, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 10)); // ESP32S3主控接法: // SS(CS)=10 MOSI(SDA)=11 MISO(不接)=13 SCK=12 DC=8 RST=7 BUSY=9 // 2.9寸屏 // GxEPD2_BW display(GxEPD2_290_T94_V2(/*CS=5*/ 10, /*DC=*/ 8, /*RST=*/ 7, /*BUSY=*/ 9)); // 2.13寸屏 // GxEPD2_BW display(GxEPD2_213_B72(/*CS=5*/ 10, /*DC=*/ 8, /*RST=*/ 7, /*BUSY=*/ 9)); // 1.54寸屏 // GxEPD2_BW display(GxEPD2_154_T8(/*CS=5*/ 10, /*DC=*/ 8, /*RST=*/ 7, /*BUSY=*/ 9)); #else // ESP8266 模块接法: // SS(CS)=15 MOSI(SDA)=13 MISO=12 SCK(SCLK)=14 DC=4 RST=2 BUSY=5 // ESP8266开发板对应引脚: // CS=D8 SDA=D7 SCK=D5 DC=D2 RST=D4 BUSY=D1 // 4.2寸屏 GxEPD2_3C display(GxEPD2_420c_GDEY042Z98(/*CS=5*/ 15, /*DC=*/ 4, /*RST=*/ 2, /*BUSY=*/ 5)); #endif #if defined(ESP32) #include "bitmaps/Bitmaps1304x984.h" // 12.48" b/w #else // 3-color #include "bitmaps/Bitmaps3c400x300.h" // 4.2" 3-color b/w/r #endif ``` ## 参考资料 * [GxEPD2\_WS\_ESP32\_Driver - 搜索](https://cn.bing.com/search?q=GxEPD2_WS_ESP32_Driver\&cvid=b9d7aaf01ec2476f8fd179af1a784f11\&gs_lcrp=EgRlZGdlKgYIABBFGDkyBggAEEUYOTIGCAEQABhAMgYIAhAAGEAyBggDEAAYQDIGCAQQABhAMgYIBRAAGEAyBggGEAAYQDIGCAcQABhAMgcICBDrBxhA0gEHNDM2ajBqMagCALACAA\&FORM=ANAB01\&PC=U531) * [一起学习墨水屏驱动方法\_哔哩哔哩\_bilibili](https://www.bilibili.com/video/BV1ZWwdeSExg?spm_id_from=333.788.videopod.sections\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) --- --- url: /posts/fusion360-创建工程.md --- # fusion360-创建工程 ## 创建与导出 由于fusion360是在线存储的,所以保存本地的话需要使用导出f3d格式,打开的时候选择导入 ![](../public/images/Pasted%20image%2020260217140427.png) --- --- url: /posts/fusion360-绘制实体.md --- # fusion360-绘制实体 ## 绘制 绘制实体本质就是基于一个平面,绘制另外两个平面 ### 构造平面 可以创建xyz以外的一个基础平面,用于绘制草图,比如两个平面的中间点平面 ![](../public/images/Pasted%20image%2020260217141022.png) ### 平面命令 #### 曲面 ![](../public/images/Pasted%20image%2020260211132305.png) #### 扫掠 本质就是一个平面+另一个平面的中心轴 ![](../public/images/Pasted%20image%2020260211135013.png) ## 放样 放样可以用光滑曲面连接**在同一轴的不同平面** ![](../public/images/Pasted%20image%2020260211171807.png) ## 检查 检验 ---> 截面分析 ![](../public/images/Pasted%20image%2020260211141534.png) ## 练习 ### 牟合方盖 拉伸圆,相交 ![](../public/images/Pasted%20image%2020260211172944.png) ![](../public/images/Pasted%20image%2020260211172925.png) ### 微型带轮 ![](../public/images/Pasted%20image%2020260211173157.png) ![](../public/images/Pasted%20image%2020260217141547.png) ### 零件 ![](../public/images/Pasted%20image%2020260217111709.png) ![](../public/images/Pasted%20image%2020260217135130.png) --- --- url: /posts/fusion360-绘制草图.md --- # fusion360-绘制草图 ## 创建草图 点击创建草图,选择平面后就可以绘制草图了 ![](../public/images/Pasted%20image%2020260217140311.png) 通过**约束**、**对称**和**钣金**可以快速绘制草图的比例 修建命令可以删除多余线条 ![](../public/images/Pasted%20image%2020260217140714.png) ## 练习 ![](../public/images/Pasted%20image%2020260210125431.png) ![](../public/images/Pasted%20image%2020260210131255.png) ![](../public/images/Pasted%20image%2020260210133949.png) ![](../public/images/Pasted%20image%2020260210143648.png) --- --- url: /posts/Github-Action自动更新免费的clash-node.md --- # Github-Action自动更新免费的clash-node ```yaml title=".github/workflows/main.yml" name: Update Clash.yaml # 工作流名称 on: # push: # 推送代码时触发工作流 workflow_dispatch: # 手动触发工作流 schedule: #UTC+8 转换成 UTC时间 - cron: '0 0 * * *' # 每天 08:00 (中国时间) - cron: '30 6 * * *' # 每天 14:30 (中国时间) - cron: '0 10 * * *' # 每天 18:00 (中国时间) jobs: run_script: runs-on: ubuntu-latest # 使用 Ubuntu 环境来运行脚本 permissions: contents: write # 为 GITHUB_TOKEN 或 ACCESS_TOKEN 授权写入权限 steps: - name: Checkout code uses: actions/checkout@v2 # 检出仓库代码 - name: Clear yaml files # 清除仓库中的 YAML 文件 run: | rm -rf ./*.yaml - name: Run update.sh update YAML files # 运行 update.sh 脚本更新 YAML 文件 run: | chmod +x ./update.sh # 给脚本加上执行权限 ./update.sh # 执行脚本 - name: Commit and push changes # 提交并推送修改 run: | git config --global user.email "xiaodong.zhuang@hotmail.com" git config --global user.name "Xiaodong Zhuang" git add . git commit -m "updated by github actions" git push https://x-access-token:${{ secrets.ACCESS_TOKEN }}@github.com/${{ github.repository }} env: GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} # 设置环境变量,使用存储的 ACCESS_TOKEN 推送代码 ``` ```shell title="update.sh" year=$(date +%Y) month=$(date +%m) day=$(date +%d) single_month=$(echo $month | sed 's/^0//') declare -A map # 定义sites与urls的关联数组 map["clash-meta.github.io"]="https://clash-meta.github.io/uploads/$year/$month/0-$year$month$day.yaml" # 新增的条目:路径中的月份为单数字,文件名中的月份为两位数 map["a.nodeshare.xyz"]="https://a.nodeshare.xyz/uploads/$year/$single_month/$year$month$day.yaml" # 更新clash配置文件 for site in "${!map[@]}"; do url="${map[$site]}" wget "$url" -O "$site.yaml" done ``` --- --- url: /posts/I2C协议.md --- # I2C协议 > Inter-Intergrated Circuit Bus 集成电路总线 ## 作用 * 多个ic间相互通信 ## 特点 * 占用接口少:只有SCL 和 SDA线 * 串行的,所有从机都用一根SDA线连接 * 可变速通信:时钟线的高低电平的切换频率可以控制 * 一主多从机:从机有7位地址构成,至多可连接**111个**器件 * 理论上是2^7=128个,但有一些[预留地址](#预留地址) ![](../public/images/Pasted%20image%2020260107160612.png) ## 原理 ![](../public/images/Pasted%20image%2020260107161532.png) * **SCL的高电平时,SDA的数据才有效** * 上电默认,SDA和SCL都是**高电平** * 起始信号:**SDA下降沿** * 数据包:SDA高电平表示1,低电平表示0 * 应答信号:一个数据包是8位,第9位表示应答信号,低电平表示收到数据 * 终止信号:**SDA上升沿** ### 主机写 主机要在从机0x0a上,寄存器0x04,写数据 ![](../public/images/Pasted%20image%2020260107173045.png) * 起始信号 * 主机写从机地址 `0001010 0`(即 0x14),从机应答信号 * 主机写寄存器地址,从机回应 * 主机发送8位数据,从机回应 * .... * 结束信号 ### 主机读 主机要在从机0x0a上,寄存器0x04,读数据 ![](../public/images/Pasted%20image%2020260107173051.png) ![](../public/images/Pasted%20image%2020260107161908.png) * 起始信号 * 主机写从机地址 `0001010 0`(即 0x14),从机应答信号 * 主机写寄存器地址,从机回应 * 起始信号(重启信号) * 主机读从机地址`0001010 1`(即 0x15),从机应答信号 * 从机发送8位数据,主机应答信号 * .... * 结束信号 ## 示例 \#\_Later 通过gpio模拟i2c与oled屏通信 ![](../public/images/Pasted%20image%2020260107162154.png) ## 附件 ### 预留地址 ![|650](../public/images/Pasted%20image%2020260107162111.png) ## 参考资料 * [【极速入门单片机】I2C总线的底层逻辑 时序电平全解析\_哔哩哔哩\_bilibili](https://www.bilibili.com/video/BV1dPaDzeEDg/?spm_id_from=333.337.search-card.all.click\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) --- --- url: /posts/linux挂载共享文件夹.md --- # linux挂载共享文件夹 > [VMware ubuntu共享文件夹自动挂载\_ubuntu虚拟机 自动挂载共享目录-CSDN博客](https://blog.csdn.net/weixin_45842078/article/details/121319770) ## 永久挂载 ```c sudo vi /etc/fstab ``` 加上这行: ```c .host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other,defaults 0 0 ``` ## 一次性挂载 ```shell sudo vmhgfs-fuse .host:/Desktop /mnt/hgfs/Desktop -o allow_other ``` --- --- url: /@pages/loginPage.md --- --- --- url: /posts/nrf52811_墨水屏桌搭_bom表.md --- # nrf52811\_墨水屏桌搭\_bom表 > [墨水屏桌搭bom](https://flowus.cn/zhuangxd/45f20168-56e5-411d-9bdf-d5005fb3a1c3) ![](../public/images/Pasted%20image%2020260208134906.png) --- --- url: /posts/nrf52811_墨水屏桌搭_jlink烧录.md --- # nrf52811\_墨水屏桌搭\_jlink烧录 > [nRF5 蓝牙墨水屏固件刷机教程 - 哔哩哔哩](https://www.bilibili.com/opus/1042166787832021028) 下载 [ jlink6.86驱动](https://www.segger.com/downloads/jlink/JLink_Windows_V686.exe) 通过 `C:\Program Files (x86)\SEGGER\JLink\JFlash.exe` 进行烧录 通过杜邦线链接Jlink的对应引脚 ![](../public/images/Pasted%20image%2020260207173036.png) 创建jflash项目 ![](../public/images/Pasted%20image%2020260207173301.png) 选择rf52811型号 ![](../public/images/Pasted%20image%2020260207173324.png) 把固件拖拽到jflash中 ![](../public/images/Pasted%20image%2020260207173351.png) 1. 清除flash:target ---> Manual Programming ---> erase chip 2. 烧录固件:target ---> Production Programming 3. 启动程序:target ---> Manual Programming ---> Start Applation --- --- url: /posts/nrf52811_墨水屏桌搭_外壳.md --- # nrf52811\_墨水屏桌搭\_外壳 ## 成果 ![](../public/images/Pasted%20image%2020260220075257.png) ## 注意 打印机喷头255度 ## 绘制 ![](../public/images/Pasted%20image%2020260217192146.png) ![](/assets/PixPin_2026-02-17_20-13-36.ZDg2PfIF.png) ![](/assets/PixPin_2026-02-17_20-13-45.Dss0p2Jr.png) --- --- url: /posts/nrf52811_墨水屏桌搭_配套上位机.md --- # nrf52811\_墨水屏桌搭\_配套上位机 [网页配置](https://tsl0922.github.io/EPD-nRF5/) 小程序配置 ![二维码](/assets/IMG_20260204_151534.D5bGfJWW.jpg) --- --- url: /private/archives/password.md --- # Password qq邮箱 * ejeravudhkmibadb --- --- url: /posts/platform_io识别cpp和.h文件.md --- # platform\_io识别cpp和.h文件 ```ini [env:esp32dev] platform = espressif32 board = esp32dev framework = arduino ; 核心解决方法1: 包含子目录的头文件,解决编译时找不到 .h 的问题 ; -I 告诉编译器在 src/Int 和 src/Com 目录下查找头文件 build_flags = -Isrc/Int -Isrc/Com ; 核心解决方法2: 递归编译 src 下的所有 .c/.cpp 文件 ; +<*> 包含 src 根目录 ; + +setText("Button clicked via lambda"); }); ``` ## 原理 \#\_Later 基于**Meta-Object System**(元对象系统)的**发布-订阅**模式。 ![](../public/images/Pasted%20image%2020260107143313.png) ## 应用场景 ### 信号和槽都在当前类 * 一对一 ```cpp // 示例:温度转换器 class TemperatureConverter : public QObject { Q_OBJECT public: TemperatureConverter() { // 信号槽,连接lineEdit的textChanged信号-convertToFahrenheit槽函数 connect(&m_celsiusEdit, &QLineEdit::textChanged, this, &TemperatureConverter::convertToFahrenheit); // 信号槽2 connect(&m_fahrenheitEdit, &QLineEdit::textChanged, this, &TemperatureConverter::convertToCelsius); } // 槽函数 private slots: void convertToFahrenheit(const QString &celsiusText) { bool ok; double celsius = celsiusText.toDouble(&ok); if (ok) { double fahrenheit = celsius * 9/5 + 32; m_fahrenheitEdit.setText(QString::number(fahrenheit)); } } void convertToCelsius(const QString &fahrenheitText) { // 类似实现... } private: QLineEdit m_celsiusEdit; QLineEdit m_fahrenheitEdit; }; ``` ## 参考 * [1,Qt源码解析信号和槽的机制\_哔哩哔哩\_bilibili](https://www.bilibili.com/video/BV1or4y1j7R4/?spm_id_from=333.337.search-card.all.click\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) --- --- url: /@pages/riskLinkPage.md --- --- --- url: /posts/sketchup_使用技巧.md --- # sketchup\_使用技巧 ## 快速选中模型 三击一条边,就可快速选中一个封闭模型 ![](../public/images/GIF%202026-2-7%2019-54-10.gif) ## 快速复制 * 通过ctrl+移动工具,可以快速复制1次 * 通过右下角 `/number` 或者 `*number` 可以快速复制多次 ![](../public/images/GIF%202026-2-6%2023-21-23.gif) 旋转也是适用 ![](../public/images/GIF%202026-2-6%2023-39-17.gif) --- --- url: /posts/sketchup_基础操作.md --- # sketchup\_基础操作 ## 滚轮 * 缩放:上下滚动滚轮 * 旋转视角:按住滚轮移动鼠标 * 平移视角:shift+按住滚轮移动鼠标 ## 选项卡 ### 导出3d打印格式 文件 ---> 导出三维模型 ---> stl格式 仅导出部![](../public/images/Pasted%20image%2020260207192513.png).png) ## 常用工具 ### 矩形 使用工具画出形状后,直接输入数字按回车(\`,![](../public/images/Pasted%20image%2020260206230601.png)230601.png) ### 偏移工具 主要用于画边框,![](/assets/PixPin_2026-02-06_23-09-54.BOSEQNib.png)6\_23-09-54.png) ### ![](../public/images/GIF%202026-2-6%2023-36-05.gif)-2-6%2023-36-05.gif) ## 右键操作 ### 创建组群 * 可以通过右键 ---> 创建组群锁定组合,可以防止误操作模型 * 可以通过右键 ---> 炸开组群解锁 \##![](../public/images/Pasted%20image%2020260206230730.png)d![](../public/images/Pasted%20image%2020260206230827.png)ed%20image%2020260206230827.png) --- --- url: /posts/sketchup_项目配置.md --- # sketchup\_项目配置 * 新建模型 ---> 建筑 ![](../public/images/Pasted%20image%2020260206225734.png)---> 模型信息 ---> 十进制 ---> 毫米 ![](../public/images/Pasted%20image%2020260206225927.png) --- --- url: /posts/vitepress-teek-theme使用.md --- # vitepress-teek-theme使用 模板地址 [onlyonexl/vitepress-theme-teek-one-public](https://gitee.com/onlyonexl/vitepress-theme-teek-one-public) --- --- url: /posts/vscode使用root账号ssh登录ubuntu.md --- # vscode使用root账号ssh登录ubuntu ubuntu打开配置文件 ```shell sudo vi /etc/ssh/sshd_config ``` 解除注释 `PermitRootLogin prohibit-password` ![](../public/images/Pasted%20image%2020260411200534.png) 重启ssh ```shell systemctl restart ssh ``` --- --- url: /posts/vscode使用ssh远程登陆ubuntu.md --- # vscode使用ssh远程登陆ubuntu ```shell sudo apt install openssh-server sudo systemctl enable ssh sudo systemctl start ssh ``` --- --- url: /posts/vs项目配置.md --- # vs项目配置 ## 单项目 > 参考 > > * [Visual Studio的最佳设置](https://www.bilibili.com/video/BV1zV41187jR?spm_id_from=333.788.videopod.sections\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) > * [Visual Studio 2022/VSCode C++配置第三方库](https://blog.csdn.net/Aritro/article/details/131833601) ### 输出目录 ``` $(SolutionDir)$(Configuration)\ 改为 $(SolutionDir)bin\$(Platform)\$(Configuration)\ ``` ### 中间目录 ``` $(ShortProjectName)\$(Configuration)\ 改为 $(SolutionDir)bin\intermediates\$(Platform)\$(Configuration)\ ``` ### 快捷键 * 编辑.复制 * 编辑.复制 改为 shift+alt+down * 编辑器上下文菜单.代码窗口.切换标题代码文件 改为 f4 * 编辑.设置选定内容的格式 改为 shift+alt+f \###![](../public/images/Pasted%20image%2020250928141311.png)250928141311.png) #### 添加自定义的lib ```cpp // 导入lib #ifdef __cplusplus extern "C" { #pragma comment (lib, "avcodec.lib") }; #endif ``` ![](../public/images/Pasted%20image%2020250928163049.png)%20image%20202509281![](../public/images/Pasted%20image%2020250928163653.png)e![](../public/images/Pasted%20image%2020250928163753.png)ted%20image%2020250928163753.png) ## 多个项目共用库 ### 输出目录 ``` $(SolutionDir)$(Configuration)\ 改为 ..\..\bin\$(Platform)\$(Configuration)\ ``` ### 中间目录 ``` $(ShortProjectName)\$(Configuration)\ 改为 ..\..\bin\intermediates\$(Platform)\$(Configuration)\ ``` ### 附加包含目录 ```text ..\..\include\ ``` ### 附加库目录 ``` ..\..\lib\x86 ``` #### \[Release模式下调试]\(https://blo![](../public/images/Pasted%20image%2020250928180157.png)调试跳转源码 ![](../public/images/Pasted%20image%2020250928180157.png) --- --- url: /posts/vue入门.md --- # vue入门 * 变量 * 绑定 数据绑定 ![](../public/images/Pasted%20image%2020260412144859.png) ![](../public/images/Pasted%20image%2020260412191217.png) --- --- url: /about/intro.md description: 认识一下打造这个项目的核心团队成员 --- --- --- url: /@pages/categoriesPage.md --- --- --- url: /posts/单例模式.md --- # 单例模式 ## 区别 * 创建时机 * 懒汉模式是指针,调用getInstance的时候才会创建对象 * 饿汉模式是静态成员,在数据段创建的(程序启动时就创建了对象) * 线程安全 * 饿汉安全 ## 示例 ::: code-group ```ts [懒汉模式] class Singleton { private: static Singleton* instance; // 私有构造函数,防止外部创建 Singleton() { std::cout << "Singleton created\n"; } // 禁用拷贝和赋值 Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; public: static Singleton* getInstance() { if (instance == nullptr) { instance = new Singleton(); } return instance; } void showMessage() { std::cout << "Hello from Singleton!\n"; } ~Singleton() { std::cout << "Singleton destroyed\n"; } }; // 静态成员初始化 Singleton* Singleton::instance = nullptr; ``` ```js [饿汉模式] class EagerSingleton { private: static EagerSingleton instance; EagerSingleton() { std::cout << "EagerSingleton created at program start\n"; } EagerSingleton(const EagerSingleton&) = delete; EagerSingleton& operator=(const EagerSingleton&) = delete; public: static EagerSingleton& getInstance() { return instance; // 直接返回引用 } void showMessage() { std::cout << "Hello from EagerSingleton!\n"; } ~EagerSingleton() { std::cout << "EagerSingleton destroyed\n"; } }; // 程序启动时就创建实例(静态初始化) EagerSingleton EagerSingleton::instance; ``` ::: --- --- url: /posts/单片机_stc89c52_中断.md --- # 单片机\_stc89c52\_中断 51单片机共有8个中断,通过不同的中断号区分 ![](../public/images/Pasted%20image%2020260129233827.png)外部中断 ### 原理 外部中断引脚和按键相连,因此可以通过`P32`按键触发外部中断0 ![](../public/images/Pasted%20image%2020260129210406.png) ![](../public/images/Pasted%20image%2020260129210416.png)) ### 示例 > [014\_interrupt](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/014_interrupt![]\(../publics/images/GIF_20260129_210222.gif\).gif) ## 定时器中断 ### 原理 * [回调函数](回调函数.md) ```c #define FOSC 11059200L #define T1MS (65536-FOSC/12/1000) void Timer0_start() { EA = 1; // 中断总开关 ET0 = 1; // 定时器0中断开关 TMOD &= 0xF0; // 定时器0 TMOD |= 0x01; TL0 = T1MS; // 初始值 低8位 TH0 = T1MS >> 8; // 初始值 高8位 TF0 = 1; // 清除 TR0 = 1; // 定时器0开始计时 } ``` ### 示例 #### 按键时钟 > [011\_timer](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/011_timer) > [012\_timer\_clock](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_c![]\(../publics/images/GIF_20260129_210651.gif\)images/GIF_20260129_210651.gif) #### PWM [024\_pwm](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/024_pwm) [026\_da](https://github.com/Zhuang-xd/blog-giscus-page/tree![]\(../publics/images/GIF_20260129_203936.gif\)ublic/images/GIF_20260129_203936.gif) ````c void time0_handle() { // 100us TL0 = 0x9C; //设置定时初值 TH0 = 0xFF; //设置定时初值 Counter++; Counter%=100; //计数值变化范围限制在0~99 if(Counter [013_uart](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/013_uart) #### 串口发送数据 串口发送中断是在![](../publics/images/Pasted%20image%2020260114144156.png)发送完毕,此时需要手动置0 ![](../public/images/Pasted%20image%2020260114144156.png) ```c #include "Int/LCD1602.h" #include #include "Com/Com_Util.h" #include "INTRINS.H" #define SYSclk 11059200L #define BAUD_RATE 9600 #define INIT_VAL (256 - SYSclk/32/12/BAUD_RATE) void Init_uart() { // IE中断总开关 EA = 1; ET1 = 1; // 中断允许溢出 // 串口中断 SCON = 0x40; // 串口控制 0100 0000 // 发送 PCON = 0; // 电源控制 0100 0000 ES = 1; // 串行口中断允许位 // 定时器1中断 TMOD = 0x20; // 定时器模式-位数 0010 0000 (8bit auto-reload) TH1 = INIT_VAL; // 初始值 高8位 TL1 = INIT_VAL; // 初始值 低8位 TR1 = 1; // 定时器1开始计时 } void Send_byte(u8 byte) { SBUF = byte; } void usrt_handle() interrupt 4 { if (TI == 1) // 发送完成中断标志位 { TI = 0; // 手动重置标志位,发送下一个字节 } } char str[] = "hello\r\n"; void main() { int i; Init_uart(); while (1) { for (i = ![](../publics/images/Pasted%20image%2020260113152439.png) Com_Util_DelayMs(10); } } } ```` #### 串口接收数据 ![](../public/images/Pasted%20image%2020260113152439.png) --- --- url: /posts/单片机_stc89c52_创建工程.md --- # 单片机\_stc89c52\_创建工程 ## EIDE ### 作用 可以用vscode代替keil5和stc-isp,但需要保留keil5用于编译 ### 示例 #### 编译烧录 vscode 安装 EIDE 插件 编译,配置keil5编译器(设置`TOOLS.INI`路![](../public/images/Pasted%20image%2020260112103855.png)png) 配置完就可以通过右上角进![](../public/images/Pasted%20image%2020260112104400.png)400.png) 右上角可以点击烧录 #### 配置hex路径 可以使用相对目录 ```shell .\build\Target ![](../publics/images/Pasted%20image%2020260112104324.png)20260112104324.png) #### 配置烧录工具 ``` C:\Users\Shelton>stcgal --help 'stcgal' 不是内部或外部命令,也不是可运行的程序 或批处理文件。 ```` [烧录工具 stcgal](https://gitee.com/mirrors/stcgal/blob/master/doc/zh_CN/INSTALL.md) 是一个python程序,需要下载python ```shell pip3 install stcgal ```` 并且配置环境变量 ```shell C:\Users\Shelton\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\Local-Packages\Python313\Scripts ``` 验证是否安装成功![](../public/images/Pasted%20image%2020260112104523.png)c/images/Pasted%20image%2020260112104523.png) ## 模块化 ### 示例 [006\_modules](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/006_modules) --- --- url: /posts/单片机_stc89c52_通信协议.md --- # 单片机\_stc89c52\_通信协议 ## I2C - EEPROM ### 原理 > [I2C协议](I2C协议.md) i2c地址,由于E0 ~ E2 都接地,所以 * 写地址为 `1010 0000` = `0xA0` * 读地址为 `1010 0001` = `0xA1` !\[]\(../p![](../public/images/Pasted%20image%2020260129200841.png)/p![](../public/images/Pasted%20image%2020260129200949.png)示例 > [021\_at24c02\_i2c\_data\_store](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/021_at24c02_i2c_data_store) 由高到低发送 一共16页,可以进行页读,页写 ```c void Int_WritePage(u8 addr, u8 byte[], u8 len) { u8 i; Dri_I2cStart(); Dri_I2cSendByte(IC_ADDRESS); Dri_I2cRecvAck(); Dri_I2cSendByte(addr); Dri_I2cRecvAck(); for (i = 0; i < len; i++) { Dri_I2cSendByte(byte[i]); Dri_I2cRecvAck(); } Dri_I2cStop(); Com_Util_DelayMs(10); } void Int_ReadPage(u8 addr, u8 byte[], u8 len) { u8 i; Dri_I2cStart(); Dri_I2cSendByte(IC_ADDRESS); Dri_I2cRecvAck(); Dri_I2cSendByte(addr); Dri_I2cRecvAck(); Dri_I2cStart(); // 重新起始信号 Dri_I2cSendByte(IC_ADDRESS+1); // 读取位 Dri_I2cRecvAck(); for (i = 0; i < len; i++) { byte[i] = Dri_I2cRecvByte(); Dri_I2cSendAck(i == len - 1 ? 1 : 0); } Dri_I2cStop(); } ``` i2c协议实现 ```c #include "Dri_I2C.h" #include sbit I2C_SCL = P2^1; sbit I2C_SDA = P2^0; /* 释放总线 - SDA = 1 - SCL = 0 */ /* 起始信号(两低) */ void Dri_I2cStart() { // 在scl电平的时候准备好数据 I2C_SCL = 1; I2C_SDA = 1; I2C_SDA = 0; // 下降沿 I2C_SCL = 0; // 时钟下降沿准备接收数据 } /* 截止信号(两高) */ void Dri_I2cStop() { I2C_SDA = 0; I2C_SCL = 1; I2C_SDA = 1; // 上升沿 } /* 发送数据包 */ void Dri_I2cSendByte(u8 byte) { u8 i; for (i = 0; i < 8; i++) { I2C_SDA = byte & (0x80 >> i) ; // 先写入高位,高电平前准备数据 I2C_SCL = 1; // SDA在SCL高电平时有效 I2C_SCL = 0; } } /* 接收数据包 */ u8 Dri_I2cRecvByte() { u8 i, byte = 0; I2C_SDA = 1; // 释放总线 for (i = 0; i < 8; i++) { I2C_SCL = 1; // SDA在SCL高电平时有效 if (I2C_SDA) { byte |= (0x80 >> i); // 先读取高位 } I2C_SCL = 0; } return byte; } void Dri_I2cSendAck(u8 ack_bit) { I2C_SDA = ack_bit; // 0=ACK, 1=NACK I2C_SCL = 1; I2C_SCL = 0; } u8 Dri_I2cRecvAck() { bit ack; I2C_SDA = 1; // 释放数据线 I2C_SCL = 1; ack = I2C_SDA; I2C_SCL = 0; return ack; } ``` ## SPI - XPT2045 湿度传感器、光敏电阻、可变电阻 ### 原理 > [花几分钟理解SPI通信原理\_哔哩哔哩\_bilibili](https://www.bilibili.com/video/BV1anHZecEiP?spm_id_from=333.788.player.switch\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) > !\[]\(../p![](../public/images/Pasted%20image%2020260128101230.png)../p![](../public/images/Pasted%20image%2020260128115741.png),cpha相位 * CPOL = 0,CPHA = 0,空闲低电平,上升沿有效 * CPOL = 0,CPHA = 1,空闲低电平,下降沿有效 * CPOL = 1,CPHA = 0,空闲高电平,下降沿有效 * CPOL = 1,CPHA = 1,空闲高电平,上升沿有效 ```c #define XPT_2045_AD1 0x9C // AIN0 = XP 1001 1100 #define XPT_2045_NTC1 0xCC // AIN1 = YP 1100 1100 #define XPT_2045_GR1 0xAC // AIN2 = VBAT 1010 1100 u8 Int_XPT2045_Read(u8 cmd); ``` !\[]\(../p![](../public/images/Pasted%20image%2020260128124057.png)../p![](../public/images/Pasted%20image%2020260128124101.png)1 * MODE = 0 12位,MODE = 1 8位 * SER = 1 单端模式,SER = 0 差分模式 * PD1PD0 = 00 低功率模式; PD1PD0 = 11 供电状态 !\[]\(../p![](../public/images/Pasted%20image%2020260128124112.png)示例 > [025\_ad](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/025_ad) 由高到低发送 !\[]\(../p![](/assets/GIF_20260129_201612.Cpf9ibD0.gif)\`\`\`c u8 Int\_XPT2045\_Read(u8 cmd) { u8 byte = 0x00; Dri\_SPI\_Start(); Dri\_SPI\_SendByte(cmd); byte = Dri\_SPI\_RecvByte(); Dri\_SPI\_End(); ``` return byte; ``` } ```` spi协议 ```c sbit SPI_CS = P3^5; sbit SPI_DCLK = P3^6; sbit SPI_DIN = P3^4; sbit SPI_DOUT = P3^7; void Dri_SPI_Start() { SPI_CS = 0; SPI_DCLK = 0; } // SPI结束传输 void Dri_SPI_End() { SPI_CS = 1; // 释放设备 SPI_DCLK = 0; // 时钟保持低电平 } void Dri_SPI_SendByte(u8 byte) { u8 i; for (i = 0; i < 8; i++) { SPI_DCLK = 0; // 上升沿发送 SPI_DIN = byte & (0x80 >> i); // 由高到低发送 SPI_DCLK = 1; } SPI_DCLK = 0; } u8 Dri_SPI_RecvByte() { u8 i,res = 0x00; for (i = 0; i < 8; i++) { SPI_DCLK = 1; // 下降沿读取 if (SPI_DOUT) { res |= (0x80 >> i); // 由高到低读取 } SPI_DCLK = 0; } return res; } ```` ## 1 Wire - DS18B20 温度传感器 ### 原理 通过时间间隔区分高低电平 ### 示例 > [022\_ds18b20](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/022_ds18b20) 由低到高发送 !\[]\(../p![](/assets/IMG_20260129_204223.DLM9N2L_.jpg)R - 红外接收器 ### 原理 类似单总线,通过时间间隔区分高低电平 !\[]\(../p![](../public/images/Pasted%20image%2020260128142259.png) > [027\_ir](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/027_ir) > [028\_ir\_motor](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/028_ir_motor) 由低到高发送 !\[]\(../p![](/assets/GIF_20260129_203936.DeVjWCkp.gif) --- --- url: /posts/单片机_stc89c52_驱动外设.md --- # 单片机\_stc89c52\_驱动外设 ## 驱动led ### 原理 由原理图可知,LED一段都接了电源,另一端接了单片机的`P20`~`P27`引脚 !\[|3![|325](../public/images/Pasted%20image%2020260129180203.png)因此,`P2` 引脚为低电平时就可以点亮LED,可以整体赋值 ```cpp P2 = 0xFE; ``` 也可以单个赋值(头文件为``) ```cpp P2_7 = 0; ``` ### 示例 #### 点亮LED > [001\_led](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src![]\(../publics/images/GIF_20260129_181554.gif\)9_181554.gif) ## 独立按键 ### 原理 #### 原理图 由原理图可知,按键一段都接了低电平,另![|475](../public/images/Pasted%20image%2020260129182308.png)e%2020260129182308.png) 当单片机给按键低电平的时候,就导通了 #### 按键消抖 ```c if (P3_1 == 0) { DelayMs(20); // 按下消抖 while (P3_1 == 0); // 松手消抖 DelayMs(20); LedToggle(); } ``` ### 示例 #### 按键点亮led > \[002\_key\_pressed\_debounce]\(https://github.com/Zhuang-xd/blog-giscus-page/tree/master/stu![](../publics/images/GIF_20260129_182151.gif)[](../public/images/GIF_20260129_182151.gif) #### 二进制点灯 > \[003\_key\_pressed\_bin\_add]\(https://github.com/Zhuang-xd/blog-giscus-page/tree/mast![](/assets/GIF_20260129_183026.CrwO_dDb.gif) ![](/assets/GIF_20260129_183026.CrwO_dDb.gif) ## 数码管 ### 原理 #### 原理图 8个数码管通过74hc595管![](../public/images/Pasted%20image%2020260129191410.png) ![](../public/images/Pasted%20image%2020260129183230.png)ng) ![](../public/images/Pasted%20image%2020260129183230.png) #### 显示单个数码管 原理图上的数码管的COM端没有接VCC,因此时共阴极的数码管,码表为 ```c unsigned char seg[17] = { // 共阴极,高电平有效 // 7 6 5 4 3 2 1 0 // dp g f e d c b a 0x3F, // 0 0 1 1 1 1 1 1 = 0 0x06, // 0 0 0 0 0 1 1 0 = 1 0x5B, // 0 1 0 1 1 0 1 1 = 2 0x4F, // "3" a b c d g 0x66, // "4" b c f g 0x6D, // "5" a c d f g 0x7D, // "6" a c d e f g 0x07, // "7" a b c 0x7F, // "8" 全亮 0x6F, // "9" a b c d f g 0x77, // "A" 0x7C, // "B" 0x39, // "C" 0x5E, // "D" 0x79, // "E" 0x71, // "F" }; ``` #### 显示多个数码管 ```c while (1) { for (i = 0; i < 8; i++) { seg(i,i); // 第i个数码管, 显示i } } void seg(int sel_seg, int sel_chip) { switch (sel_seg) { case 0: P2_4 = 0; P2_3 = 0; P2_2 = 0;break; case 1: P2_4 = 0; P2_3 = 0; P2_2 = 1;break; case 2: P2_4 = 0; P2_3 = 1; P2_2 = 0;break; case 3: P2_4 = 0; P2_3 = 1; P2_2 = 1;break; case 4: P2_4 = 1; P2_3 = 0; P2_2 = 0;break; case 5: P2_4 = 1; P2_3 = 0; P2_2 = 1;break; case 6: P2_4 = 1; P2_3 = 1; P2_2 = 0;break; case 7: P2_4 = 1; P2_3 = 1; P2_2 = 1;break; } P0 = seg[sel_chip]; DelayMs(1); P0 = 0; } ``` ### 示例 #### 点亮单![](/assets/GIF_20260129_183936.6wm0znXQ.gif)om/Zhuang-xd/blog-giscus-page/tree/master/study\_chip\_51/src/004\_segment\_single) ![](/assets/GIF_20260129_183936.6wm0znXQ.gif) #### 点亮多![|650](/assets/IMG_20260129_184151.D4g3voCS.jpg)/Zhuang-xd/blog-giscus-page/tree/master/study\_chip\_51/src/005\_segment\_multiple) !\[|650]\(../pub![](../public/images/Pasted%20image%2020260129190305.png) 和数码管类似,通过单片机的 `P10` ~ `P17` 引脚,4个表示列,4个表示行,可以检测16个按键。 先选中一行,再扫描一列就可以确定哪个按键被按下了 !\[]\(../public/images/Pasted%20image%202026012919030![](/assets/GIF_20260129_185008.DySVEDaz.gif)key]\(https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study\_chip\_51/src/009\_matrix\_key) ![](/assets/GIF_20260129_185008.DySVEDaz.gif) #### 按键密码锁 > \[010\_matrix\_key\_l![|550](../public/images/Pasted%20image%2020260114224143.png)t![|550](../public/images/Pasted%20image%2020260129191333.png)原![|550](../public/images/Pasted%20image%2020260129191315.png)d%20image%2020260114224143.png) > ![|550](../public/images/Pasted%20image%2020260129191333.png) > ![|550](../public/images/Pasted%20image%2020260129191315.png) ```c // 点阵屏扫描 void Int_matrix_led_scan_col(u8 col, u8 byte) { Int_74hc595_send_byte(byte); P0=~(0x80>>col); // 1000 0000位移1位后取反 1011 1111,可以实现相同的逻辑 // P0 = _cror_(0x7f,col); // 0111 1111 Com_Util_DelayMs(1); //延时 P0=0xff; //位清0 } void Int_74hc595_send_byte(u8 byte) { u8 i; for (i = 0; i < 8; i++) { SER = byte&(0x80 >> i); // 由高到底发送 SRK = 1; // 上升沿移位 SRK = 0; // 上升沿移位 } RCK = 1; // 上升沿8位锁存 RCK = 0; // 上升沿8位锁存 } ``` 按列显示0点亮,一共8列,因此可以通过8个8位表示一帧画面 ```c unsigned char code bmp[]={ 0x00,0x7E,0x10,0x10,0x7E,0x00,0x00,0x7E, 0x52,0x52,0x52,0x00,0x00,0x7E,0x02,0x02, ![](../publics/images/Pasted%20image%2020260129192841.png)x42,0x42,0x3C,0x00,0x00,0x7A, }; ``` 第二帧画面为 ```c Int_matrix_led_scan_col(i,bmp[i+offset]); offset++; ``` ### 注意 跳线帽改成如图,点阵屏才能正常显示 ![](../public/images/Pasted%20image%2020260129192841.png) ### 示例 > [015\_matrix\_led\_static](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/015_matrix_led_static) 摄像头拍不出,动态显示心形 > [016\_matrix\_led\_dynamic](https://github.com/Zhuang-xd/blog-giscus-page/tree![]\(../publics/images/GIF_20260129_193059.gif\)mic) 摄像头拍不出,滚动显示HELLO ## DS1302时钟 ### 原理 ### 示例 #### 时钟 > \[017\_ds1302]\(https://github.com/Zhuang-xd/blog-giscus-page/t![](../publics/images/GIF_20260129_193350.gif)[](../public/images/GIF_20260129_193059.gif) #### 时钟设置 > \[0![|450](../public/images/Pasted%20image%2020260129193513.png)-![|450](../public/images/Pasted%20image%2020260129194003.png)[](../public/images/GIF_20260129_193350.gif) ## 蜂鸣器 ### 原理 有源蜂鸣器通电就可以响,但是开发板上是无源蜂鸣器,因此需要提供一个PWM方波来驱动蜂鸣器 ![|450](../public/images/Pasted%20image%2020260129193513.png) ![|450](../public/images/Pasted%20image%2020260129194003.png) ### 示例 > [019\_beep\_key](https://github.co![]\(../publics/images/Pasted%20image%2020260129194622.png\)c/019_beep_key) > \[020\_beep\_music]\(https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study\_chip![](../publics/images/Pasted%20image%2020260129194223.png)2内部有一个字库,可以自动将ASCII码转换成对应的字符。 > ![](../public/images/Pasted%20image%2020260129194622.png) LCD1602有2行,每行16个字符: * **第0行**的地址范围:`0x80` ~ `0x8F` * **第1行**的地址范围:`0xC0` ~ `0xCF` 主要由三个控制引脚:RS、RW、EN ![](../public/images/Pasted%20image%2020260129194223.png) ### 示例 > [023\_lcd1602](https://github.com/Zhuang-xd/blog-giscus-page/tree/master/study_chip_51/src/023_lcd1602) ```c sbit LCD1602_EN = P2^7; // 1读  下降沿执行指令 sbit LCD1602_RS = P2^6; // 0指令 1数据 sbit LCD1602_RW = P2^5; // 0写   1读 void Int_LCD_Init() { Int_LCD_WriteCmd(0x38); // 设置8位格式 Int_LCD_WriteCmd(0x0c); // 整体写入 Int_LCD_WriteCmd(0x06); // 设置输入 Int_LCD_WriteCmd(0x01); // 清屏 Com_Util_DelayMs(1); } void Int_LCD_WriteCmd(u8 byte) { LCD1602_SDA=byte; LCD1602_RS=0; //指令 LCD1602_RW=0; //写入 LCD1602_EN=1; Com_Util_DelayMs(1); LCD1602_EN=0; //下降沿 Com_Util_DelayMs(1); } void Int_LCD_WriteData(u8 byte) { LCD1602_SDA=byte; LCD1602_RS=1; //数据 LCD1602_RW=0; //写入 LCD1602_EN=1; Com_Util_DelayMs(1); LCD1602_EN=0; //下降沿 Com_Util_DelayMs(1); } void Int_LCD_ShowChar(u8 line, u8 pos, u8 ch) { u8 addr; // 1000 0000 addr = (line == 0) ? 0x80+pos : 0xc0+pos; // 0xc0 = 0x80 + 0x40 Int_LCD_WriteCmd(addr); Int_LCD_WriteData(ch); } ``` --- --- url: /posts/单片机_stm32f103c8t6_GPIO输出.md --- # 单片机\_stm32f103c8t6\_GPIO输出 ## 点亮LED ![](/assets/IMG_20260208_211920.Db1f-e5C.jpg) ```c #include "stm32f10x.h" int main(void) { // 1.使能GPIOA的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 2.初始化GPIOA GPIO_InitTypeDef GPIO_InitStructure = { .GPIO_Mode = GPIO_Mode_Out_PP, // 推挽输出 .GPIO_Pin = GPIO_Pin_0, .GPIO_Speed = GPIO_Speed_50MHz, }; GPIO_Init(GPIOA,&GPIO_InitStructure); // 3. 0管脚低电平点亮 GPIO_ResetBits(GPIOA, GPIO_Pin_0); //GPIO_ResetBits(GPIOA, GPIO_Pin_0); while(1) { } } ``` ## LED流水灯 > 推挽输出高低电平都可以驱动,开漏输出只能低电平驱动 ![](/assets/GIF_20260209_103537.Ymq6JQfo.gif) ```c #include "stm32f10x.h" // Device header #include "Delay.h" int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure = { // 开漏输出只有低电平的输出能力,推挽输出高低电平的能力都有 .GPIO_Mode = GPIO_Mode_Out_PP, // 推挽输出 .GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5, .GPIO_Speed = GPIO_Speed_50MHz, }; GPIO_Init(GPIOA,&GPIO_InitStructure); unsigned int tmp = 0x0001; while(1) { GPIO_Write(GPIOA, tmp); // 低电平 亮 一次写入32位 Delay_ms(500); tmp <<= 1; if (tmp > GPIO_Pin_5) tmp = 0x0001; } } ``` ## 蜂鸣器 PB3、PB4、PA15 为Jtag调试端口,当作普通gpio来使用,需要额外的配置 #注意事项 ```c #include "stm32f10x.h" // Device header #include "Delay.h" int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure = { .GPIO_Mode = GPIO_Mode_Out_PP, // 推挽输出 .GPIO_Pin = GPIO_Pin_8, .GPIO_Speed = GPIO_Speed_50MHz, }; GPIO_Init(GPIOB,&GPIO_InitStructure); while(1) { GPIO_WriteBit(GPIOB, GPIO_Pin_8, Bit_RESET); Delay_ms(100); } } ``` --- --- url: /posts/单片机_stm32f103c8t6_创建工程.md --- # 单片机\_stm32f103c8t6\_创建工程 > [\[3-2\] LED闪烁\&LED流水灯&蜂鸣器\_哔哩哔哩\_bilibili](https://www.bilibili.com/video/BV1th411z7sn?spm_id_from=333.788.videopod.episodes\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504\&p=6) ## keil创建工程 ### 编译 添加库文件到项目, ![](../public/images/Pasted%20image%2020260208202739.png)件的`include`路径 ![](../public/images/Pasted%20image%2020260208120741.png)义 ![](../public/images/Pasted%20image%2020260208203336.png)编译器,compiler v6会报错,原因未知 ![](../public/images/Pasted%20image%2020260208152203.png)m的 `include`路径 ![](../public/images/Pasted%20image%2020260208202939.png) 我这里使用的是 j-link烧录 ![](../public/images/Pasted%20image%2020260208230808.png)../p![](../public/images/Pasted%20image%2020260208203153.png)完毕后自动跑程序 ![](../public/images/Pasted%20image%2020260208203212.png)IDE创建工程 ### 编译 配置arm compiler编译器 ![](../public/images/Pasted%20image%2020260209100537.png)义 ![](../public/images/Pasted%20image%2020260209102024.png)烧录 配置 [j-link ](https://www.segger.com/downloads/jlink/JLink_Windows_V686.exe) 路径 和 芯片型号 ![](../public/images/Pasted%20image%2020260209102928.png) 测试 可以看到小灯在闪烁,说明已经烧录成功 ![](/assets/GIF_20260209_103537.Ymq6JQfo.gif) ```cpp #include "Delay.h" #include "stm32f10x.h" // Device header #include "Delay.h" int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure = { .GPIO_Mode = GPIO_Mode_Out_PP, // 推挽输出 .GPIO_Pin = GPIO_Pin_0, .GPIO_Speed = GPIO_Speed_50MHz, }; GPIO_Init(GPIOA,&GPIO_InitStructure); while(1) { GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET); Delay_ms(500); GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); Delay_ms(500); } } ``` --- --- url: /posts/回调函数.md --- # 回调函数 ```c typedef void (*Timer0_Callback)(void); // 定义函数指针 ``` ```c #define MAX_CALLBACK_COUNT 2 static Timer0_Callback s_callbacks[MAX_CALLBACK_COUNT]; // 函数指针数组 void Dri_Timer0_Init() { u8 i; // 1.启用中断 EA = 1; ET0 = 1; // 2.工作模式:GATE=0;C/T=0;M1=0,M0=1 TMOD &= 0xF0; TMOD |= 0x01; // 3.初始值 TL0 = 64614; TH0 = 64614 >> 8; // 1ms // 4.启动 TR0 = 1; // 5.初始化函数指数组 for (i = 0; i < MAX_CALLBACK_COUNT; i++) { s_callbacks[i] = NULL; } } bit Dri_Timer0_RegisterCallback(Timer0_Callback callback) { u8 i; // 确保不会重复注册 for (i = 0; i < MAX_CALLBACK_COUNT; i++) { if (s_callbacks[i] == callback) { return 1; } } // 寻找坑位 for (i = 0; i < MAX_CALLBACK_COUNT; i++) { if (s_callbacks[i] == NULL) { s_callbacks[i] = callback; return 1; } } return 0; } bit Dri_Timer0_DeregisterCallback(Timer0_Callback callback) { u8 i; for (i = 0; i < MAX_CALLBACK_COUNT; i++) { if (s_callbacks[i] == callback) { s_callbacks[i] = NULL; return 1; } } return 0; } void Dri_Timer0_Handler() interrupt 1 { u8 i; // 1.重新装载初始值 TL0 = 64614; TH0 = 64614 >> 8; // 2.轮询函数指针数组 for (i = 0; i < MAX_CALLBACK_COUNT; i++) { if (s_callbacks[i] != NULL) { s_callbacks[i](); } } } ``` --- --- url: /@pages/collectionsPage.md --- # 收集 ## 剧集 * [海市蜃楼](https://www.bilibili.com/video/BV1Jkr5BLES9/?spm_id_from=333.1007.tianma.2-2-5.click\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) ## 教程 * [QT QML](https://www.bilibili.com/video/BV1pWameyELy?spm_id_from=333.788.player.switch\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504\&trackid=web_related_0.router-related-2206419-fjhdv.1767697152090.883) ## 博客 * https://gitee.com/dlwwei ## 软件 * [WPS Office 2023、2025 专业版](https://www.mefcl.com/wps-office-2023.html) ## 机场 * [仪表盘 | 光速机场](https://www.gscloud.sbs/#/dashboard) ## openai-api-key * [chatanywhere/GPT\_API\_free: Free ChatGPT\&DeepSeek API Key](https://github.com/chatanywhere/GPT_API_free?tab=readme-ov-file) ## markmap与mermaid生成器 * [中文Markmap在线编辑器与思维导图自动生成 - MIN2K](https://www.min2k.com/tools/markmap/) ## pdf翻译工具 * [PDFMathTranslate - PDF Translation with preserved formats](https://pdf2zh.com/) ## tvbox源 * [47.96.82.41:8/api.json](http://47.96.82.41:8/api.json) * [登录 - 接口管理系统](https://api.starlink.fan/login.php) * [新建标签页](https://zongru666.github.io/myIPTV/) --- --- url: /@pages/articleOverviewPage.md --- --- --- url: /@pages/timelinePage.md --- --- --- url: /@pages/tagsPage.md --- --- --- url: /posts/泰山派_SDK打补丁.md --- # 泰山派\_SDK打补丁 > [随笔三、底板扩展板网口测试及内核升级\_泰山派扩展板-CSDN博客](https://blog.csdn.net/mcubbs/article/details/141256009) 拓展板的网口,可以通过这个补丁驱动,把`kernel.patch `拷贝到`kernel`目录,执行下面的命令就可以了 ```shell patch -p1 < kernel.patch ``` ![](../public/images/Pasted%20image%2020251213110942.png) --- --- url: /posts/泰山派_交叉编译qt.md --- # 泰山派\_交叉编译qt ## 构建makefile 使用虚拟机直接编译,用vscode remote容易崩 在qt源码的根目录下新建 `auto-configure.sh` ```shell #!/bin/sh ./configure \ -prefix /home/shelton/Workspaces/source/qt/build/aarch64-rk3566-linux-gnu-qt-5.15.2 \ -xplatform aarch64-rk3566-linux-gnu-g++ \ -confirm-license \ -opensource \ -release \ -make libs \ -pch \ -qt-libjpeg \ -qt-libpng \ -qt-zlib \ -no-opengl \ -no-sse2 \ -no-openssl \ -no-cups \ -no-glib \ -no-dbus \ -no-separate-debug-info \ -nomake tools \ -nomake examples \ -qpa linuxfb \ -skip qt3d \ -skip qtactiveqt \ -skip qtandroidextras \ -skip qtcanvas3d \ -skip qtconnectivity \ -skip qtdatavis3d \ -skip qtdoc \ -skip qtgamepad \ -skip qtlocation \ -skip qtmacextras \ -skip qtnetworkauth \ -skip qtpurchasing \ -skip qtremoteobjects \ -skip qtscript \ -skip qtscxml \ -skip qtsensors \ -skip qtspeech \ -skip qtsvg \ -skip qttools \ -skip qttranslations \ -skip qtwayland \ -skip qtwebengine \ -skip qtwebview \ -skip qtwinextras \ -skip qtx11extras \ -skip qtxmlpatterns \ -skip qtdeclarative \ -skip qtmultimedia ``` 创建交叉编译平台 `qt-everywhere-src-5.12.9/qtbase/mkspecs/aarch64-rk3566-linux-gnu-g++` `qmake.conf` ``` # # qmake configuration for building with aarch64-buildroot-linux-gnu-g++ # MAKEFILE_GENERATOR = UNIX CONFIG += incremental QMAKE_INCREMENTAL_STYLE = sublib QT_QPA_DEFAULT_PLATFORM = linuxfb QMAKE_CFLAGS_RELEASE += -O2 -march=armv8-a -lts QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv8-a -lts include(../common/linux.conf) include(../common/gcc-base-unix.conf) include(../common/g++-unix.conf) # modifications to g++.conf QMAKE_CC = aarch64-buildroot-linux-gnu-gcc QMAKE_CXX = aarch64-buildroot-linux-gnu-g++ QMAKE_LINK = aarch64-buildroot-linux-gnu-g++ QMAKE_LINK_SHLIB = aarch64-buildroot-linux-gnu-g++ # modifications to linux.conf QMAKE_AR = aarch64-buildroot-linux-gnu-ar cqs QMAKE_OBJCOPY = aarch64-buildroot-linux-gnu-objcopy QMAKE_NM = aarch64-buildroot-linux-gnu-nm -P QMAKE_STRIP = aarch64-buildroot-linux-gnu-strip load(qt_config) ``` 执行这个脚本,构建makefile ![](../public/images/Pasted%20image%2020260106155439.png)e -j16\` 开始编译 `make install` 安装 \#\_Later 把画面在rk3566上跑起来 --- --- url: /posts/泰山派_固件打包脚本.md --- # 泰山派\_固件打包脚本 可以一键把img镜像打包,并拷贝到宿主机的桌面 ```shell #! /bin/sh export RK_ROOTFS_SYSTEM=buildroot ./build.sh all ./mkfirmware.sh ./build.sh updateimg cp ./rockdev/update.img /mnt/hgfs/Desktop ``` --- --- url: /posts/泰山派_常用的目录.md --- # 泰山派\_常用的目录 rootfs目录 ```shell /home/shelton/Workspaces/media-sys/info/tspi_linux_sdk_repo_20240131/buildroot/output/rockchip_rk3566/target ``` 摄像头设备树 ```shell /home/shelton/Workspaces/media-sys/info/tspi_linux_sdk_repo_20240131/kernel/arch/arm64/boot/dts/rockchip/tspi-rk3566-csi-v10.dtsi ``` 摄像头驱动源码 ```shell /home/shelton/Workspaces/media-sys/info/tspi_linux_sdk_repo_20240131/kernel/drivers/media/i2c/ov5695.c ``` --- --- url: /posts/泰山派_挂载nfs.md --- # 泰山派\_挂载nfs ## ubuntu安装nfs服务器 安装nfs ```shell sudo apt-get install nfs-kernel-server rpcbind ``` 配置nfs ```shell sudo vim /etc/exports ``` ```ts /home/shelton/Workspaces/projects *(rw,sync,no_root_squash) ``` 重启nfs ```shell sudo /etc/init.d/nfs-kernel-server restart ps -A | grep nfs #判断服务是否开启 ``` ## 泰山派buildroot构建nfs > [【 泰山派RK3566 | NFS】使用泰山派RK3566进行 NFS 网络文件挂载\_rk3566 nfs-CSDN博客](https://blog.csdn.net/2302_80277720/article/details/150995943) 加载板子对应的环境变量 ```shell source buildroot/build/envsetup.sh #泰山派rk3566选择65 ``` 编辑kconfig,配置nfs ``` make menuconfig ``` 按下 `/` 然后输入 `nfs_utils`,勾选`nfs-utils` 保存到默认配置 ```shell make savedefconfig ``` 挂载nfs脚本 ```shell #! /bin/sh wifi_start.sh 1103 Z18221974718 #连接wifi ifconfig wlan0 192.168.0.150 netmask 255.255.255.0 #配置wifi mount -t nfs -o nfsvers=3,nolock 192.168.0.200:/home/shelton/Workspaces/projects /mnt #挂载命令 ``` --- --- url: /posts/泰山派_摄像头程序编译.md --- # 泰山派\_摄像头程序编译 cmake配置交叉编译器 ```shell # Example toolchain.cmake content set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) # 交叉编译器地址 set(CMAKE_C_COMPILER "/home/shelton/Workspaces/media-sys/info/tspi_linux_sdk_repo_20240131/buildroot/output/rockchip_rk3566/host/bin/aarch64-buildroot-linux-gnu-gcc") # 自行修改 set(CMAKE_CXX_COMPILER "/home/shelton/Workspaces/media-sys/info/tspi_linux_sdk_repo_20240131/buildroot/output/rockchip_rk3566/host/bin/aarch64-buildroot-linux-gnu-g++") # 自行修改 #set(CMAKE_C_COMPILER "/home/shelton/Workspaces/media-sys/info/tspi_linux_sdk_repo_20240131/prebuilts/gcc/linux-x86/aarch64/gcc-buildroot-9.3.0-2020.03-x86_64_aarch64-rockchip-linux-gnu/bin/aarch64-buildroot-linux-gnu-gcc") # 自行修改 #set(CMAKE_CXX_COMPILER "/home/shelton/Workspaces/media-sys/info/tspi_linux_sdk_repo_20240131/prebuilts/gcc/linux-x86/aarch64/gcc-buildroot-9.3.0-2020.03-x86_64_aarch64-rockchip-linux-gnu/bin/aarch64-buildroot-linux-gnu-g++") # 自行修改 # 设置目标系统根目录 set(CMAKE_FIND_ROOT_PATH /home/shelton/Workspaces/media-sys/info/tspi_linux_sdk_repo_20240131/buildroot/output/rockchip_rk3568/target/) # 自行修改 # 配置 CMake 查找程序和库文件的方式 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) ``` cmake去除highgui,因为这个依赖qt库,项目中没有配置qt,因此可以去除 ```shell # 修改链接库顺序,使用以下替代方案 target_link_libraries(rk_cmake_project pthread rockit rt_test_comm opencv_core opencv_imgproc opencv_imgcodecs # 去掉 opencv_highgui 或者使用以下替代 # opencv_highgui # 注释掉这一行 rknnrt rga turbojpeg mk_api ) # 或者直接不链接 opencv_highgui(如果不需要 GUI 显示) ``` --- --- url: /posts/泰山派_点亮mipi屏幕.md --- # 泰山派\_点亮mipi屏幕 ## i2c > GP7101.pdf i2c转pwm #\_Later !\[|375]![|375](../public/images/Pasted%20image%2020251224101919.png)地址实际是7位 + 1位读写位 * 写操作时,使用 `0xB0`。 * 读操作时,使用 `0xB1`(只改变最低位) ``` 1011 0000 = 0xB0 ``` 因此GP7101的实际I2C地址如下 ``` 0101 1000 = 0x58 ``` 目录`kernel/arch/arm64/boot/dts/rockchip/tspi-rk3566-dsi-v10.dtsi` ```cpp &i2c1 { status = "okay"; // 状态为"okay",表示此节点是可用和配置正确的 // 板载背光驱动电路 GP7101@58 { compatible = "gp7101-backlight"; reg = <0x58>; max-brightness-levels = <255>; // 背光亮度的最大级别是255 default-brightness-level = <100>; // 默认的背光亮度级别是100 }; }; ``` ## 参考资料 * 屏幕手册 * [LCKFB-mipi-3.1inch-screen中文资料\_最新报价\_数据手册下载\_立创开发板-开发板-立创商城](https://item.szlcsc.com/44319751.html) * [D310T9362V1 3.1寸带电容触摸液晶显示模组 500亮度 IPS全视角 MIPI接口分辨率480\*800 驱动IC:ST7701S, 搭配电容触摸屏. | 深圳市大显伟业科技有限公司](https://www.panelook.cn/D310T9362V1-detail_cn_100341.html) * [Hardware/Accessories/Display/D310T9362V1 SPEC.pdf · GloomyGhost/Yuzukilizard - Gitee.com](https://gitee.com/GloomyGhost/Yuzukilizard/blob/master/Hardware/Accessories/Display/D310T9362V1%20SPEC.pdf)- * 泰山派 * [3.1寸屏幕扩展板 | 立创开发板技术文档中心](https://wiki.lckfb.com/zh-hans/lushan-pi-k230/open-source-hardware/lckfb-mipi-3.1inch-screen.html) --- --- url: /posts/泰山派_移植ov8858摄像头.md --- # 泰山派\_移植ov8858摄像头 内核中已经适配了ov8858的驱动源码,只需要 * 开启对应的驱动编译选项 * 配置设备树 ``` /home/shelton/Workspaces/source/sdk/rockchip/rk3566_tspi/tspi_linux_sdk_repo_20240131/kernel/drivers/media/i2c/ov8858.c ``` ## 开启OV5695驱动编译选项 kernel kconfig ```shell #选中预选的配置 source buildroot/build/envsetup.sh # 所有配置项的目录 #/home/shelton/Workspaces/source/sdk/rockchip/rk3566_tspi/tspi_linux_sdk_repo_20240131/buildroot/configs # 进入图形化配置 make menuconfig # 65 rockchip_rk3566_defconfig #保存配置 make savedefconfig ``` 此时kernel的 kconfig 会加载默认的配置项`tspi_linux_sdk_repo_20240131/kernel/arch/arm64/configs/rockchip_linux_defconfig` * kconfig由多个配置文件组合而成,因此可以直接在`rockchip_linux_defconfig`中添加配置 在 `rockchip_linux_defconfig` 中添加 `CONFIG_VIDEO_OV8858=y` ```shell # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_VIDEO_OV5695=y #... CONFIG_VIDEO_OV8858=y ``` 此时`tspi_linux_sdk_repo_20240131/kernel/arch` 中的 `Makefile`的这个目标就生效了 ```shell obj-$(CONFIG_VIDEO_OV8858) += ov8858.o ``` `tspi_linux_sdk_repo_20240131/kernel/drivers/media/i2c` 中出现 `ov8858.o` 即为添加成功 ## 修改设备树 设备树的路径为 ```shell /home/shelton/Workspaces/source/sdk/rockchip/rk3566_tspi/tspi_linux_sdk_repo_20240131/kernel/arch/arm64/boot/dts/rockchip ``` ### 创建ov8858对应的设备树 基于ov5695的设备树 `tspi-rk3566-csi-v10.dtsi` 修改 ![](../public/images/Pasted%20image%2020251218125946.png) 数据链路 这是一个真实、对称、可验证的硬件连接 **Sensor → CSI-2 DPHY → ISP** 的数据通路 ``` [ov8858] ──⇄── [csi2_dphy0] ──⇄── [rkisp_vir0] (in/out endpoints) ``` `remote-endpoint` 的指向如上图 ```shell //摄像头D-PHY接口 &csi2_dphy0 { status = "okay"; ports { port@0 { reg = <0>; dphy0_in: endpoint@1 { reg = <1>; remote-endpoint = <&ov8858_out>; data-lanes = <1 2 3 4>; }; }; port@1 { reg = <1>; dphy0_out: endpoint@1 { reg = <1>; remote-endpoint = <&isp0_in>; }; }; }; }; //图像处理接口 &rkisp_vir0 { status = "okay"; port { isp0_in: endpoint@0 { reg = <0>; remote-endpoint = <&dphy0_out>; }; }; }; &i2c4 { port { ov8858_out: endpoint { remote-endpoint = <&dphy0_in>; data-lanes = <1 2 3 4>; // 2lane为 <1 2>, 4lane为 <1 2 3 4> }; }; }; }; ``` #### 复位引脚 高电平有效 复位引脚 高电平有效 #\_Later #### 镜头参数 ``` /home/shelton/Workspaces/source/sdk/rockchip/rk3566_tspi/tspi_linux_sdk_repo_20240131/external/camera_engine_rkaiq/iqfiles/isp21 ./camera_engine_rkaiq/tests/rkisp_demo/demo/rkisp_demo.cpp ``` ### 完整设备树代码 ```shell /********************************************************************* * 立创开发板不靠卖板赚钱,以培养中国工程师为己任 * 泰山派软硬件资料与相关扩展板软硬件资料官网全部开源 * 开发板官网:www.lckfb.com * 立创论坛:oshwhub.com/forum * 关注B站:【立创开发板】,掌握我们的最新动态! ********************************************************************* * 文件名:tspi-rk3566-csi-v10 * 描述:mipi 摄像头 * 更新: * 时间 作者 联系 说明 * 2023-09-13 吴才成 1378913492@qq.com v1.0.0 *********************************************************************/ //phy u序列 &combphy1_usq { status = "okay"; }; //phy P序列 &combphy2_psq { status = "okay"; }; //dphy硬件 &csi2_dphy_hw { status = "okay"; }; //摄像头D-PHY接口 &csi2_dphy0 { status = "okay"; /* * dphy0 only used for full mode, * full mode and split mode are mutually exclusive */ ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; #address-cells = <1>; #size-cells = <0>; dphy0_in: endpoint@1 { reg = <1>; remote-endpoint = <&ov8858_out>; data-lanes = <1 2 3 4>; }; }; port@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; dphy0_out: endpoint@1 { reg = <1>; remote-endpoint = <&isp0_in>; }; }; }; }; //摄像头D-PHY接口 &csi2_dphy1 { status = "disabled"; /* * dphy1 only used for split mode, * can be used concurrently with dphy2 * full mode and split mode are mutually exclusive */ ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; #address-cells = <1>; #size-cells = <0>; dphy1_in: endpoint@1 { reg = <1>; remote-endpoint = <&ov8858_out>; data-lanes = <1 2>; }; }; port@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; dphy1_out: endpoint@1 { reg = <1>; remote-endpoint = <&isp0_in>; }; }; }; }; //摄像头D-PHY接口 &csi2_dphy2 { status = "disabled"; /* * dphy2 only used for split mode, * can be used concurrently with dphy1 * full mode and split mode are mutually exclusive */ ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; #address-cells = <1>; #size-cells = <0>; dphy2_in: endpoint@1 { reg = <1>; //remote-endpoint = <&gc5025_out>; data-lanes = <1 2>; }; }; port@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; dphy2_out: endpoint@1 { reg = <1>; remote-endpoint = <&mipi_csi2_input>; }; }; }; }; &mipi_csi2 { status = "disabled"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; #address-cells = <1>; #size-cells = <0>; mipi_csi2_input: endpoint@1 { reg = <1>; remote-endpoint = <&dphy2_out>; data-lanes = <1 2>; }; }; port@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; mipi_csi2_output: endpoint@0 { reg = <0>; remote-endpoint = <&cif_mipi_in>; data-lanes = <1 2>; }; }; }; }; //Rockchip Camera Interface &rkcif { status = "disabled"; }; //dvp接口摄像头 &rkcif_dvp { status = "disabled"; port { /* Parallel bus endpoint */ dvp_in_bcam: endpoint { // remote-endpoint = <&gc2145_out>; bus-width = <8>; vsync-active = <0>; hsync-active = <1>; }; }; }; //LVDS接口摄像头 &rkcif_mipi_lvds { status = "disabled"; port { cif_mipi_in: endpoint { remote-endpoint = <&mipi_csi2_output>; data-lanes = <1 2>; }; }; }; //摄像头内存管理 &rkcif_mmu { status = "disabled"; }; //硬件图像处理器模块 &rkisp { status = "okay"; }; //硬件图像处理器模块内存管理器 &rkisp_mmu { status = "okay"; }; //图像处理接口 &rkisp_vir0 { status = "okay"; port { #address-cells = <1>; #size-cells = <0>; isp0_in: endpoint@0 { reg = <0>; remote-endpoint = <&dphy0_out>; }; }; }; &i2c4 { /* i2c4 sda conflict with camera pwdn */ status = "okay"; ov8858: ov8858@36 { status = "okay"; compatible = "ovti,ov8858"; reg = <0x36>; clocks = <&cru CLK_CIF_OUT>; clock-names = "xvclk"; power-domains = <&power RK3568_PD_VI>; pinctrl-names = "default"; pinctrl-0 = <&cif_clk>; reset-gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>; pwdn-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; power-gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; rockchip,camera-module-index = <0>; rockchip,camera-module-facing = "back"; rockchip,camera-module-name = "HS5885-BNSM1018-V01"; rockchip,camera-module-lens-name = "default"; port { ov8858_out: endpoint { remote-endpoint = <&dphy0_in>; data-lanes = <1 2 3 4>; }; }; }; }; ``` --- --- url: /posts/泰山派_运行库.md --- # 泰山派\_运行库 配置库的路径 `vi /etc/profile` ``` export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/nfs/nfs_root/lib:/lib/rk_lib" ``` 启动脚本 `vi /etc/init.d/rcS`, 挂载nfs ```shell #!/bin/sh ifconfig eth0 up ifconfig eth0 192.168.0.150 netmask 255.255.255.0 mount -t nfs -o nfsvers=3,nolock 192.168.0.200:/home/shelton/Workspaces/projects /mnt # Start all init scripts in /etc/init.d # executing them in numerical order. # for i in /etc/init.d/S??* ;do # Ignore dangling symlinks (if any). [ ! -f "$i" ] && continue case "$i" in *.sh) # Source shell script for speed. ( trap - INT QUIT TSTP set start . $i ) ;; *) # No sh extension, so fork subprocess. $i start ;; esac done ``` --- --- url: /posts/自定义徽章.md --- # 自定义徽章 ## 背景 在github上看见了 [自定义徽章](https://github.com/pudding0503/github-badge-collection),想尝试一下 ## 使用 * 这个网站 [Simple Icons](https://simpleicons.org/?q=jav)可以找到图标 * get参数看 [Static Badge](https://shields.io/badges) 文档 ``` https://img.shields.io/badge/%20-javascript-F7DF1E?logo=javascript&style=for-the-badge&logoColor=white ``` ![JAVASCRIPT](https://img.shields.io/badge/%20-javascript-F7DF1E?logo=javascript\&style=for-the-badge\&logoColor=white) --- --- url: /projects/项目_学习uni-app.md --- # 项目\_学习uni-app ## 效果 ## 目的 工作上需要学习安卓,使用uniapp生成安卓应用 ## 实践 * \[\[vue入门]] ## 参考资料 * [零基础入门uniapp Vue3组合式API版本-咸虾米壁纸项目实战](https://www.bilibili.com/video/BV1Yg4y127Fp?spm_id_from=333.788.videopod.episodes\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) * [uni-app官网教程](https://uniapp.dcloud.net.cn/component/view.html) * [Vue.js官网指南](https://cn.vuejs.org/guide/introduction.html) --- --- url: /archives/项目_学习单片机_stc89c52.md --- # 项目\_学习单片机\_stc89c52 ## 时间 2026-01-11 ~ 2026-01-29 (19天) ## 目的 * 学习c语言 * 补足硬件短板 * 看懂原理图:能找到引脚 * 看芯片手册驱动外设:能找到器件地址,把时序转换成代码 * 熟悉常用通信协议:如i2c、spi、1wire ## 实践 > 基于普中A2开发板 * [项目工程](../posts/单片机_stc89c52_创建工程.md) * [驱动外设](../posts/单片机_stc89c52_驱动外设.md) * [中断](../posts/单片机_stc89c52_中断.md) * [通信协议](../posts/单片机_stc89c52_通信协议.md) ## 参考资料 * 江科大 * [江科大51课程代码,PPT,开发板资料](https://gitee.com/Jiachen--Zhu/jiangke-university-51) * [视频-江科大51单片机入门教程](https://www.bilibili.com/video/BV1Mb411e7re/?spm_id_from=333.337.search-card.all.click\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) * 尚硅谷 * [视频-51单片机全套教程](https://www.bilibili.com/video/BV139sSe7E2K/?spm_id_from=333.337.search-card.all.click) --- --- url: /archives/项目_学习单片机_stm32f103c8t6.md --- # 项目\_学习单片机\_stm32f103c8t6 ## 时间 * 计划:两周 * 实际:2026-02-08 - 2026-02-21 ## 目的 * 熟悉不同模块间的通信协议 ## 实践 * [创建工程](../../posts/单片机_stm32f103c8t6_创建工程.md) * [GPIO输出](../../posts/单片机_stm32f103c8t6_GPIO输出.md) ## 参考资料 * [江科大\_STM32入门教程-2023版](https://www.bilibili.com/video/BV1th411z7sn/?spm_id_from=333.337.search-card.all.click) * [尚硅谷\_stm32单片机教程](https://www.bilibili.com/video/BV1KM4m1U7f1/?spm_id_from=333.337.search-card.all.click) --- --- url: /archives/项目_学习用fushion360_3d建模.md --- # 项目\_学习用fushion360\_3d建模 ## 成果 [![nrf52811\_墨水屏桌搭\_外壳](../public/images/Pasted%20image%2020260220075257.png)](../posts/nrf52811_墨水屏桌搭_外壳.md) ## 时间 2025-2-10 ~ 2025-2-17 ## 目的 由于 sketchup 绘制的3d模型导入 bambo sutdio 的时候经常出现非流体边问题,不是很好用,因此尝试更换3d建模软件 ![](../public/images/Pasted%20image%2020260210102234.png) ## 实践 * \[\[fusion360-创建工程]] * \[\[fusion360-绘制草图]] * \[\[fusion360-绘制实体]] ## 参考资料 * [软件下载](https://www.autodesk.com/products/fusion-360/appstream) * [2023年最新 Fusion 360 教程(持续更新中)](https://www.bilibili.com/video/BV1xX4y1E7nG/?spm_id_from=333.337.search-card.all.click\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) * [Fusion 帮助 | Autodesk](https://help.autodesk.com/view/fusion360/CHS/?guid=SKT-CONSTRAIN-SYMMETRY) --- --- url: /archives/项目_学习用sketchup_3d建模.md --- # 项目\_学习用sketchup\_3d建模 ## 效果 > [003\_毛利侦探事务所笔筒](https://github.com/Zhuang-xd/blog-giscus-page/blob/master/study_3d_modeling/003_%E7%AC%94%E7%AD%92.skp) ![](../public/images/Pasted%20image%2020260206205528.png) ## 目的 买了3d打印机,想学习建模打印外壳 ## 实践 * [sketchup\_项目配置](../posts/sketchup_项目配置.md) * [sketchup\_基础操作](../posts/sketchup_基础操作.md) * [sketchup\_使用技巧](../posts/sketchup_使用技巧.md) ## 参考资料 * sketchup * [【包教包会】0基础自学3D打印建模教程](https://www.bilibili.com/video/BV1xA4tzuE58?spm_id_from=333.788.videopod.sections\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) --- --- url: /archives/项目_泰山派监控系统.md --- # 项目\_泰山派监控系统 > 项目代码 - [Zhuang-xd/cctv\_monitor](https://github.com/Zhuang-xd/cctv_monitor) ## 效果 ![](/assets/GIF_20260211_143052.Cnsxq7cV.gif) ## 时间 * 计划:三个月 * 实际:2025-10-08 ~ 2025-11-30 (54天) ### 当前进度 * 上位机 * 拉流rtsp * 下位机 * 设备树:驱动ov5695 * mpp 捕获摄像头 * ZLMediaKit 推流rtsp ### 未来计划 * 上位机可以通过json传递圈画坐标给下位机,实时同步到各个上位机程序 ## 目的 找工作 ## 实践 ### 环境搭建 * [泰山派-源码编译](https://wiki.lckfb.com/zh-hans/tspi-rk3566/sdk-compilation/linux-compilation.html) * [泰山派\_挂载nfs](../posts/泰山派_挂载nfs.md) * [泰山派\_SDK打补丁](../posts/泰山派_SDK打补丁.md) ### 一些个人习惯 * [泰山派\_固件打包脚本](../posts/泰山派_固件打包脚本.md) * [泰山派\_常用的目录](../posts/泰山派_常用的目录.md) ### 上位机 这个是用qt写的,主要用了xvideoview这个库,里面对ffmpeg和sdl进行了浅封装,之后应该会进行深度封装,并使用责任链模式组织代码 ### 下位机 * [泰山派\_摄像头程序编译](../posts/泰山派_摄像头程序编译.md) * [泰山派\_运行库](../posts/泰山派_运行库.md) ## 参考资料 * 文档 * [博客](https://blog.csdn.net/qq_53686293/article/details/148673403?sharetype=blog\&shareId=148673403\&sharerefer=APP\&sharesource=qq_53686293\&sharefrom=link) * [泰山派训练营](https://www.bilibili.com/video/BV1QT4m1S7Ae/?spm_id_from=333.337.search-card.all.click\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) * [泰山派文档](https://wiki.lckfb.com/zh-hans/tspi-rk3566/download-center.html) * rk论坛 \- [易百纳-瑞芯微](https://www.ebaina.com/channels/16) \- [Firefly开源社区](https://dev.t-firefly.com/search.php?mod=forum\&searchid=387396\&orderby=lastpost\&ascdesc=desc\&searchsubmit=yes\&kw=rk3566) * 驱动 * [linux下mipi摄像头驱动详解和v4l2框架浅析(以rk3566+ov5695为例) - CSDN App](https://blog.csdn.net/qq_53686293/article/details/155452312?sharetype=blog\&shareId=155452312\&sharerefer=APP\&sharesource=shelton_z\&sharefrom=link) --- --- url: /archives/项目_泰山派相机.md --- # 项目\_泰山派相机 ## 时间 * 计划:三个月 * 实际:2025-12-15 ## 目的 * 掌握瑞芯微的MPP ## 实践 * [泰山派\_移植ov8858摄像头](../../posts/泰山派_移植ov8858摄像头.md) * [泰山派\_点亮mipi屏幕](../../posts/泰山派_点亮mipi屏幕.md) ## 参考资料 * 摄像头 * [泰山派移植OV8858驱动并添加自动聚焦功能\_摄像头驱动ov8858-CSDN博客](https://blog.csdn.net/qq_53686293/article/details/153208692?spm=1001.2014.3001.5502) * [linux下mipi摄像头驱动详解和v4l2框架浅析(以rk3566+ov5695为例)-CSDN博客](https://blog.csdn.net/qq_53686293/article/details/155452312?spm=1001.2014.3001.5502) * 屏幕 * [泰山派3.1寸mipi屏幕驱动分析(对比正点原子LCD驱动)\_正点原子mipi屏-CSDN博客](https://blog.csdn.net/qq_53686293/article/details/151259625?spm=1001.2014.3001.5502) * [泰山派构建buildroot](https://wiki.lckfb.com/zh-hans/tspi-rk3566/sdk-compilation/linux-compilation.html#%E5%85%A8%E7%BC%96%E8%AF%91) * [查看泰山派 ov5695研究(1)\_ov5695调试-CSDN博客](https://blog.csdn.net/ganhui13000/article/details/150070903) --- --- url: /private/archives/项目_病情记录_2602.md --- # 项目\_病情记录\_2602 ## 目的 记录观察自己的病情 * 避免情绪心态恶化 * 给医生提供信息 ## 实践 ::: timeline **2025-03-01** * 年后基本听不见声音了,但是很困,每天都睡不醒的感觉 ::: ::: timeline **2025-02-19** * 过年我回了趟家,当时我在改代码,刚开始还好,遇到当下解决不了的问题后,声音又出现了,而且比较清晰。然后我就回家了,期间有个男的声音总是问我有什么意义呢,比如我回家,他就会说回家有什么意义;我开始做3d打印项目,他就会说3d打印有什么意义 * 意识到自己是双相情感障碍,那些声音都是自己的妄想后,没有那么害怕了 ::: --- --- url: /private/archives/项目_面试_2025-12.md --- # 项目\_面试\_2025-12 ## 总结 基本持续了一个月时间,最后选择了昶音智能,这家公司做的是项目很多,我进的组是ai智能眼镜。需要用的技术栈包括 * ffmepg * linux * rtos 感觉上与之前的工作有一些交集,又有拓展,应该是一份合适的工作 ## 时间 * 2025.12.01 ~ 2025.1.09 ## 目的 * 总结面试套路 * 记录自己的不足 ## 实践 ### 面试必做 * 看招聘简介,公司官网 * 成立时间 * 公司业务 * 岗位职责 * 你还有什么要问我的 * 试用期多久,是双休吗 * 公司研发的人数有多少? * 你们的嵌入式的平台是什么 * 你们比较看重我什么能力 ### 面试记录 #### 科锐国际-京瓷信息 > 中型公司 \#interview-record/26/12/29 * sdk \#interview-record/26/01/09 * 技术面 * 介绍项目架构 * 产品面 * 运动相机,制作原因 * 人事面 * 性格测试 #### 昶音智能 > 中型公司,ODM \#interview-record/26/01/08 * 技术面 * 介绍项目架构 * linux推流+rtos * 产品面 * 运动相机,制作原因 * 人事面 * 性格测试 * 职业规划:深入一门,带动其他技能,自己做产品 * 解决问题的方式:从难到容易 * 你遇到的最大困难是工作or生活上,你是怎么处理的 * 工作上遇到的困难:沟通 * 你交朋友的标准:善良、真诚 #### 古鳌电子 > 中型公司,同普路,验钞机 \#interview-record/26/01/08 * 技术面 * 扫描币数 -> 剔除假币 * 介绍项目架构 * kvm项目进程通信 * 电路图 #### 得逸信息-中远海控 > 外包 \#interview-record/26/01/07 * 就问能不能用qt重构现有项目 #### 上海乐存信息 > 中型公司 \#interview-record/26/01/07 * 一问三不知 * 单片机 * stm32点灯模式 * i2c起始信号 #### 光之人 > 中型公司 \#interview-record/26/01/07 * [线上笔试](https://wj.qq.com/r/answer_detail.html?sid=22988694\&aid=303\&hash=7442) 待约面 #### 钛昕 > 中型公司,充电桩,上位机qt \#interview-record/25/12/24 * c++ * 智能指针 * qt * 多线程:重写thread的run方法 * 信号槽 * 表单中的checkbox:委托 * 项目简介 * 薪资 #### 辰光融信 > 中型公司,打印机,linux驱动 \#interview-record/25/12/22 * [官网](https://www.cgprintech.com/) * 做题 * 项目简介 * 薪资 #### 泰极讯科技 > 小公司,做光纤,20人研发,linux驱动 \#interview-record/25/12/20 * 人事面 * 离职原因:想换个大一点的平台 * 项目职责:自动投料机的一环 * 介绍了公司情况 * 武汉研发中心,上海20人 * [行业新力量!算力中心互联和无源光网络设备商泰极讯加入和光荟\_光纤在线 - 和我们一起塑造中国光通信的未来!](https://www.c-fol.net/news/4_202506/20250626100658.html) \#interview-record/25/12/22 * 技术面 * 设备树改了什么 * 驱动摄像头: * 最主要的区别是lanes,ov5695是2lane,但rk3566最大支持4lane * i2c:时钟,电源域,lane * lane数据链路: * ov5695:splite mode:sensor -> csi\_dphy1 -> isp,2对数据线,1对时钟线 * ov8828:fullmode:sensor -> csi\_dphy0 -> isp,4对数据线,1对时钟线 * mipi区别:dphy有时钟线,cphy没有时钟线 * kvm的应用场景 * 可以从中央控制多台外部计算机 * 监控安防 * 数据中心 * 教育培训 #### 索德慧影 > 小公司,海思、qt,音视频嵌入式 \#interview-record/25/12/17 * 技术面 * 数据结构 * 黑白树 * 自动喂料机 * 我负责的是其中摄像头的环境,负责精准计量和控制提供,助力客户实现生产过程的优化和效率提升,智能化&精细化 * [卡尔史托斯-内窥镜](https://www.karlstorz.com/cn/zh/index.htm) #### 益码机械设备 > 小公司,qt,后期可能有嵌入式 \#interview-record/25/12/16 * 没问技术 #### 柏飞电子科技有限公司 > 中型公司,板卡fae \#interview-record/25/12/15 * 人事面+主管面 * 离职原因 * 项目职责 * 介绍了他们公司两个岗位的职责 * 联调fae * 板卡bmc * 看重主观能动性 * 沟通能力 * 独立解决问题能力 #### 奥然生物科技 > 中型公司,嵌入式研发,生物试剂研发 \#interview-record/25/12/15 * 人事面+主管面 * 离职原因 * 项目职责,是否自己能实现 * 介绍了他们公司的岗位的职责 * 考察软件设计能力 * 检测95度,偏差+-0.5度 * 检测温度,和95度比较,调节偏差值 * 检测升温时间<=15s * 检测两个时间点,起始时间温度,终止时间温度,计算升温时间,等待降温,重复 * 你还有什么要问我的吗 #### 上海思晋智能科技 > 松江,10人团队 * 第二家公司的项目:医疗内窥镜摄像系统 * 分辨率是 rk3566-ov5695-1920x1080x30fps * 下位机: * 摄像头驱动,修改设备树 * 推流rtsp * 上位机 * ffmpeg+sdl 做的解码渲染 * 添加json协议的标注 * io多路复用 * select:内核监控+事件通知 * poll: #### 联合电梯技术中心 > 嵌入式,驱动,小公司,1165-123-2001 * stm32和c做题 #### 像意智能 > 小公司、qt、图像、dsp+fpga、徐汇滨江 \#interview-record/25/12/11 * 理论知识 * 专业课 * 控制原理 * 负反馈:目的是回归稳态 * 检测偏差-> 调节偏差值 -> 回归稳态 * 正反馈:放大器 * 图像处理 * 帧内压缩:记录宏块之间的变化 * 宏块划分图像,取主要的宏块,乘上一个缩放系数,实现有损压缩 * 帧间压缩: * 推测图像之间的变化,依赖其他帧,再做当前帧的帧内压缩 * 压缩算法 * 哈夫曼算法 * 你是否培训过 * 没有,我之前自学的qt找到的工作,然后接触到了嵌入式linux开发,感觉对这个方向比较感兴趣,所以都找的这个方向的 * 离职原因(呆的时间短) #### 利格泰生物-涛影医疗 > 上位机qt,c++,小公司,医疗影像,5-10年经验 \#interview-record/25/12/10 * 多态的其他表现 * 父类指针指向子类 * 编译时多态 * 函数、运算符重载、模板类 * 运行时多态 * 虚函数 * dynamic\_cast * lambda * 指针和引用的区别 * 引用相当于const 指针 * 智能指针 * 引用计数 * shared\_pointer 循环引用 * ffmpeg有哪些库 * libavcodec 编解码 * libavformat 封装 * libavfilter 滤镜 * libavutil 工具库 * libswscale 转换 * libswresample 音频 * long在linux和windows的区别 * Windows: 4字节, Linux: 8字节 * 设计模式 * 工厂模式拓展接口 * 定义一个抽象类、写了一些虚函数,子类去重写接口的方法 * 内存泄漏 * 查看的工具 * vs上可以看内存使用率 * 查看内存命令 * free * 交叉编译工具 * 可以在其他平台上编译出当前平台的程序的工具 * 编译选项 * `-I./include` * `-L./lib` * `-o app` #### 上海钜蛟 > 上位机qt、c#、py,校企小公司 \#interview-record/25/12/10 * 你现在有offer了吗 * 之前的offer基本满足我的需求,我现在是想稍微看看找一下有没有更合适的平台 * 你对我们公司有什么了解 * 看招聘简介 * 离职原因 * 小公司: * 寻找更合适的平台 * 第一家:做嵌入式的只有我一个人,成长有限 * 第二家:写的代码量太少,成长有限 * 大公司: * 人员流动性大 * 专精一个方向 * 到岗时间 * 一周内,搬家 \#interview-record/25/12/11 * 栈和堆的区别 * qt的信号槽机制 * Q\_OBJECT --> connect绑定 --> 运行时反射 * 你做的两份工作都是偏界面的? * 第一份早期是,初期会做一些简单的工作,后面给库添加了新的功能,增加了json的通信协议;第二份是做嵌入式后端程序为主的 * c++11新特性 * 智能指针 * 循环引用问题,除了手动减引用计数还有什么方式 * weak\_ptr 这个不会增加引用计数 * 线程同步 * 除了锁还有什么方式 * 原子操作 * 信号量,控制并发数量 * 消息队列,双向的 * promise-future(生产者消费者),单向的 * auto类型 * 范围for循环 * Lambda 表达式 * nullptr * override * MyClass(double) = delete; // 禁止double参数 * 正则表达式 * 设计模式 * 单例 * 工厂 #### 钰策科技有限公司 > 量化交易,中型公司 \#interview-record/25/12/09 * 海投的简历 * 做题 #### 芯巧电子 > pcb二次开发,上位机,小公司 \#interview-record/25/12/09 * 栈和堆的区别 * 空间大小:栈小、堆大 * 访问速度:栈快、堆慢 * 生命周期:栈FILO、堆手动释放(手动释放成对写避免悬空指针、智能指针) * 悬空指针:释放后没置null * 野指针:没有初始化,是随机值 * 多线程:栈安全、堆会存在竞态问题(通过锁解决) #### 孚恩科技 > 嵌入式公司,小公司 \#interview-record/25/12/02 * 阴阳简历,需要资深的工程师 * 看中的是我会打包固件 * 报名吹风人力资源 --- --- url: /archives/项目_墨水屏桌搭_基于esp32.md --- # 项目\_墨水屏桌搭\_基于esp32\_DEVKIT\_V1 ## 成果 ![](/assets/IMG_20260330_002430.Bpbr-YIn.jpg) ![](/assets/IMG_20260304_011202.D7cSeOyZ.jpg) ## 时间 * 预计:一周 * 实际:2026-02-15 - 2026-03-10 (24天) ## 目的 想做一个能自定义的桌搭,这个 [项目\_墨水屏桌搭\_基于nrf52811](../archives/项目_墨水屏桌搭_基于nrf52811.md) 项目的固件编译后打包失败,因此想自己实现一个同样功能的桌搭,于是有了这个项目 ## 实践 > 主控使用esp32rev1,因为自带电源管理模块 * [esp32rev1原理图](../posts/esp32rev1原理图.md) * [esp32rev1驱动墨水屏](esp32rev1驱动墨水屏.md) * [esp32使用u8g2字库在墨水屏显示中文](../posts/esp32使用u8g2字库在墨水屏显示中文.md) * 代码 [zhuang-xd/eink-desktop-assistant](https://github.com/zhuang-xd/eink-desktop-assistant) * 制作外壳,参考[nrf52811\_墨水屏桌搭\_外壳](../posts/nrf52811_墨水屏桌搭_外壳.md) * [esp32\_蓝牙ble通信](../posts/esp32_蓝牙ble通信.md) ## 参考资料 * [JADE-Jerry/jcalendar: Ink Screen Calendar](https://github.com/JADE-Jerry/jcalendar) * [驱动墨水屏基础教程1](https://www.bilibili.com/video/BV16h6eBhECk/?spm_id_from=333.1007.top_right_bar_window_history.content.click\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) * [esp8266 水墨屏显示中文之全量字库 - 金色旭光 - 博客园](https://www.cnblogs.com/goldsunshine/p/17403345.html) --- --- url: /archives/项目_墨水屏桌搭_基于nrf52811.md --- # 项目\_墨水屏桌搭\_基于nrf52811 ## 效果 ![](/assets/IMG_20260204_115039.meqIh-02.jpg) ![](../public/images/IMG_20260204_123740%201.jpg) ## 时间 * 计划:2天 * 实际:2026-02-02 ~ 2026-02-04 ## 目的 想要一个电子相册,通过三色墨水屏实现一个日历和壁纸显示 ## 实践 * [nrf52811\_墨水屏桌搭\_bom表](../posts/nrf52811_墨水屏桌搭_bom表.md) * [nrf52811\_墨水屏桌搭\_jlink烧录](../posts/nrf52811_墨水屏桌搭_jlink烧录.md) * [nrf52811\_墨水屏桌搭\_配套上位机](../posts/nrf52811_墨水屏桌搭_配套上位机.md) * \[\[nrf52811\_墨水屏桌搭\_外壳]] ## 参考资料 * [【开源】4.2寸墨水屏固件(蓝牙传图+日历)\_哔哩哔哩\_bilibili](https://www.bilibili.com/video/BV1KWAVe1EKs/?spm_id_from=333.337.search-card.all.click\&vd_source=8f0a7910abc46a7f7258da6ae2e0d504) * [tsl0922/EPD-nRF5: E-paper display firmware for Nordic nRF51/nRF52, with support for image transfer, OTA update.](https://github.com/tsl0922/EPD-nRF5)